blob: 7194548cdc0be971a932529aebea77e36ec79982 [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
Shuzhen Wangd4abdf72021-05-28 11:22:50 -070078Camera3Device::Camera3Device(const String8 &id, bool overrideForPerfClass):
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -080079 mId(id),
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -080080 mOperatingMode(NO_MODE),
Eino-Ville Talvala9a179412015-06-09 13:15:16 -070081 mIsConstrainedHighSpeedConfiguration(false),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070082 mStatus(STATUS_UNINITIALIZED),
Ruben Brunk183f0562015-08-12 12:55:02 -070083 mStatusWaiters(0),
Zhijun He204e3292014-07-14 17:09:23 -070084 mUsePartialResult(false),
85 mNumPartialResults(1),
Shuzhen Wangc28dccc2016-02-11 23:48:46 -080086 mTimestampOffset(0),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -070087 mNextResultFrameNumber(0),
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -070088 mNextReprocessResultFrameNumber(0),
Shuzhen Wang5ee99842019-04-12 11:55:48 -070089 mNextZslStillResultFrameNumber(0),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -070090 mNextShutterFrameNumber(0),
Chien-Yu Chen3df11ce2015-09-30 14:13:30 -070091 mNextReprocessShutterFrameNumber(0),
Shuzhen Wang5ee99842019-04-12 11:55:48 -070092 mNextZslStillShutterFrameNumber(0),
Emilian Peev71c73a22017-03-21 16:35:51 +000093 mListener(NULL),
Emilian Peev811d2952018-05-25 11:08:40 +010094 mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID),
Shuzhen Wang268a1362018-10-16 16:32:59 -070095 mLastTemplateId(-1),
Shuzhen Wangd4abdf72021-05-28 11:22:50 -070096 mNeedFixupMonochromeTags(false),
97 mOverrideForPerfClass(overrideForPerfClass)
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080098{
99 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800100 ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800101}
102
103Camera3Device::~Camera3Device()
104{
105 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800106 ALOGV("%s: Tearing down for camera id %s", __FUNCTION__, mId.string());
Yin-Chia Yehc5248132018-08-15 12:19:20 -0700107 disconnectImpl();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800108}
109
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800110const String8& Camera3Device::getId() const {
Igor Murashkin71381052013-03-04 14:53:08 -0800111 return mId;
112}
113
Emilian Peevbd8c5032018-02-14 23:05:40 +0000114status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800115 ATRACE_CALL();
116 Mutex::Autolock il(mInterfaceLock);
117 Mutex::Autolock l(mLock);
118
119 ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
120 if (mStatus != STATUS_UNINITIALIZED) {
121 CLOGE("Already initialized!");
122 return INVALID_OPERATION;
123 }
124 if (manager == nullptr) return INVALID_OPERATION;
125
126 sp<ICameraDeviceSession> session;
127 ATRACE_BEGIN("CameraHal::openSession");
Steven Moreland5ff9c912017-03-09 23:13:00 -0800128 status_t res = manager->openSession(mId.string(), this,
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800129 /*out*/ &session);
130 ATRACE_END();
131 if (res != OK) {
132 SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
133 return res;
134 }
135
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700136 res = manager->getCameraCharacteristics(mId.string(), mOverrideForPerfClass, &mDeviceInfo);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800137 if (res != OK) {
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700138 SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800139 session->close();
140 return res;
141 }
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800142 mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
Yin-Chia Yeh52778d42016-12-22 18:20:43 -0800143
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700144 std::vector<std::string> physicalCameraIds;
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700145 bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700146 if (isLogical) {
147 for (auto& physicalId : physicalCameraIds) {
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700148 // Do not override characteristics for physical cameras
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -0700149 res = manager->getCameraCharacteristics(
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700150 physicalId, /*overrideForPerfClass*/false, &mPhysicalDeviceInfoMap[physicalId]);
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700151 if (res != OK) {
152 SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)",
153 physicalId.c_str(), strerror(-res), res);
154 session->close();
155 return res;
156 }
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -0700157
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800158 bool usePrecorrectArray =
159 DistortionMapper::isDistortionSupported(mPhysicalDeviceInfoMap[physicalId]);
160 if (usePrecorrectArray) {
161 res = mDistortionMappers[physicalId].setupStaticInfo(
162 mPhysicalDeviceInfoMap[physicalId]);
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -0700163 if (res != OK) {
164 SET_ERR_L("Unable to read camera %s's calibration fields for distortion "
165 "correction", physicalId.c_str());
166 session->close();
167 return res;
168 }
169 }
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800170
Shuzhen Wang1c834da2019-12-18 11:17:03 -0800171 mZoomRatioMappers[physicalId] = ZoomRatioMapper(
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800172 &mPhysicalDeviceInfoMap[physicalId],
173 mSupportNativeZoomRatio, usePrecorrectArray);
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700174 }
175 }
176
Yifan Hongf79b5542017-04-11 14:44:25 -0700177 std::shared_ptr<RequestMetadataQueue> queue;
Yifan Honga640c5a2017-04-12 16:30:31 -0700178 auto requestQueueRet = session->getCaptureRequestMetadataQueue(
179 [&queue](const auto& descriptor) {
180 queue = std::make_shared<RequestMetadataQueue>(descriptor);
181 if (!queue->isValid() || queue->availableToWrite() <= 0) {
182 ALOGE("HAL returns empty request metadata fmq, not use it");
183 queue = nullptr;
184 // don't use the queue onwards.
185 }
186 });
187 if (!requestQueueRet.isOk()) {
188 ALOGE("Transaction error when getting request metadata fmq: %s, not use it",
189 requestQueueRet.description().c_str());
Eino-Ville Talvalac5cbb872017-04-27 12:48:33 -0700190 return DEAD_OBJECT;
Yifan Hongf79b5542017-04-11 14:44:25 -0700191 }
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700192
193 std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
Yifan Honga640c5a2017-04-12 16:30:31 -0700194 auto resultQueueRet = session->getCaptureResultMetadataQueue(
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700195 [&resQueue](const auto& descriptor) {
196 resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
197 if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
Yifan Honga640c5a2017-04-12 16:30:31 -0700198 ALOGE("HAL returns empty result metadata fmq, not use it");
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700199 resQueue = nullptr;
200 // Don't use the resQueue onwards.
Yifan Honga640c5a2017-04-12 16:30:31 -0700201 }
202 });
203 if (!resultQueueRet.isOk()) {
204 ALOGE("Transaction error when getting result metadata queue from camera session: %s",
205 resultQueueRet.description().c_str());
Eino-Ville Talvalac5cbb872017-04-27 12:48:33 -0700206 return DEAD_OBJECT;
Yifan Honga640c5a2017-04-12 16:30:31 -0700207 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700208 IF_ALOGV() {
209 session->interfaceChain([](
210 ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
211 ALOGV("Session interface chain:");
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800212 for (const auto& iface : interfaceChain) {
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700213 ALOGV(" %s", iface.c_str());
214 }
215 });
216 }
Yifan Hongf79b5542017-04-11 14:44:25 -0700217
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -0800218 camera_metadata_entry bufMgrMode =
219 mDeviceInfo.find(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
220 if (bufMgrMode.count > 0) {
221 mUseHalBufManager = (bufMgrMode.data.u8[0] ==
222 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
223 }
224
Yin-Chia Yehb978c382019-10-30 00:22:37 -0700225 camera_metadata_entry_t capabilities = mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
226 for (size_t i = 0; i < capabilities.count; i++) {
227 uint8_t capability = capabilities.data.u8[i];
228 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING) {
229 mSupportOfflineProcessing = true;
230 }
231 }
232
233 mInterface = new HalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);
Emilian Peev71c73a22017-03-21 16:35:51 +0000234 std::string providerType;
235 mVendorTagId = manager->getProviderTagIdLocked(mId.string());
Emilian Peevbd8c5032018-02-14 23:05:40 +0000236 mTagMonitor.initialize(mVendorTagId);
237 if (!monitorTags.isEmpty()) {
238 mTagMonitor.parseTagsToMonitor(String8(monitorTags));
239 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800240
Shuzhen Wang268a1362018-10-16 16:32:59 -0700241 // Metadata tags needs fixup for monochrome camera device version less
242 // than 3.5.
243 hardware::hidl_version maxVersion{0,0};
244 res = manager->getHighestSupportedVersion(mId.string(), &maxVersion);
245 if (res != OK) {
246 ALOGE("%s: Error in getting camera device version id: %s (%d)",
247 __FUNCTION__, strerror(-res), res);
248 return res;
249 }
250 int deviceVersion = HARDWARE_DEVICE_API_VERSION(
251 maxVersion.get_major(), maxVersion.get_minor());
252
253 bool isMonochrome = false;
Yin-Chia Yehb978c382019-10-30 00:22:37 -0700254 for (size_t i = 0; i < capabilities.count; i++) {
255 uint8_t capability = capabilities.data.u8[i];
Shuzhen Wang268a1362018-10-16 16:32:59 -0700256 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
257 isMonochrome = true;
258 }
259 }
260 mNeedFixupMonochromeTags = (isMonochrome && deviceVersion < CAMERA_DEVICE_API_VERSION_3_5);
261
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800262 return initializeCommonLocked();
263}
264
265status_t Camera3Device::initializeCommonLocked() {
266
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700267 /** Start up status tracker thread */
268 mStatusTracker = new StatusTracker(this);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800269 status_t res = mStatusTracker->run(String8::format("C3Dev-%s-Status", mId.string()).string());
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700270 if (res != OK) {
271 SET_ERR_L("Unable to start status tracking thread: %s (%d)",
272 strerror(-res), res);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800273 mInterface->close();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700274 mStatusTracker.clear();
275 return res;
276 }
277
Eino-Ville Talvala24b366e2016-07-21 12:53:07 -0700278 /** Register in-flight map to the status tracker */
Yin-Chia Yeh87b3ec02019-06-03 10:44:39 -0700279 mInFlightStatusId = mStatusTracker->addComponent("InflightRequests");
Eino-Ville Talvala24b366e2016-07-21 12:53:07 -0700280
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -0700281 if (mUseHalBufManager) {
282 res = mRequestBufferSM.initialize(mStatusTracker);
283 if (res != OK) {
284 SET_ERR_L("Unable to start request buffer state machine: %s (%d)",
285 strerror(-res), res);
286 mInterface->close();
287 mStatusTracker.clear();
288 return res;
289 }
290 }
291
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -0800292 /** Create buffer manager */
293 mBufferManager = new Camera3BufferManager();
294
295 Vector<int32_t> sessionParamKeys;
296 camera_metadata_entry_t sessionKeysEntry = mDeviceInfo.find(
297 ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
298 if (sessionKeysEntry.count > 0) {
299 sessionParamKeys.insertArrayAt(sessionKeysEntry.data.i32, 0, sessionKeysEntry.count);
300 }
301
Chien-Yu Chenab5135b2015-06-30 11:20:58 -0700302 /** Start up request queue thread */
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -0700303 mRequestThread = new RequestThread(
304 this, mStatusTracker, mInterface, sessionParamKeys, mUseHalBufManager);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800305 res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800306 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700307 SET_ERR_L("Unable to start request queue thread: %s (%d)",
308 strerror(-res), res);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800309 mInterface->close();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800310 mRequestThread.clear();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800311 return res;
312 }
313
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700314 mPreparerThread = new PreparerThread();
315
Ruben Brunk183f0562015-08-12 12:55:02 -0700316 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800317 mNextStreamId = 0;
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -0400318 mFakeStreamId = NO_STREAM;
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -0700319 mNeedConfig = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700320 mPauseStateNotify = false;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800321 mIsInputStreamMultiResolution = false;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800322
Shuzhen Wangc28dccc2016-02-11 23:48:46 -0800323 // Measure the clock domain offset between camera and video/hw_composer
324 camera_metadata_entry timestampSource =
325 mDeviceInfo.find(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE);
326 if (timestampSource.count > 0 && timestampSource.data.u8[0] ==
327 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME) {
328 mTimestampOffset = getMonoToBoottimeOffset();
329 }
330
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700331 // Will the HAL be sending in early partial result metadata?
Emilian Peev08dd2452017-04-06 16:55:14 +0100332 camera_metadata_entry partialResultsCount =
333 mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
334 if (partialResultsCount.count > 0) {
335 mNumPartialResults = partialResultsCount.data.i32[0];
336 mUsePartialResult = (mNumPartialResults > 1);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700337 }
338
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800339 bool usePrecorrectArray = DistortionMapper::isDistortionSupported(mDeviceInfo);
340 if (usePrecorrectArray) {
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -0700341 res = mDistortionMappers[mId.c_str()].setupStaticInfo(mDeviceInfo);
Eino-Ville Talvala7b8a1fd2018-05-22 15:30:35 -0700342 if (res != OK) {
343 SET_ERR_L("Unable to read necessary calibration fields for distortion correction");
344 return res;
345 }
346 }
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800347
Shuzhen Wang1c834da2019-12-18 11:17:03 -0800348 mZoomRatioMappers[mId.c_str()] = ZoomRatioMapper(&mDeviceInfo,
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800349 mSupportNativeZoomRatio, usePrecorrectArray);
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -0800350
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -0800351 if (RotateAndCropMapper::isNeeded(&mDeviceInfo)) {
352 mRotateAndCropMappers.emplace(mId.c_str(), &mDeviceInfo);
353 }
354
Eino-Ville Talvala305cec62020-11-12 14:18:17 -0800355 camera_metadata_entry_t availableTestPatternModes = mDeviceInfo.find(
356 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES);
357 for (size_t i = 0; i < availableTestPatternModes.count; i++) {
358 if (availableTestPatternModes.data.i32[i] == ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR) {
359 mSupportCameraMute = true;
360 break;
361 }
362 }
363
Cliff Wuc2ad9c82021-04-21 00:58:58 +0800364 mInjectionMethods = new Camera3DeviceInjectionMethods(this);
365
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800366 return OK;
367}
368
369status_t Camera3Device::disconnect() {
Yin-Chia Yehc5248132018-08-15 12:19:20 -0700370 return disconnectImpl();
371}
372
373status_t Camera3Device::disconnectImpl() {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800374 ATRACE_CALL();
Yin-Chia Yehe1c80632016-08-08 14:48:05 -0700375 ALOGI("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800376
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700377 status_t res = OK;
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700378 std::vector<wp<Camera3StreamInterface>> streams;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700379 {
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800380 Mutex::Autolock il(mInterfaceLock);
381 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
382 {
383 Mutex::Autolock l(mLock);
384 if (mStatus == STATUS_UNINITIALIZED) return res;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700385
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800386 if (mStatus == STATUS_ACTIVE ||
387 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
388 res = mRequestThread->clearRepeatingRequests();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700389 if (res != OK) {
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800390 SET_ERR_L("Can't stop streaming");
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700391 // Continue to close device even in case of error
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800392 } else {
393 res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
394 if (res != OK) {
395 SET_ERR_L("Timeout waiting for HAL to drain (% " PRIi64 " ns)",
396 maxExpectedDuration);
397 // Continue to close device even in case of error
398 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700399 }
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700400 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800401
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800402 if (mStatus == STATUS_ERROR) {
403 CLOGE("Shutting down in an error state");
404 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700405
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800406 if (mStatusTracker != NULL) {
407 mStatusTracker->requestExit();
408 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700409
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800410 if (mRequestThread != NULL) {
411 mRequestThread->requestExit();
412 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700413
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800414 streams.reserve(mOutputStreams.size() + (mInputStream != nullptr ? 1 : 0));
415 for (size_t i = 0; i < mOutputStreams.size(); i++) {
416 streams.push_back(mOutputStreams[i]);
417 }
418 if (mInputStream != nullptr) {
419 streams.push_back(mInputStream);
420 }
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700421 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700422 }
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800423 // Joining done without holding mLock and mInterfaceLock, otherwise deadlocks may ensue
424 // as the threads try to access parent state (b/143513518)
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700425 if (mRequestThread != NULL && mStatus != STATUS_ERROR) {
426 // HAL may be in a bad state, so waiting for request thread
427 // (which may be stuck in the HAL processCaptureRequest call)
428 // could be dangerous.
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800429 // give up mInterfaceLock here and then lock it again. Could this lead
430 // to other deadlocks
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700431 mRequestThread->join();
432 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700433 {
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800434 Mutex::Autolock il(mInterfaceLock);
435 if (mStatusTracker != NULL) {
436 mStatusTracker->join();
437 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800438
Cliff Wuc2ad9c82021-04-21 00:58:58 +0800439 if (mInjectionMethods->isInjecting()) {
440 mInjectionMethods->stopInjection();
441 }
442
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800443 HalInterface* interface;
444 {
445 Mutex::Autolock l(mLock);
446 mRequestThread.clear();
447 Mutex::Autolock stLock(mTrackerLock);
448 mStatusTracker.clear();
449 interface = mInterface.get();
450 }
Eino-Ville Talvalaefff1c42015-08-28 16:27:27 -0700451
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800452 // Call close without internal mutex held, as the HAL close may need to
453 // wait on assorted callbacks,etc, to complete before it can return.
454 interface->close();
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700455
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800456 flushInflightRequests();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800457
Jayant Chowdhary646c31b2020-01-30 13:09:59 -0800458 {
459 Mutex::Autolock l(mLock);
460 mInterface->clear();
461 mOutputStreams.clear();
462 mInputStream.clear();
463 mDeletedStreams.clear();
464 mBufferManager.clear();
465 internalUpdateStatusLocked(STATUS_UNINITIALIZED);
466 }
467
468 for (auto& weakStream : streams) {
469 sp<Camera3StreamInterface> stream = weakStream.promote();
470 if (stream != nullptr) {
471 ALOGE("%s: Stream %d leaked! strong reference (%d)!",
472 __FUNCTION__, stream->getId(), stream->getStrongCount() - 1);
473 }
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -0700474 }
475 }
Yin-Chia Yehe1c80632016-08-08 14:48:05 -0700476 ALOGI("%s: X", __FUNCTION__);
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700477 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800478}
479
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700480// For dumping/debugging only -
481// try to acquire a lock a few times, eventually give up to proceed with
482// debug/dump operations
483bool Camera3Device::tryLockSpinRightRound(Mutex& lock) {
484 bool gotLock = false;
485 for (size_t i = 0; i < kDumpLockAttempts; ++i) {
486 if (lock.tryLock() == NO_ERROR) {
487 gotLock = true;
488 break;
489 } else {
490 usleep(kDumpSleepDuration);
491 }
492 }
493 return gotLock;
494}
495
Shuzhen Wang83bff122020-11-20 15:51:39 -0800496camera3::Size Camera3Device::getMaxJpegResolution() const {
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700497 int32_t maxJpegWidth = 0, maxJpegHeight = 0;
Emilian Peev08dd2452017-04-06 16:55:14 +0100498 const int STREAM_CONFIGURATION_SIZE = 4;
499 const int STREAM_FORMAT_OFFSET = 0;
500 const int STREAM_WIDTH_OFFSET = 1;
501 const int STREAM_HEIGHT_OFFSET = 2;
502 const int STREAM_IS_INPUT_OFFSET = 3;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800503 bool isHighResolutionSensor =
504 camera3::SessionConfigurationUtils::isUltraHighResolutionSensor(mDeviceInfo);
505 int32_t scalerSizesTag = isHighResolutionSensor ?
506 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_MAXIMUM_RESOLUTION :
507 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
Emilian Peev08dd2452017-04-06 16:55:14 +0100508 camera_metadata_ro_entry_t availableStreamConfigs =
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800509 mDeviceInfo.find(scalerSizesTag);
Emilian Peev08dd2452017-04-06 16:55:14 +0100510 if (availableStreamConfigs.count == 0 ||
511 availableStreamConfigs.count % STREAM_CONFIGURATION_SIZE != 0) {
Shuzhen Wang83bff122020-11-20 15:51:39 -0800512 return camera3::Size(0, 0);
Emilian Peev08dd2452017-04-06 16:55:14 +0100513 }
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700514
Emilian Peev08dd2452017-04-06 16:55:14 +0100515 // Get max jpeg size (area-wise).
516 for (size_t i=0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) {
517 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
518 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
519 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
520 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
521 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
522 && format == HAL_PIXEL_FORMAT_BLOB &&
523 (width * height > maxJpegWidth * maxJpegHeight)) {
524 maxJpegWidth = width;
525 maxJpegHeight = height;
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700526 }
527 }
Emilian Peev08dd2452017-04-06 16:55:14 +0100528
Shuzhen Wang83bff122020-11-20 15:51:39 -0800529 return camera3::Size(maxJpegWidth, maxJpegHeight);
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700530}
531
Shuzhen Wangc28dccc2016-02-11 23:48:46 -0800532nsecs_t Camera3Device::getMonoToBoottimeOffset() {
533 // try three times to get the clock offset, choose the one
534 // with the minimum gap in measurements.
535 const int tries = 3;
536 nsecs_t bestGap, measured;
537 for (int i = 0; i < tries; ++i) {
538 const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
539 const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
540 const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
541 const nsecs_t gap = tmono2 - tmono;
542 if (i == 0 || gap < bestGap) {
543 bestGap = gap;
544 measured = tbase - ((tmono + tmono2) >> 1);
545 }
546 }
547 return measured;
548}
549
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800550hardware::graphics::common::V1_0::PixelFormat Camera3Device::mapToPixelFormat(
551 int frameworkFormat) {
552 return (hardware::graphics::common::V1_0::PixelFormat) frameworkFormat;
553}
554
555DataspaceFlags Camera3Device::mapToHidlDataspace(
556 android_dataspace dataSpace) {
557 return dataSpace;
558}
559
Chia-I Wu67a0c0e2017-04-06 13:37:01 -0700560BufferUsageFlags Camera3Device::mapToConsumerUsage(
Emilian Peev050f5dc2017-05-18 14:43:56 +0100561 uint64_t usage) {
Yin-Chia Yeh47cf8e62017-04-04 13:00:03 -0700562 return usage;
563}
564
Emilian Peevf4816702020-04-03 15:44:51 -0700565StreamRotation Camera3Device::mapToStreamRotation(camera_stream_rotation_t rotation) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800566 switch (rotation) {
Emilian Peevf4816702020-04-03 15:44:51 -0700567 case CAMERA_STREAM_ROTATION_0:
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800568 return StreamRotation::ROTATION_0;
Emilian Peevf4816702020-04-03 15:44:51 -0700569 case CAMERA_STREAM_ROTATION_90:
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800570 return StreamRotation::ROTATION_90;
Emilian Peevf4816702020-04-03 15:44:51 -0700571 case CAMERA_STREAM_ROTATION_180:
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800572 return StreamRotation::ROTATION_180;
Emilian Peevf4816702020-04-03 15:44:51 -0700573 case CAMERA_STREAM_ROTATION_270:
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800574 return StreamRotation::ROTATION_270;
575 }
576 ALOGE("%s: Unknown stream rotation %d", __FUNCTION__, rotation);
577 return StreamRotation::ROTATION_0;
578}
579
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800580status_t Camera3Device::mapToStreamConfigurationMode(
Emilian Peevf4816702020-04-03 15:44:51 -0700581 camera_stream_configuration_mode_t operationMode, StreamConfigurationMode *mode) {
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800582 if (mode == nullptr) return BAD_VALUE;
Emilian Peevf4816702020-04-03 15:44:51 -0700583 if (operationMode < CAMERA_VENDOR_STREAM_CONFIGURATION_MODE_START) {
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800584 switch(operationMode) {
Emilian Peevf4816702020-04-03 15:44:51 -0700585 case CAMERA_STREAM_CONFIGURATION_NORMAL_MODE:
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800586 *mode = StreamConfigurationMode::NORMAL_MODE;
587 break;
Emilian Peevf4816702020-04-03 15:44:51 -0700588 case CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800589 *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
590 break;
591 default:
592 ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
593 return BAD_VALUE;
594 }
595 } else {
596 *mode = static_cast<StreamConfigurationMode>(operationMode);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800597 }
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800598 return OK;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800599}
600
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800601int Camera3Device::mapToFrameworkFormat(
602 hardware::graphics::common::V1_0::PixelFormat pixelFormat) {
603 return static_cast<uint32_t>(pixelFormat);
604}
605
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700606android_dataspace Camera3Device::mapToFrameworkDataspace(
607 DataspaceFlags dataSpace) {
608 return static_cast<android_dataspace>(dataSpace);
609}
610
Emilian Peev050f5dc2017-05-18 14:43:56 +0100611uint64_t Camera3Device::mapConsumerToFrameworkUsage(
Chia-I Wu67a0c0e2017-04-06 13:37:01 -0700612 BufferUsageFlags usage) {
Yin-Chia Yeh47cf8e62017-04-04 13:00:03 -0700613 return usage;
614}
615
Emilian Peev050f5dc2017-05-18 14:43:56 +0100616uint64_t Camera3Device::mapProducerToFrameworkUsage(
Chia-I Wu67a0c0e2017-04-06 13:37:01 -0700617 BufferUsageFlags usage) {
Yin-Chia Yeh47cf8e62017-04-04 13:00:03 -0700618 return usage;
619}
620
Zhijun Hef7da0962014-04-24 13:27:56 -0700621ssize_t Camera3Device::getJpegBufferSize(uint32_t width, uint32_t height) const {
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700622 // Get max jpeg size (area-wise).
Shuzhen Wang83bff122020-11-20 15:51:39 -0800623 camera3::Size maxJpegResolution = getMaxJpegResolution();
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700624 if (maxJpegResolution.width == 0) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800625 ALOGE("%s: Camera %s: Can't find valid available jpeg sizes in static metadata!",
626 __FUNCTION__, mId.string());
Zhijun Hef7da0962014-04-24 13:27:56 -0700627 return BAD_VALUE;
628 }
629
Zhijun Hef7da0962014-04-24 13:27:56 -0700630 // Get max jpeg buffer size
631 ssize_t maxJpegBufferSize = 0;
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700632 camera_metadata_ro_entry jpegBufMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE);
633 if (jpegBufMaxSize.count == 0) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800634 ALOGE("%s: Camera %s: Can't find maximum JPEG size in static metadata!", __FUNCTION__,
635 mId.string());
Zhijun Hef7da0962014-04-24 13:27:56 -0700636 return BAD_VALUE;
637 }
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700638 maxJpegBufferSize = jpegBufMaxSize.data.i32[0];
Yin-Chia Yeh0c4e56d2015-01-09 15:21:27 -0800639 assert(kMinJpegBufferSize < maxJpegBufferSize);
Zhijun Hef7da0962014-04-24 13:27:56 -0700640
641 // Calculate final jpeg buffer size for the given resolution.
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700642 float scaleFactor = ((float) (width * height)) /
643 (maxJpegResolution.width * maxJpegResolution.height);
Yin-Chia Yeh0c4e56d2015-01-09 15:21:27 -0800644 ssize_t jpegBufferSize = scaleFactor * (maxJpegBufferSize - kMinJpegBufferSize) +
645 kMinJpegBufferSize;
Zhijun Hef7da0962014-04-24 13:27:56 -0700646 if (jpegBufferSize > maxJpegBufferSize) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800647 ALOGI("%s: jpeg buffer size calculated is > maxJpeg bufferSize(%zd), clamping",
648 __FUNCTION__, maxJpegBufferSize);
Zhijun Hef7da0962014-04-24 13:27:56 -0700649 jpegBufferSize = maxJpegBufferSize;
Zhijun Hef7da0962014-04-24 13:27:56 -0700650 }
651
652 return jpegBufferSize;
653}
654
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700655ssize_t Camera3Device::getPointCloudBufferSize() const {
656 const int FLOATS_PER_POINT=4;
657 camera_metadata_ro_entry maxPointCount = mDeviceInfo.find(ANDROID_DEPTH_MAX_DEPTH_SAMPLES);
658 if (maxPointCount.count == 0) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800659 ALOGE("%s: Camera %s: Can't find maximum depth point cloud size in static metadata!",
660 __FUNCTION__, mId.string());
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700661 return BAD_VALUE;
662 }
663 ssize_t maxBytesForPointCloud = sizeof(android_depth_points) +
664 maxPointCount.data.i32[0] * sizeof(float) * FLOATS_PER_POINT;
665 return maxBytesForPointCloud;
666}
667
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800668ssize_t Camera3Device::getRawOpaqueBufferSize(int32_t width, int32_t height,
669 bool maxResolution) const {
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -0800670 const int PER_CONFIGURATION_SIZE = 3;
671 const int WIDTH_OFFSET = 0;
672 const int HEIGHT_OFFSET = 1;
673 const int SIZE_OFFSET = 2;
674 camera_metadata_ro_entry rawOpaqueSizes =
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800675 mDeviceInfo.find(
676 camera3::SessionConfigurationUtils::getAppropriateModeTag(
677 ANDROID_SENSOR_OPAQUE_RAW_SIZE,
678 maxResolution));
Aurimas Liutikasbc57b122016-02-16 09:59:16 -0800679 size_t count = rawOpaqueSizes.count;
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -0800680 if (count == 0 || (count % PER_CONFIGURATION_SIZE)) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800681 ALOGE("%s: Camera %s: bad opaque RAW size static metadata length(%zu)!",
682 __FUNCTION__, mId.string(), count);
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -0800683 return BAD_VALUE;
684 }
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700685
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -0800686 for (size_t i = 0; i < count; i += PER_CONFIGURATION_SIZE) {
687 if (width == rawOpaqueSizes.data.i32[i + WIDTH_OFFSET] &&
688 height == rawOpaqueSizes.data.i32[i + HEIGHT_OFFSET]) {
689 return rawOpaqueSizes.data.i32[i + SIZE_OFFSET];
690 }
691 }
692
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800693 ALOGE("%s: Camera %s: cannot find size for %dx%d opaque RAW image!",
694 __FUNCTION__, mId.string(), width, height);
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -0800695 return BAD_VALUE;
696}
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700697
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800698status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
699 ATRACE_CALL();
700 (void)args;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700701
702 // Try to lock, but continue in case of failure (to avoid blocking in
703 // deadlocks)
704 bool gotInterfaceLock = tryLockSpinRightRound(mInterfaceLock);
705 bool gotLock = tryLockSpinRightRound(mLock);
706
707 ALOGW_IF(!gotInterfaceLock,
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800708 "Camera %s: %s: Unable to lock interface lock, proceeding anyway",
709 mId.string(), __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700710 ALOGW_IF(!gotLock,
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800711 "Camera %s: %s: Unable to lock main lock, proceeding anyway",
712 mId.string(), __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700713
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800714 bool dumpTemplates = false;
Eino-Ville Talvala4d453832016-07-15 11:56:53 -0700715
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800716 String16 templatesOption("-t");
717 int n = args.size();
718 for (int i = 0; i < n; i++) {
719 if (args[i] == templatesOption) {
720 dumpTemplates = true;
721 }
Emilian Peevbd8c5032018-02-14 23:05:40 +0000722 if (args[i] == TagMonitor::kMonitorOption) {
Eino-Ville Talvala4d453832016-07-15 11:56:53 -0700723 if (i + 1 < n) {
724 String8 monitorTags = String8(args[i + 1]);
725 if (monitorTags == "off") {
726 mTagMonitor.disableMonitoring();
727 } else {
728 mTagMonitor.parseTagsToMonitor(monitorTags);
729 }
730 } else {
731 mTagMonitor.disableMonitoring();
732 }
733 }
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800734 }
735
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800736 String8 lines;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800737
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800738 const char *status =
739 mStatus == STATUS_ERROR ? "ERROR" :
740 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700741 mStatus == STATUS_UNCONFIGURED ? "UNCONFIGURED" :
742 mStatus == STATUS_CONFIGURED ? "CONFIGURED" :
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800743 mStatus == STATUS_ACTIVE ? "ACTIVE" :
744 "Unknown";
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700745
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800746 lines.appendFormat(" Device status: %s\n", status);
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700747 if (mStatus == STATUS_ERROR) {
748 lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
749 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800750 lines.appendFormat(" Stream configuration:\n");
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -0800751 const char *mode =
752 mOperatingMode == static_cast<int>(StreamConfigurationMode::NORMAL_MODE) ? "NORMAL" :
753 mOperatingMode == static_cast<int>(
754 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ? "CONSTRAINED_HIGH_SPEED" :
755 "CUSTOM";
756 lines.appendFormat(" Operation mode: %s (%d) \n", mode, mOperatingMode);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800757
758 if (mInputStream != NULL) {
759 write(fd, lines.string(), lines.size());
760 mInputStream->dump(fd, args);
761 } else {
762 lines.appendFormat(" No input stream.\n");
763 write(fd, lines.string(), lines.size());
764 }
765 for (size_t i = 0; i < mOutputStreams.size(); i++) {
766 mOutputStreams[i]->dump(fd,args);
767 }
768
Zhijun He431503c2016-03-07 17:30:16 -0800769 if (mBufferManager != NULL) {
770 lines = String8(" Camera3 Buffer Manager:\n");
771 write(fd, lines.string(), lines.size());
772 mBufferManager->dump(fd, args);
773 }
Zhijun He125684a2015-12-26 15:07:30 -0800774
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700775 lines = String8(" In-flight requests:\n");
776 if (mInFlightMap.size() == 0) {
777 lines.append(" None\n");
778 } else {
779 for (size_t i = 0; i < mInFlightMap.size(); i++) {
780 InFlightRequest r = mInFlightMap.valueAt(i);
Colin Crosse5729fa2014-03-21 15:04:25 -0700781 lines.appendFormat(" Frame %d | Timestamp: %" PRId64 ", metadata"
Greg Kaiser51b882c2020-06-10 05:41:44 +0000782 " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
Chien-Yu Chen43e69a62014-11-25 16:38:33 -0800783 r.shutterTimestamp, r.haveResultMetadata ? "true" : "false",
Greg Kaiser51b882c2020-06-10 05:41:44 +0000784 r.numBuffersLeft);
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700785 }
786 }
787 write(fd, lines.string(), lines.size());
788
Shuzhen Wang686f6442017-06-20 16:16:04 -0700789 if (mRequestThread != NULL) {
790 mRequestThread->dumpCaptureRequestLatency(fd,
791 " ProcessCaptureRequest latency histogram:");
792 }
793
Igor Murashkin1e479c02013-09-06 16:55:14 -0700794 {
795 lines = String8(" Last request sent:\n");
796 write(fd, lines.string(), lines.size());
797
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700798 CameraMetadata lastRequest = getLatestRequestLocked();
Igor Murashkin1e479c02013-09-06 16:55:14 -0700799 lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
800 }
801
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800802 if (dumpTemplates) {
Emilian Peevf4816702020-04-03 15:44:51 -0700803 const char *templateNames[CAMERA_TEMPLATE_COUNT] = {
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800804 "TEMPLATE_PREVIEW",
805 "TEMPLATE_STILL_CAPTURE",
806 "TEMPLATE_VIDEO_RECORD",
807 "TEMPLATE_VIDEO_SNAPSHOT",
808 "TEMPLATE_ZERO_SHUTTER_LAG",
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -0800809 "TEMPLATE_MANUAL",
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800810 };
811
Emilian Peevf4816702020-04-03 15:44:51 -0700812 for (int i = 1; i < CAMERA_TEMPLATE_COUNT; i++) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800813 camera_metadata_t *templateRequest = nullptr;
814 mInterface->constructDefaultRequestSettings(
Emilian Peevf4816702020-04-03 15:44:51 -0700815 (camera_request_template_t) i, &templateRequest);
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800816 lines = String8::format(" HAL Request %s:\n", templateNames[i-1]);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800817 if (templateRequest == nullptr) {
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800818 lines.append(" Not supported\n");
819 write(fd, lines.string(), lines.size());
820 } else {
821 write(fd, lines.string(), lines.size());
822 dump_indented_camera_metadata(templateRequest,
823 fd, /*verbosity*/2, /*indentation*/8);
824 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800825 free_camera_metadata(templateRequest);
Eino-Ville Talvala7e7a62d2015-11-04 14:49:43 -0800826 }
827 }
828
Eino-Ville Talvala4d453832016-07-15 11:56:53 -0700829 mTagMonitor.dumpMonitoredMetadata(fd);
830
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800831 if (mInterface->valid()) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -0800832 lines = String8(" HAL device dump:\n");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800833 write(fd, lines.string(), lines.size());
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -0800834 mInterface->dump(fd);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800835 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800836
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700837 if (gotLock) mLock.unlock();
838 if (gotInterfaceLock) mInterfaceLock.unlock();
839
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800840 return OK;
841}
842
Emilian Peevfaa4bde2020-01-23 12:19:37 -0800843const CameraMetadata& Camera3Device::infoPhysical(const String8& physicalId) const {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800844 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800845 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
846 mStatus == STATUS_ERROR)) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700847 ALOGW("%s: Access to static info %s!", __FUNCTION__,
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800848 mStatus == STATUS_ERROR ?
849 "when in error state" : "before init");
850 }
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -0700851 if (physicalId.isEmpty()) {
852 return mDeviceInfo;
853 } else {
854 std::string id(physicalId.c_str());
855 if (mPhysicalDeviceInfoMap.find(id) != mPhysicalDeviceInfoMap.end()) {
856 return mPhysicalDeviceInfoMap.at(id);
857 } else {
858 ALOGE("%s: Invalid physical camera id %s", __FUNCTION__, physicalId.c_str());
859 return mDeviceInfo;
860 }
861 }
862}
863
864const CameraMetadata& Camera3Device::info() const {
865 String8 emptyId;
Emilian Peevfaa4bde2020-01-23 12:19:37 -0800866 return infoPhysical(emptyId);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800867}
868
Jianing Wei90e59c92014-03-12 18:29:36 -0700869status_t Camera3Device::checkStatusOkToCaptureLocked() {
870 switch (mStatus) {
871 case STATUS_ERROR:
872 CLOGE("Device has encountered a serious error");
873 return INVALID_OPERATION;
874 case STATUS_UNINITIALIZED:
875 CLOGE("Device not initialized");
876 return INVALID_OPERATION;
877 case STATUS_UNCONFIGURED:
878 case STATUS_CONFIGURED:
879 case STATUS_ACTIVE:
880 // OK
881 break;
882 default:
883 SET_ERR_L("Unexpected status: %d", mStatus);
884 return INVALID_OPERATION;
885 }
886 return OK;
887}
888
889status_t Camera3Device::convertMetadataListToRequestListLocked(
Emilian Peevaebbe412018-01-15 13:53:24 +0000890 const List<const PhysicalCameraSettingsList> &metadataList,
Shuzhen Wang0129d522016-10-30 22:43:41 -0700891 const std::list<const SurfaceMap> &surfaceMaps,
Shuzhen Wang316781a2020-08-18 18:11:01 -0700892 bool repeating, nsecs_t requestTimeNs,
Shuzhen Wang9d066012016-09-30 11:30:20 -0700893 RequestList *requestList) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700894 if (requestList == NULL) {
895 CLOGE("requestList cannot be NULL.");
896 return BAD_VALUE;
897 }
898
Jianing Weicb0652e2014-03-12 18:29:36 -0700899 int32_t burstId = 0;
Emilian Peevaebbe412018-01-15 13:53:24 +0000900 List<const PhysicalCameraSettingsList>::const_iterator metadataIt = metadataList.begin();
Shuzhen Wang0129d522016-10-30 22:43:41 -0700901 std::list<const SurfaceMap>::const_iterator surfaceMapIt = surfaceMaps.begin();
902 for (; metadataIt != metadataList.end() && surfaceMapIt != surfaceMaps.end();
903 ++metadataIt, ++surfaceMapIt) {
904 sp<CaptureRequest> newRequest = setUpRequestLocked(*metadataIt, *surfaceMapIt);
Jianing Wei90e59c92014-03-12 18:29:36 -0700905 if (newRequest == 0) {
906 CLOGE("Can't create capture request");
907 return BAD_VALUE;
908 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700909
Shuzhen Wang9d066012016-09-30 11:30:20 -0700910 newRequest->mRepeating = repeating;
Shuzhen Wang316781a2020-08-18 18:11:01 -0700911 newRequest->mRequestTimeNs = requestTimeNs;
Shuzhen Wang9d066012016-09-30 11:30:20 -0700912
Jianing Weicb0652e2014-03-12 18:29:36 -0700913 // Setup burst Id and request Id
914 newRequest->mResultExtras.burstId = burstId++;
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -0800915 auto requestIdEntry = metadataIt->begin()->metadata.find(ANDROID_REQUEST_ID);
916 if (requestIdEntry.count == 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -0700917 CLOGE("RequestID does not exist in metadata");
918 return BAD_VALUE;
919 }
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -0800920 newRequest->mResultExtras.requestId = requestIdEntry.data.i32[0];
Jianing Weicb0652e2014-03-12 18:29:36 -0700921
Jianing Wei90e59c92014-03-12 18:29:36 -0700922 requestList->push_back(newRequest);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700923
924 ALOGV("%s: requestId = %" PRId32, __FUNCTION__, newRequest->mResultExtras.requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700925 }
Shuzhen Wang0129d522016-10-30 22:43:41 -0700926 if (metadataIt != metadataList.end() || surfaceMapIt != surfaceMaps.end()) {
927 ALOGE("%s: metadataList and surfaceMaps are not the same size!", __FUNCTION__);
928 return BAD_VALUE;
929 }
Chien-Yu Chen85a64552015-08-28 15:46:12 -0700930
931 // Setup batch size if this is a high speed video recording request.
932 if (mIsConstrainedHighSpeedConfiguration && requestList->size() > 0) {
933 auto firstRequest = requestList->begin();
934 for (auto& outputStream : (*firstRequest)->mOutputStreams) {
935 if (outputStream->isVideoStream()) {
936 (*firstRequest)->mBatchSize = requestList->size();
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800937 outputStream->setBatchSize(requestList->size());
Chien-Yu Chen85a64552015-08-28 15:46:12 -0700938 break;
939 }
940 }
941 }
942
Jianing Wei90e59c92014-03-12 18:29:36 -0700943 return OK;
944}
945
Yin-Chia Yeh7e5a2042019-02-06 16:01:06 -0800946status_t Camera3Device::capture(CameraMetadata &request, int64_t* lastFrameNumber) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800947 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800948
Emilian Peevaebbe412018-01-15 13:53:24 +0000949 List<const PhysicalCameraSettingsList> requestsList;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700950 std::list<const SurfaceMap> surfaceMaps;
Emilian Peevaebbe412018-01-15 13:53:24 +0000951 convertToRequestList(requestsList, surfaceMaps, request);
Shuzhen Wang0129d522016-10-30 22:43:41 -0700952
Yin-Chia Yeh7e5a2042019-02-06 16:01:06 -0800953 return captureList(requestsList, surfaceMaps, lastFrameNumber);
Shuzhen Wang0129d522016-10-30 22:43:41 -0700954}
955
Emilian Peevaebbe412018-01-15 13:53:24 +0000956void Camera3Device::convertToRequestList(List<const PhysicalCameraSettingsList>& requestsList,
Shuzhen Wang0129d522016-10-30 22:43:41 -0700957 std::list<const SurfaceMap>& surfaceMaps,
958 const CameraMetadata& request) {
Emilian Peevaebbe412018-01-15 13:53:24 +0000959 PhysicalCameraSettingsList requestList;
960 requestList.push_back({std::string(getId().string()), request});
961 requestsList.push_back(requestList);
Shuzhen Wang0129d522016-10-30 22:43:41 -0700962
963 SurfaceMap surfaceMap;
964 camera_metadata_ro_entry streams = request.find(ANDROID_REQUEST_OUTPUT_STREAMS);
965 // With no surface list passed in, stream and surface will have 1-to-1
966 // mapping. So the surface index is 0 for each stream in the surfaceMap.
967 for (size_t i = 0; i < streams.count; i++) {
968 surfaceMap[streams.data.i32[i]].push_back(0);
969 }
970 surfaceMaps.push_back(surfaceMap);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800971}
972
Jianing Wei90e59c92014-03-12 18:29:36 -0700973status_t Camera3Device::submitRequestsHelper(
Emilian Peevaebbe412018-01-15 13:53:24 +0000974 const List<const PhysicalCameraSettingsList> &requests,
Shuzhen Wang0129d522016-10-30 22:43:41 -0700975 const std::list<const SurfaceMap> &surfaceMaps,
976 bool repeating,
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700977 /*out*/
978 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700979 ATRACE_CALL();
Shuzhen Wang316781a2020-08-18 18:11:01 -0700980 nsecs_t requestTimeNs = systemTime();
981
Jianing Wei90e59c92014-03-12 18:29:36 -0700982 Mutex::Autolock il(mInterfaceLock);
983 Mutex::Autolock l(mLock);
984
985 status_t res = checkStatusOkToCaptureLocked();
986 if (res != OK) {
987 // error logged by previous call
988 return res;
989 }
990
991 RequestList requestList;
992
Shuzhen Wang0129d522016-10-30 22:43:41 -0700993 res = convertMetadataListToRequestListLocked(requests, surfaceMaps,
Shuzhen Wang316781a2020-08-18 18:11:01 -0700994 repeating, requestTimeNs, /*out*/&requestList);
Jianing Wei90e59c92014-03-12 18:29:36 -0700995 if (res != OK) {
996 // error logged by previous call
997 return res;
998 }
999
1000 if (repeating) {
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07001001 res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -07001002 } else {
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07001003 res = mRequestThread->queueRequestList(requestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -07001004 }
1005
1006 if (res == OK) {
1007 waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
1008 if (res != OK) {
1009 SET_ERR_L("Can't transition to active in %f seconds!",
1010 kActiveTimeout/1e9);
1011 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001012 ALOGV("Camera %s: Capture request %" PRId32 " enqueued", mId.string(),
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07001013 (*(requestList.begin()))->mResultExtras.requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -07001014 } else {
1015 CLOGE("Cannot queue request. Impossible.");
1016 return BAD_VALUE;
1017 }
1018
1019 return res;
1020}
1021
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07001022hardware::Return<void> Camera3Device::requestStreamBuffers(
1023 const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
1024 requestStreamBuffers_cb _hidl_cb) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001025 RequestBufferStates states {
Shuzhen Wang316781a2020-08-18 18:11:01 -07001026 mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001027 *this, *mInterface, *this};
1028 camera3::requestStreamBuffers(states, bufReqs, _hidl_cb);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07001029 return hardware::Void();
1030}
1031
1032hardware::Return<void> Camera3Device::returnStreamBuffers(
1033 const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer>& buffers) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001034 ReturnBufferStates states {
Shuzhen Wang316781a2020-08-18 18:11:01 -07001035 mId, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder, *mInterface};
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001036 camera3::returnStreamBuffers(states, buffers);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07001037 return hardware::Void();
1038}
1039
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001040hardware::Return<void> Camera3Device::processCaptureResult_3_4(
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001041 const hardware::hidl_vec<
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001042 hardware::camera::device::V3_4::CaptureResult>& results) {
Yin-Chia Yeh657c1872017-07-18 18:09:57 -07001043 // Ideally we should grab mLock, but that can lead to deadlock, and
1044 // it's not super important to get up to date value of mStatus for this
1045 // warning print, hence skipping the lock here
1046 if (mStatus == STATUS_ERROR) {
1047 // Per API contract, HAL should act as closed after device error
1048 // But mStatus can be set to error by framework as well, so just log
1049 // a warning here.
1050 ALOGW("%s: received capture result in error state.", __FUNCTION__);
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -07001051 }
Yifan Honga640c5a2017-04-12 16:30:31 -07001052
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001053 sp<NotificationListener> listener;
1054 {
1055 std::lock_guard<std::mutex> l(mOutputLock);
1056 listener = mListener.promote();
1057 }
1058
Yifan Honga640c5a2017-04-12 16:30:31 -07001059 if (mProcessCaptureResultLock.tryLock() != OK) {
1060 // This should never happen; it indicates a wrong client implementation
1061 // that doesn't follow the contract. But, we can be tolerant here.
1062 ALOGE("%s: callback overlapped! waiting 1s...",
1063 __FUNCTION__);
1064 if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
1065 ALOGE("%s: cannot acquire lock in 1s, dropping results",
1066 __FUNCTION__);
1067 // really don't know what to do, so bail out.
1068 return hardware::Void();
1069 }
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001070 }
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001071 CaptureOutputStates states {
1072 mId,
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001073 mInFlightLock, mLastCompletedRegularFrameNumber,
1074 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1075 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001076 mNextShutterFrameNumber,
1077 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1078 mNextResultFrameNumber,
1079 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1080 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1081 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08001082 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
Shuzhen Wang316781a2020-08-18 18:11:01 -07001083 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
1084 *mInterface
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001085 };
1086
Yifan Honga640c5a2017-04-12 16:30:31 -07001087 for (const auto& result : results) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001088 processOneCaptureResultLocked(states, result.v3_2, result.physicalCameraMetadata);
Yifan Honga640c5a2017-04-12 16:30:31 -07001089 }
1090 mProcessCaptureResultLock.unlock();
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001091 return hardware::Void();
1092}
1093
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001094// Only one processCaptureResult should be called at a time, so
1095// the locks won't block. The locks are present here simply to enforce this.
1096hardware::Return<void> Camera3Device::processCaptureResult(
1097 const hardware::hidl_vec<
1098 hardware::camera::device::V3_2::CaptureResult>& results) {
1099 hardware::hidl_vec<hardware::camera::device::V3_4::PhysicalCameraMetadata> noPhysMetadata;
1100
1101 // Ideally we should grab mLock, but that can lead to deadlock, and
1102 // it's not super important to get up to date value of mStatus for this
1103 // warning print, hence skipping the lock here
1104 if (mStatus == STATUS_ERROR) {
1105 // Per API contract, HAL should act as closed after device error
1106 // But mStatus can be set to error by framework as well, so just log
1107 // a warning here.
1108 ALOGW("%s: received capture result in error state.", __FUNCTION__);
1109 }
1110
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001111 sp<NotificationListener> listener;
1112 {
1113 std::lock_guard<std::mutex> l(mOutputLock);
1114 listener = mListener.promote();
1115 }
1116
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001117 if (mProcessCaptureResultLock.tryLock() != OK) {
1118 // This should never happen; it indicates a wrong client implementation
1119 // that doesn't follow the contract. But, we can be tolerant here.
1120 ALOGE("%s: callback overlapped! waiting 1s...",
1121 __FUNCTION__);
1122 if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
1123 ALOGE("%s: cannot acquire lock in 1s, dropping results",
1124 __FUNCTION__);
1125 // really don't know what to do, so bail out.
1126 return hardware::Void();
1127 }
1128 }
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001129
1130 CaptureOutputStates states {
1131 mId,
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001132 mInFlightLock, mLastCompletedRegularFrameNumber,
1133 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1134 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001135 mNextShutterFrameNumber,
1136 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1137 mNextResultFrameNumber,
1138 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1139 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1140 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08001141 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
Shuzhen Wang316781a2020-08-18 18:11:01 -07001142 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
1143 *mInterface
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001144 };
1145
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001146 for (const auto& result : results) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001147 processOneCaptureResultLocked(states, result, noPhysMetadata);
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001148 }
1149 mProcessCaptureResultLock.unlock();
1150 return hardware::Void();
1151}
1152
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001153hardware::Return<void> Camera3Device::notify(
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001154 const hardware::hidl_vec<hardware::camera::device::V3_2::NotifyMsg>& msgs) {
Yin-Chia Yeh657c1872017-07-18 18:09:57 -07001155 // Ideally we should grab mLock, but that can lead to deadlock, and
1156 // it's not super important to get up to date value of mStatus for this
1157 // warning print, hence skipping the lock here
1158 if (mStatus == STATUS_ERROR) {
1159 // Per API contract, HAL should act as closed after device error
1160 // But mStatus can be set to error by framework as well, so just log
1161 // a warning here.
1162 ALOGW("%s: received notify message in error state.", __FUNCTION__);
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -07001163 }
Yin-Chia Yeh657c1872017-07-18 18:09:57 -07001164
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001165 sp<NotificationListener> listener;
1166 {
1167 std::lock_guard<std::mutex> l(mOutputLock);
1168 listener = mListener.promote();
1169 }
1170
1171 CaptureOutputStates states {
1172 mId,
Shuzhen Wangb7b42652020-05-07 11:59:02 -07001173 mInFlightLock, mLastCompletedRegularFrameNumber,
1174 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1175 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001176 mNextShutterFrameNumber,
1177 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1178 mNextResultFrameNumber,
1179 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1180 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1181 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08001182 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
Shuzhen Wang316781a2020-08-18 18:11:01 -07001183 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
1184 *mInterface
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001185 };
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001186 for (const auto& msg : msgs) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001187 camera3::notify(states, msg);
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08001188 }
1189 return hardware::Void();
1190}
1191
Emilian Peevaebbe412018-01-15 13:53:24 +00001192status_t Camera3Device::captureList(const List<const PhysicalCameraSettingsList> &requestsList,
Shuzhen Wang0129d522016-10-30 22:43:41 -07001193 const std::list<const SurfaceMap> &surfaceMaps,
Jianing Weicb0652e2014-03-12 18:29:36 -07001194 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -07001195 ATRACE_CALL();
1196
Emilian Peevaebbe412018-01-15 13:53:24 +00001197 return submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/false, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -07001198}
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001199
Jianing Weicb0652e2014-03-12 18:29:36 -07001200status_t Camera3Device::setStreamingRequest(const CameraMetadata &request,
1201 int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001202 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001203
Emilian Peevaebbe412018-01-15 13:53:24 +00001204 List<const PhysicalCameraSettingsList> requestsList;
Shuzhen Wang0129d522016-10-30 22:43:41 -07001205 std::list<const SurfaceMap> surfaceMaps;
Emilian Peevaebbe412018-01-15 13:53:24 +00001206 convertToRequestList(requestsList, surfaceMaps, request);
Shuzhen Wang0129d522016-10-30 22:43:41 -07001207
Emilian Peevaebbe412018-01-15 13:53:24 +00001208 return setStreamingRequestList(requestsList, /*surfaceMap*/surfaceMaps,
Shuzhen Wang0129d522016-10-30 22:43:41 -07001209 /*lastFrameNumber*/NULL);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001210}
1211
Emilian Peevaebbe412018-01-15 13:53:24 +00001212status_t Camera3Device::setStreamingRequestList(
1213 const List<const PhysicalCameraSettingsList> &requestsList,
1214 const std::list<const SurfaceMap> &surfaceMaps, int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -07001215 ATRACE_CALL();
1216
Emilian Peevaebbe412018-01-15 13:53:24 +00001217 return submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/true, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -07001218}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001219
1220sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
Emilian Peevaebbe412018-01-15 13:53:24 +00001221 const PhysicalCameraSettingsList &request, const SurfaceMap &surfaceMap) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001222 status_t res;
1223
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001224 if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
Eino-Ville Talvalae7091aa2017-03-07 15:23:06 -08001225 // This point should only be reached via API1 (API2 must explicitly call configureStreams)
1226 // so unilaterally select normal operating mode.
Emilian Peevaebbe412018-01-15 13:53:24 +00001227 res = filterParamsAndConfigureLocked(request.begin()->metadata,
Emilian Peevf4816702020-04-03 15:44:51 -07001228 CAMERA_STREAM_CONFIGURATION_NORMAL_MODE);
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07001229 // Stream configuration failed. Client might try other configuraitons.
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001230 if (res != OK) {
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07001231 CLOGE("Can't set up streams: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001232 return NULL;
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07001233 } else if (mStatus == STATUS_UNCONFIGURED) {
1234 // Stream configuration successfully configure to empty stream configuration.
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001235 CLOGE("No streams configured");
1236 return NULL;
1237 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001238 }
1239
Shuzhen Wang0129d522016-10-30 22:43:41 -07001240 sp<CaptureRequest> newRequest = createCaptureRequest(request, surfaceMap);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001241 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001242}
1243
Jianing Weicb0652e2014-03-12 18:29:36 -07001244status_t Camera3Device::clearStreamingRequest(int64_t *lastFrameNumber) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001245 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001246 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001247 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001248
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001249 switch (mStatus) {
1250 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001251 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001252 return INVALID_OPERATION;
1253 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001254 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001255 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001256 case STATUS_UNCONFIGURED:
1257 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001258 case STATUS_ACTIVE:
1259 // OK
1260 break;
1261 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001262 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001263 return INVALID_OPERATION;
1264 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001265 ALOGV("Camera %s: Clearing repeating request", mId.string());
Jianing Weicb0652e2014-03-12 18:29:36 -07001266
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07001267 return mRequestThread->clearRepeatingRequests(lastFrameNumber);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001268}
1269
1270status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
1271 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001272 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001273
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001274 return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001275}
1276
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001277status_t Camera3Device::createInputStream(
Shuzhen Wang83bff122020-11-20 15:51:39 -08001278 uint32_t width, uint32_t height, int format, bool isMultiResolution, int *id) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001279 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001280 Mutex::Autolock il(mInterfaceLock);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001281 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001282 Mutex::Autolock l(mLock);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001283 ALOGV("Camera %s: Creating new input stream %d: %d x %d, format %d",
1284 mId.string(), mNextStreamId, width, height, format);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001285
1286 status_t res;
1287 bool wasActive = false;
1288
1289 switch (mStatus) {
1290 case STATUS_ERROR:
1291 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
1292 return INVALID_OPERATION;
1293 case STATUS_UNINITIALIZED:
1294 ALOGE("%s: Device not initialized", __FUNCTION__);
1295 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001296 case STATUS_UNCONFIGURED:
1297 case STATUS_CONFIGURED:
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001298 // OK
1299 break;
1300 case STATUS_ACTIVE:
1301 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001302 res = internalPauseAndWaitLocked(maxExpectedDuration);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001303 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001304 SET_ERR_L("Can't pause captures to reconfigure streams!");
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001305 return res;
1306 }
1307 wasActive = true;
1308 break;
1309 default:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001310 SET_ERR_L("%s: Unexpected status: %d", mStatus);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001311 return INVALID_OPERATION;
1312 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001313 assert(mStatus != STATUS_ACTIVE);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001314
1315 if (mInputStream != 0) {
1316 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
1317 return INVALID_OPERATION;
1318 }
1319
1320 sp<Camera3InputStream> newStream = new Camera3InputStream(mNextStreamId,
1321 width, height, format);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001322 newStream->setStatusTracker(mStatusTracker);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001323
1324 mInputStream = newStream;
Shuzhen Wang83bff122020-11-20 15:51:39 -08001325 mIsInputStreamMultiResolution = isMultiResolution;
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001326
1327 *id = mNextStreamId++;
1328
1329 // Continue captures if active at start
1330 if (wasActive) {
1331 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001332 // Reuse current operating mode and session parameters for new stream config
1333 res = configureStreamsLocked(mOperatingMode, mSessionParams);
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001334 if (res != OK) {
1335 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
1336 __FUNCTION__, mNextStreamId, strerror(-res), res);
1337 return res;
1338 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001339 internalResumeLocked();
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001340 }
1341
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001342 ALOGV("Camera %s: Created input stream", mId.string());
Igor Murashkin5a269fa2013-04-15 14:59:22 -07001343 return OK;
1344}
1345
Eino-Ville Talvala727d1722015-06-09 13:44:19 -07001346status_t Camera3Device::createStream(sp<Surface> consumer,
Shuzhen Wang0129d522016-10-30 22:43:41 -07001347 uint32_t width, uint32_t height, int format,
Emilian Peevf4816702020-04-03 15:44:51 -07001348 android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
Shuzhen Wangc28189a2017-11-27 23:05:10 -08001349 const String8& physicalCameraId,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001350 const std::unordered_set<int32_t> &sensorPixelModesUsed,
1351 std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
1352 uint64_t consumerUsage) {
Shuzhen Wang0129d522016-10-30 22:43:41 -07001353 ATRACE_CALL();
1354
1355 if (consumer == nullptr) {
1356 ALOGE("%s: consumer must not be null", __FUNCTION__);
1357 return BAD_VALUE;
1358 }
1359
1360 std::vector<sp<Surface>> consumers;
1361 consumers.push_back(consumer);
1362
1363 return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001364 format, dataSpace, rotation, id, physicalCameraId, sensorPixelModesUsed, surfaceIds,
1365 streamSetId, isShared, isMultiResolution, consumerUsage);
1366}
1367
1368static bool isRawFormat(int format) {
1369 switch (format) {
1370 case HAL_PIXEL_FORMAT_RAW16:
1371 case HAL_PIXEL_FORMAT_RAW12:
1372 case HAL_PIXEL_FORMAT_RAW10:
1373 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1374 return true;
1375 default:
1376 return false;
1377 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07001378}
1379
1380status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
1381 bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
Emilian Peevf4816702020-04-03 15:44:51 -07001382 android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001383 const String8& physicalCameraId, const std::unordered_set<int32_t> &sensorPixelModesUsed,
Shuzhen Wang83bff122020-11-20 15:51:39 -08001384 std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
1385 uint64_t consumerUsage) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001386 ATRACE_CALL();
Emilian Peev40ead602017-09-26 15:46:36 +01001387
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001388 Mutex::Autolock il(mInterfaceLock);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001389 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001390 Mutex::Autolock l(mLock);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001391 ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
Shuzhen Wang83bff122020-11-20 15:51:39 -08001392 " consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s, isMultiResolution %d",
1393 mId.string(), mNextStreamId, width, height, format, dataSpace, rotation,
1394 consumerUsage, isShared, physicalCameraId.string(), isMultiResolution);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001395
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001396 status_t res;
1397 bool wasActive = false;
1398
1399 switch (mStatus) {
1400 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001401 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001402 return INVALID_OPERATION;
1403 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001404 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001405 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001406 case STATUS_UNCONFIGURED:
1407 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001408 // OK
1409 break;
1410 case STATUS_ACTIVE:
1411 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001412 res = internalPauseAndWaitLocked(maxExpectedDuration);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001413 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001414 SET_ERR_L("Can't pause captures to reconfigure streams!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001415 return res;
1416 }
1417 wasActive = true;
1418 break;
1419 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001420 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001421 return INVALID_OPERATION;
1422 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001423 assert(mStatus != STATUS_ACTIVE);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001424
1425 sp<Camera3OutputStream> newStream;
Zhijun He5d677d12016-05-29 16:52:39 -07001426
Shuzhen Wang0129d522016-10-30 22:43:41 -07001427 if (consumers.size() == 0 && !hasDeferredConsumer) {
1428 ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
1429 return BAD_VALUE;
1430 }
Zhijun He5d677d12016-05-29 16:52:39 -07001431
Shuzhen Wang0129d522016-10-30 22:43:41 -07001432 if (hasDeferredConsumer && format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
Zhijun He5d677d12016-05-29 16:52:39 -07001433 ALOGE("Deferred consumer stream creation only support IMPLEMENTATION_DEFINED format");
1434 return BAD_VALUE;
1435 }
1436
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001437 if (isRawFormat(format) && sensorPixelModesUsed.size() > 1) {
1438 // We can't use one stream with a raw format in both sensor pixel modes since its going to
1439 // be found in only one sensor pixel mode.
1440 ALOGE("%s: RAW opaque stream cannot be used with > 1 sensor pixel modes", __FUNCTION__);
1441 return BAD_VALUE;
1442 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001443 if (format == HAL_PIXEL_FORMAT_BLOB) {
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -07001444 ssize_t blobBufferSize;
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001445 if (dataSpace == HAL_DATASPACE_DEPTH) {
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -07001446 blobBufferSize = getPointCloudBufferSize();
1447 if (blobBufferSize <= 0) {
1448 SET_ERR_L("Invalid point cloud buffer size %zd", blobBufferSize);
1449 return BAD_VALUE;
1450 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001451 } else if (dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
1452 blobBufferSize = width * height;
1453 } else {
1454 blobBufferSize = getJpegBufferSize(width, height);
1455 if (blobBufferSize <= 0) {
1456 SET_ERR_L("Invalid jpeg buffer size %zd", blobBufferSize);
1457 return BAD_VALUE;
1458 }
Zhijun Hef7da0962014-04-24 13:27:56 -07001459 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07001460 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
Shuzhen Wangc28dccc2016-02-11 23:48:46 -08001461 width, height, blobBufferSize, format, dataSpace, rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001462 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
1463 isMultiResolution);
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -08001464 } else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001465 bool maxResolution =
1466 sensorPixelModesUsed.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
1467 sensorPixelModesUsed.end();
1468 ssize_t rawOpaqueBufferSize = getRawOpaqueBufferSize(width, height, maxResolution);
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -08001469 if (rawOpaqueBufferSize <= 0) {
1470 SET_ERR_L("Invalid RAW opaque buffer size %zd", rawOpaqueBufferSize);
1471 return BAD_VALUE;
1472 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07001473 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
Shuzhen Wangc28dccc2016-02-11 23:48:46 -08001474 width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001475 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
1476 isMultiResolution);
Shuzhen Wang758c2152017-01-10 18:26:18 -08001477 } else if (isShared) {
1478 newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
1479 width, height, format, consumerUsage, dataSpace, rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001480 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
1481 mUseHalBufManager);
Shuzhen Wang0129d522016-10-30 22:43:41 -07001482 } else if (consumers.size() == 0 && hasDeferredConsumer) {
Zhijun He5d677d12016-05-29 16:52:39 -07001483 newStream = new Camera3OutputStream(mNextStreamId,
1484 width, height, format, consumerUsage, dataSpace, rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001485 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
1486 isMultiResolution);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001487 } else {
Shuzhen Wang0129d522016-10-30 22:43:41 -07001488 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
Shuzhen Wangc28dccc2016-02-11 23:48:46 -08001489 width, height, format, dataSpace, rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001490 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
1491 isMultiResolution);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001492 }
Emilian Peev40ead602017-09-26 15:46:36 +01001493
1494 size_t consumerCount = consumers.size();
1495 for (size_t i = 0; i < consumerCount; i++) {
1496 int id = newStream->getSurfaceId(consumers[i]);
1497 if (id < 0) {
1498 SET_ERR_L("Invalid surface id");
1499 return BAD_VALUE;
1500 }
1501 if (surfaceIds != nullptr) {
1502 surfaceIds->push_back(id);
1503 }
1504 }
1505
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001506 newStream->setStatusTracker(mStatusTracker);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001507
Emilian Peev08dd2452017-04-06 16:55:14 +01001508 newStream->setBufferManager(mBufferManager);
Zhijun He125684a2015-12-26 15:07:30 -08001509
Shuzhen Wangabbcb6b2020-12-09 22:32:44 -08001510 newStream->setImageDumpMask(mImageDumpMask);
1511
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001512 res = mOutputStreams.add(mNextStreamId, newStream);
1513 if (res < 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001514 SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001515 return res;
1516 }
1517
Shuzhen Wang316781a2020-08-18 18:11:01 -07001518 mSessionStatsBuilder.addStream(mNextStreamId);
1519
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001520 *id = mNextStreamId++;
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001521 mNeedConfig = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001522
1523 // Continue captures if active at start
1524 if (wasActive) {
1525 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001526 // Reuse current operating mode and session parameters for new stream config
1527 res = configureStreamsLocked(mOperatingMode, mSessionParams);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001528 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001529 CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
1530 mNextStreamId, strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001531 return res;
1532 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001533 internalResumeLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001534 }
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001535 ALOGV("Camera %s: Created new stream", mId.string());
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001536 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001537}
1538
Emilian Peev710c1422017-08-30 11:19:38 +01001539status_t Camera3Device::getStreamInfo(int id, StreamInfo *streamInfo) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001540 ATRACE_CALL();
Emilian Peev710c1422017-08-30 11:19:38 +01001541 if (nullptr == streamInfo) {
1542 return BAD_VALUE;
1543 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001544 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001545 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001546
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001547 switch (mStatus) {
1548 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001549 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001550 return INVALID_OPERATION;
1551 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001552 CLOGE("Device not initialized!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001553 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001554 case STATUS_UNCONFIGURED:
1555 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001556 case STATUS_ACTIVE:
1557 // OK
1558 break;
1559 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001560 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001561 return INVALID_OPERATION;
1562 }
1563
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001564 sp<Camera3StreamInterface> stream = mOutputStreams.get(id);
1565 if (stream == nullptr) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001566 CLOGE("Stream %d is unknown", id);
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001567 return BAD_VALUE;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001568 }
1569
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001570 streamInfo->width = stream->getWidth();
1571 streamInfo->height = stream->getHeight();
1572 streamInfo->format = stream->getFormat();
1573 streamInfo->dataSpace = stream->getDataSpace();
1574 streamInfo->formatOverridden = stream->isFormatOverridden();
1575 streamInfo->originalFormat = stream->getOriginalFormat();
1576 streamInfo->dataSpaceOverridden = stream->isDataSpaceOverridden();
1577 streamInfo->originalDataSpace = stream->getOriginalDataSpace();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001578 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001579}
1580
1581status_t Camera3Device::setStreamTransform(int id,
1582 int transform) {
1583 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001584 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001585 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001586
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001587 switch (mStatus) {
1588 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001589 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001590 return INVALID_OPERATION;
1591 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001592 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001593 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001594 case STATUS_UNCONFIGURED:
1595 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001596 case STATUS_ACTIVE:
1597 // OK
1598 break;
1599 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001600 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001601 return INVALID_OPERATION;
1602 }
1603
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001604 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(id);
1605 if (stream == nullptr) {
1606 CLOGE("Stream %d does not exist", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001607 return BAD_VALUE;
1608 }
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001609 return stream->setTransform(transform);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001610}
1611
1612status_t Camera3Device::deleteStream(int id) {
1613 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001614 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001615 Mutex::Autolock l(mLock);
1616 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001617
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001618 ALOGV("%s: Camera %s: Deleting stream %d", __FUNCTION__, mId.string(), id);
Igor Murashkine2172be2013-05-28 15:31:39 -07001619
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001620 // CameraDevice semantics require device to already be idle before
1621 // deleteStream is called, unlike for createStream.
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001622 if (mStatus == STATUS_ACTIVE) {
Yin-Chia Yeh693047d2018-03-08 12:14:19 -08001623 ALOGW("%s: Camera %s: Device not idle", __FUNCTION__, mId.string());
Igor Murashkin52827132013-05-13 14:53:44 -07001624 return -EBUSY;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001625 }
1626
Yin-Chia Yeh5090c732017-07-20 16:05:29 -07001627 if (mStatus == STATUS_ERROR) {
1628 ALOGW("%s: Camera %s: deleteStream not allowed in ERROR state",
1629 __FUNCTION__, mId.string());
1630 return -EBUSY;
1631 }
1632
Igor Murashkin2fba5842013-04-22 14:03:54 -07001633 sp<Camera3StreamInterface> deletedStream;
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001634 sp<Camera3StreamInterface> stream = mOutputStreams.get(id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001635 if (mInputStream != NULL && id == mInputStream->getId()) {
1636 deletedStream = mInputStream;
1637 mInputStream.clear();
1638 } else {
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001639 if (stream == nullptr) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001640 CLOGE("Stream %d does not exist", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001641 return BAD_VALUE;
1642 }
Shuzhen Wang316781a2020-08-18 18:11:01 -07001643 mSessionStatsBuilder.removeStream(id);
Zhijun He5f446352014-01-22 09:49:33 -08001644 }
1645
1646 // Delete output stream or the output part of a bi-directional stream.
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07001647 if (stream != nullptr) {
1648 deletedStream = stream;
1649 mOutputStreams.remove(id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001650 }
1651
1652 // Free up the stream endpoint so that it can be used by some other stream
1653 res = deletedStream->disconnect();
1654 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001655 SET_ERR_L("Can't disconnect deleted stream %d", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001656 // fall through since we want to still list the stream as deleted.
1657 }
1658 mDeletedStreams.add(deletedStream);
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001659 mNeedConfig = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001660
1661 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001662}
1663
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001664status_t Camera3Device::configureStreams(const CameraMetadata& sessionParams, int operatingMode) {
Igor Murashkine2d167e2014-08-19 16:19:59 -07001665 ATRACE_CALL();
1666 ALOGV("%s: E", __FUNCTION__);
1667
1668 Mutex::Autolock il(mInterfaceLock);
1669 Mutex::Autolock l(mLock);
Chien-Yu Chen17338fc2015-06-18 16:30:12 -07001670
Emilian Peev811d2952018-05-25 11:08:40 +01001671 // In case the client doesn't include any session parameter, try a
1672 // speculative configuration using the values from the last cached
1673 // default request.
1674 if (sessionParams.isEmpty() &&
Emilian Peevf4816702020-04-03 15:44:51 -07001675 ((mLastTemplateId > 0) && (mLastTemplateId < CAMERA_TEMPLATE_COUNT)) &&
Emilian Peev811d2952018-05-25 11:08:40 +01001676 (!mRequestTemplateCache[mLastTemplateId].isEmpty())) {
1677 ALOGV("%s: Speculative session param configuration with template id: %d", __func__,
1678 mLastTemplateId);
1679 return filterParamsAndConfigureLocked(mRequestTemplateCache[mLastTemplateId],
1680 operatingMode);
1681 }
1682
Emilian Peevac3ce6c2017-12-12 15:27:02 +00001683 return filterParamsAndConfigureLocked(sessionParams, operatingMode);
1684}
1685
1686status_t Camera3Device::filterParamsAndConfigureLocked(const CameraMetadata& sessionParams,
1687 int operatingMode) {
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001688 //Filter out any incoming session parameters
1689 const CameraMetadata params(sessionParams);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001690 camera_metadata_entry_t availableSessionKeys = mDeviceInfo.find(
1691 ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00001692 CameraMetadata filteredParams(availableSessionKeys.count);
1693 camera_metadata_t *meta = const_cast<camera_metadata_t *>(
1694 filteredParams.getAndLock());
1695 set_camera_metadata_vendor_id(meta, mVendorTagId);
1696 filteredParams.unlock(meta);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01001697 if (availableSessionKeys.count > 0) {
1698 for (size_t i = 0; i < availableSessionKeys.count; i++) {
1699 camera_metadata_ro_entry entry = params.find(
1700 availableSessionKeys.data.i32[i]);
1701 if (entry.count > 0) {
1702 filteredParams.update(entry);
1703 }
1704 }
1705 }
1706
1707 return configureStreamsLocked(operatingMode, filteredParams);
Igor Murashkine2d167e2014-08-19 16:19:59 -07001708}
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001709
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001710status_t Camera3Device::getInputBufferProducer(
1711 sp<IGraphicBufferProducer> *producer) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07001712 ATRACE_CALL();
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001713 Mutex::Autolock il(mInterfaceLock);
1714 Mutex::Autolock l(mLock);
1715
1716 if (producer == NULL) {
1717 return BAD_VALUE;
1718 } else if (mInputStream == NULL) {
1719 return INVALID_OPERATION;
1720 }
1721
1722 return mInputStream->getInputBufferProducer(producer);
1723}
1724
Emilian Peevf4816702020-04-03 15:44:51 -07001725status_t Camera3Device::createDefaultRequest(camera_request_template_t templateId,
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001726 CameraMetadata *request) {
1727 ATRACE_CALL();
Alex Rayfe7e0c62013-05-30 00:12:13 -07001728 ALOGV("%s: for template %d", __FUNCTION__, templateId);
Chien-Yu Chen9cd14022016-03-09 12:21:01 -08001729
Emilian Peevf4816702020-04-03 15:44:51 -07001730 if (templateId <= 0 || templateId >= CAMERA_TEMPLATE_COUNT) {
Chien-Yu Chen9cd14022016-03-09 12:21:01 -08001731 android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26866110",
Jayant Chowdhary12361932018-08-27 14:46:13 -07001732 CameraThreadState::getCallingUid(), nullptr, 0);
Chien-Yu Chen9cd14022016-03-09 12:21:01 -08001733 return BAD_VALUE;
1734 }
1735
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001736 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001737
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001738 {
1739 Mutex::Autolock l(mLock);
1740 switch (mStatus) {
1741 case STATUS_ERROR:
1742 CLOGE("Device has encountered a serious error");
1743 return INVALID_OPERATION;
1744 case STATUS_UNINITIALIZED:
1745 CLOGE("Device is not initialized!");
1746 return INVALID_OPERATION;
1747 case STATUS_UNCONFIGURED:
1748 case STATUS_CONFIGURED:
1749 case STATUS_ACTIVE:
1750 // OK
1751 break;
1752 default:
1753 SET_ERR_L("Unexpected status: %d", mStatus);
1754 return INVALID_OPERATION;
1755 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001756
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001757 if (!mRequestTemplateCache[templateId].isEmpty()) {
1758 *request = mRequestTemplateCache[templateId];
Emilian Peev811d2952018-05-25 11:08:40 +01001759 mLastTemplateId = templateId;
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001760 return OK;
1761 }
Zhijun Hea1530f12014-09-14 12:44:20 -07001762 }
1763
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08001764 camera_metadata_t *rawRequest;
1765 status_t res = mInterface->constructDefaultRequestSettings(
Emilian Peevf4816702020-04-03 15:44:51 -07001766 (camera_request_template_t) templateId, &rawRequest);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001767
1768 {
1769 Mutex::Autolock l(mLock);
1770 if (res == BAD_VALUE) {
1771 ALOGI("%s: template %d is not supported on this camera device",
1772 __FUNCTION__, templateId);
1773 return res;
1774 } else if (res != OK) {
1775 CLOGE("Unable to construct request template %d: %s (%d)",
1776 templateId, strerror(-res), res);
1777 return res;
1778 }
1779
1780 set_camera_metadata_vendor_id(rawRequest, mVendorTagId);
1781 mRequestTemplateCache[templateId].acquire(rawRequest);
1782
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08001783 // Override the template request with zoomRatioMapper
1784 res = mZoomRatioMappers[mId.c_str()].initZoomRatioInTemplate(
1785 &mRequestTemplateCache[templateId]);
1786 if (res != OK) {
1787 CLOGE("Failed to update zoom ratio for template %d: %s (%d)",
1788 templateId, strerror(-res), res);
1789 return res;
1790 }
1791
Shuzhen Wangd25dc972020-03-24 17:11:43 -07001792 // Fill in JPEG_QUALITY if not available
1793 if (!mRequestTemplateCache[templateId].exists(ANDROID_JPEG_QUALITY)) {
1794 static const uint8_t kDefaultJpegQuality = 95;
1795 mRequestTemplateCache[templateId].update(ANDROID_JPEG_QUALITY,
1796 &kDefaultJpegQuality, 1);
1797 }
1798
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001799 *request = mRequestTemplateCache[templateId];
Emilian Peev811d2952018-05-25 11:08:40 +01001800 mLastTemplateId = templateId;
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001801 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001802 return OK;
1803}
1804
1805status_t Camera3Device::waitUntilDrained() {
1806 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001807 Mutex::Autolock il(mInterfaceLock);
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001808 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001809 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001810
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001811 return waitUntilDrainedLocked(maxExpectedDuration);
Zhijun He69a37482014-03-23 18:44:49 -07001812}
1813
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001814status_t Camera3Device::waitUntilDrainedLocked(nsecs_t maxExpectedDuration) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001815 switch (mStatus) {
1816 case STATUS_UNINITIALIZED:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001817 case STATUS_UNCONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001818 ALOGV("%s: Already idle", __FUNCTION__);
1819 return OK;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001820 case STATUS_CONFIGURED:
1821 // To avoid race conditions, check with tracker to be sure
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001822 case STATUS_ERROR:
1823 case STATUS_ACTIVE:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001824 // Need to verify shut down
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001825 break;
1826 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001827 SET_ERR_L("Unexpected status: %d",mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001828 return INVALID_OPERATION;
1829 }
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07001830 ALOGV("%s: Camera %s: Waiting until idle (%" PRIi64 "ns)", __FUNCTION__, mId.string(),
1831 maxExpectedDuration);
1832 status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
Eino-Ville Talvala9c8a0912014-09-14 14:52:19 -07001833 if (res != OK) {
Yin-Chia Yeh87b3ec02019-06-03 10:44:39 -07001834 mStatusTracker->dumpActiveComponents();
Eino-Ville Talvala9c8a0912014-09-14 14:52:19 -07001835 SET_ERR_L("Error waiting for HAL to drain: %s (%d)", strerror(-res),
1836 res);
1837 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001838 return res;
1839}
1840
Ruben Brunk183f0562015-08-12 12:55:02 -07001841void Camera3Device::internalUpdateStatusLocked(Status status) {
1842 mStatus = status;
1843 mRecentStatusUpdates.add(mStatus);
1844 mStatusChanged.broadcast();
1845}
1846
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001847// Pause to reconfigure
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07001848status_t Camera3Device::internalPauseAndWaitLocked(nsecs_t maxExpectedDuration) {
Emilian Peeve86358b2019-02-15 13:51:39 -08001849 if (mRequestThread.get() != nullptr) {
1850 mRequestThread->setPaused(true);
1851 } else {
1852 return NO_INIT;
1853 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001854
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07001855 ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
1856 maxExpectedDuration);
1857 status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001858 if (res != OK) {
1859 SET_ERR_L("Can't idle device in %f seconds!",
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07001860 maxExpectedDuration/1e9);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001861 }
1862
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001863 return res;
1864}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001865
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001866// Resume after internalPauseAndWaitLocked
1867status_t Camera3Device::internalResumeLocked() {
1868 status_t res;
1869
1870 mRequestThread->setPaused(false);
1871
Eino-Ville Talvala002001b2018-01-23 16:53:50 -08001872 ALOGV("%s: Camera %s: Internal wait until active (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
1873 kActiveTimeout);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001874 res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
1875 if (res != OK) {
1876 SET_ERR_L("Can't transition to active in %f seconds!",
1877 kActiveTimeout/1e9);
1878 }
1879 mPauseStateNotify = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001880 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001881}
1882
Ruben Brunk183f0562015-08-12 12:55:02 -07001883status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001884 status_t res = OK;
Ruben Brunk183f0562015-08-12 12:55:02 -07001885
1886 size_t startIndex = 0;
1887 if (mStatusWaiters == 0) {
1888 // Clear the list of recent statuses if there are no existing threads waiting on updates to
1889 // this status list
1890 mRecentStatusUpdates.clear();
1891 } else {
1892 // If other threads are waiting on updates to this status list, set the position of the
1893 // first element that this list will check rather than clearing the list.
1894 startIndex = mRecentStatusUpdates.size();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001895 }
1896
Ruben Brunk183f0562015-08-12 12:55:02 -07001897 mStatusWaiters++;
1898
Yin-Chia Yehe52b8fa2020-07-28 00:17:58 -07001899 bool signalPipelineDrain = false;
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07001900 if (!active && mUseHalBufManager) {
1901 auto streamIds = mOutputStreams.getStreamIds();
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -08001902 if (mStatus == STATUS_ACTIVE) {
1903 mRequestThread->signalPipelineDrain(streamIds);
Yin-Chia Yehe52b8fa2020-07-28 00:17:58 -07001904 signalPipelineDrain = true;
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -08001905 }
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07001906 mRequestBufferSM.onWaitUntilIdle();
1907 }
1908
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001909 bool stateSeen = false;
1910 do {
Ruben Brunk183f0562015-08-12 12:55:02 -07001911 if (active == (mStatus == STATUS_ACTIVE)) {
1912 // Desired state is current
1913 break;
1914 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001915
1916 res = mStatusChanged.waitRelative(mLock, timeout);
1917 if (res != OK) break;
1918
Ruben Brunk183f0562015-08-12 12:55:02 -07001919 // This is impossible, but if not, could result in subtle deadlocks and invalid state
1920 // transitions.
1921 LOG_ALWAYS_FATAL_IF(startIndex > mRecentStatusUpdates.size(),
1922 "%s: Skipping status updates in Camera3Device, may result in deadlock.",
1923 __FUNCTION__);
1924
1925 // Encountered desired state since we began waiting
1926 for (size_t i = startIndex; i < mRecentStatusUpdates.size(); i++) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001927 if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
1928 stateSeen = true;
1929 break;
1930 }
1931 }
1932 } while (!stateSeen);
1933
Yin-Chia Yehe52b8fa2020-07-28 00:17:58 -07001934 if (signalPipelineDrain) {
1935 mRequestThread->resetPipelineDrain();
1936 }
1937
Ruben Brunk183f0562015-08-12 12:55:02 -07001938 mStatusWaiters--;
1939
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001940 return res;
1941}
1942
1943
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07001944status_t Camera3Device::setNotifyCallback(wp<NotificationListener> listener) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001945 ATRACE_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001946 std::lock_guard<std::mutex> l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001947
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001948 if (listener != NULL && mListener != NULL) {
1949 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
1950 }
1951 mListener = listener;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001952 mRequestThread->setNotificationListener(listener);
1953 mPreparerThread->setNotificationListener(listener);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001954
1955 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001956}
1957
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -07001958bool Camera3Device::willNotify3A() {
1959 return false;
1960}
1961
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001962status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07001963 ATRACE_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001964 std::unique_lock<std::mutex> l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001965
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001966 while (mResultQueue.empty()) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001967 auto st = mResultSignal.wait_for(l, std::chrono::nanoseconds(timeout));
1968 if (st == std::cv_status::timeout) {
1969 return TIMED_OUT;
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001970 }
1971 }
1972 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001973}
1974
Jianing Weicb0652e2014-03-12 18:29:36 -07001975status_t Camera3Device::getNextResult(CaptureResult *frame) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001976 ATRACE_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08001977 std::lock_guard<std::mutex> l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001978
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001979 if (mResultQueue.empty()) {
1980 return NOT_ENOUGH_DATA;
1981 }
1982
Jianing Weicb0652e2014-03-12 18:29:36 -07001983 if (frame == NULL) {
1984 ALOGE("%s: argument cannot be NULL", __FUNCTION__);
1985 return BAD_VALUE;
1986 }
1987
1988 CaptureResult &result = *(mResultQueue.begin());
1989 frame->mResultExtras = result.mResultExtras;
1990 frame->mMetadata.acquire(result.mMetadata);
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001991 frame->mPhysicalMetadatas = std::move(result.mPhysicalMetadatas);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001992 mResultQueue.erase(mResultQueue.begin());
1993
1994 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001995}
1996
1997status_t Camera3Device::triggerAutofocus(uint32_t id) {
1998 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001999 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002000
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002001 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
2002 // Mix-in this trigger into the next request and only the next request.
2003 RequestTrigger trigger[] = {
2004 {
2005 ANDROID_CONTROL_AF_TRIGGER,
2006 ANDROID_CONTROL_AF_TRIGGER_START
2007 },
2008 {
2009 ANDROID_CONTROL_AF_TRIGGER_ID,
2010 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07002011 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002012 };
2013
2014 return mRequestThread->queueTrigger(trigger,
2015 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002016}
2017
2018status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
2019 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002020 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002021
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002022 ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
2023 // Mix-in this trigger into the next request and only the next request.
2024 RequestTrigger trigger[] = {
2025 {
2026 ANDROID_CONTROL_AF_TRIGGER,
2027 ANDROID_CONTROL_AF_TRIGGER_CANCEL
2028 },
2029 {
2030 ANDROID_CONTROL_AF_TRIGGER_ID,
2031 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07002032 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002033 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002034
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002035 return mRequestThread->queueTrigger(trigger,
2036 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002037}
2038
2039status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
2040 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002041 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002042
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002043 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
2044 // Mix-in this trigger into the next request and only the next request.
2045 RequestTrigger trigger[] = {
2046 {
2047 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
2048 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
2049 },
2050 {
2051 ANDROID_CONTROL_AE_PRECAPTURE_ID,
2052 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07002053 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002054 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002055
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002056 return mRequestThread->queueTrigger(trigger,
2057 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002058}
2059
Jianing Weicb0652e2014-03-12 18:29:36 -07002060status_t Camera3Device::flush(int64_t *frameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002061 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002062 ALOGV("%s: Camera %s: Flushing all requests", __FUNCTION__, mId.string());
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002063 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002064
Zhijun He7ef20392014-04-21 16:04:17 -07002065 {
2066 Mutex::Autolock l(mLock);
Emilian Peeved2ebe42018-09-25 16:59:09 +01002067
2068 // b/116514106 "disconnect()" can get called twice for the same device. The
2069 // camera device will not be initialized during the second run.
2070 if (mStatus == STATUS_UNINITIALIZED) {
2071 return OK;
2072 }
2073
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07002074 mRequestThread->clear(/*out*/frameNumber);
Shuzhen Wang316781a2020-08-18 18:11:01 -07002075
2076 // Stop session and stream counter
2077 mSessionStatsBuilder.stopCounter();
Zhijun He7ef20392014-04-21 16:04:17 -07002078 }
2079
Emilian Peev08dd2452017-04-06 16:55:14 +01002080 return mRequestThread->flush();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002081}
2082
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002083status_t Camera3Device::prepare(int streamId) {
Ruben Brunkc78ac262015-08-13 17:58:46 -07002084 return prepare(camera3::Camera3StreamInterface::ALLOCATE_PIPELINE_MAX, streamId);
2085}
2086
2087status_t Camera3Device::prepare(int maxCount, int streamId) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002088 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002089 ALOGV("%s: Camera %s: Preparing stream %d", __FUNCTION__, mId.string(), streamId);
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07002090 Mutex::Autolock il(mInterfaceLock);
2091 Mutex::Autolock l(mLock);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002092
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002093 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2094 if (stream == nullptr) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002095 CLOGE("Stream %d does not exist", streamId);
2096 return BAD_VALUE;
2097 }
2098
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002099 if (stream->isUnpreparable() || stream->hasOutstandingBuffers() ) {
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07002100 CLOGE("Stream %d has already been a request target", streamId);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002101 return BAD_VALUE;
2102 }
2103
2104 if (mRequestThread->isStreamPending(stream)) {
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07002105 CLOGE("Stream %d is already a target in a pending request", streamId);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002106 return BAD_VALUE;
2107 }
2108
Ruben Brunkc78ac262015-08-13 17:58:46 -07002109 return mPreparerThread->prepare(maxCount, stream);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002110}
2111
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07002112status_t Camera3Device::tearDown(int streamId) {
2113 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002114 ALOGV("%s: Camera %s: Tearing down stream %d", __FUNCTION__, mId.string(), streamId);
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07002115 Mutex::Autolock il(mInterfaceLock);
2116 Mutex::Autolock l(mLock);
2117
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002118 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2119 if (stream == nullptr) {
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07002120 CLOGE("Stream %d does not exist", streamId);
2121 return BAD_VALUE;
2122 }
2123
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07002124 if (stream->hasOutstandingBuffers() || mRequestThread->isStreamPending(stream)) {
2125 CLOGE("Stream %d is a target of a in-progress request", streamId);
2126 return BAD_VALUE;
2127 }
2128
2129 return stream->tearDown();
2130}
2131
Shuzhen Wangb0fdc1e2016-03-20 23:21:39 -07002132status_t Camera3Device::addBufferListenerForStream(int streamId,
2133 wp<Camera3StreamBufferListener> listener) {
2134 ATRACE_CALL();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002135 ALOGV("%s: Camera %s: Adding buffer listener for stream %d", __FUNCTION__, mId.string(), streamId);
Shuzhen Wangb0fdc1e2016-03-20 23:21:39 -07002136 Mutex::Autolock il(mInterfaceLock);
2137 Mutex::Autolock l(mLock);
2138
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002139 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2140 if (stream == nullptr) {
Shuzhen Wangb0fdc1e2016-03-20 23:21:39 -07002141 CLOGE("Stream %d does not exist", streamId);
2142 return BAD_VALUE;
2143 }
Shuzhen Wangb0fdc1e2016-03-20 23:21:39 -07002144 stream->addBufferListener(listener);
2145
2146 return OK;
2147}
2148
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002149/**
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002150 * Methods called by subclasses
2151 */
2152
2153void Camera3Device::notifyStatus(bool idle) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07002154 ATRACE_CALL();
Shuzhen Wang316781a2020-08-18 18:11:01 -07002155 std::vector<int> streamIds;
2156 std::vector<hardware::CameraStreamStats> streamStats;
2157
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002158 {
2159 // Need mLock to safely update state and synchronize to current
2160 // state of methods in flight.
2161 Mutex::Autolock l(mLock);
2162 // We can get various system-idle notices from the status tracker
2163 // while starting up. Only care about them if we've actually sent
2164 // in some requests recently.
2165 if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
2166 return;
2167 }
Eino-Ville Talvala002001b2018-01-23 16:53:50 -08002168 ALOGV("%s: Camera %s: Now %s, pauseState: %s", __FUNCTION__, mId.string(),
2169 idle ? "idle" : "active", mPauseStateNotify ? "true" : "false");
Ruben Brunk183f0562015-08-12 12:55:02 -07002170 internalUpdateStatusLocked(idle ? STATUS_CONFIGURED : STATUS_ACTIVE);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002171
2172 // Skip notifying listener if we're doing some user-transparent
2173 // state changes
2174 if (mPauseStateNotify) return;
Shuzhen Wang316781a2020-08-18 18:11:01 -07002175
2176 // Populate stream statistics in case of Idle
2177 if (idle) {
2178 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2179 auto stream = mOutputStreams[i];
2180 if (stream.get() == nullptr) continue;
2181 streamIds.push_back(stream->getId());
2182 Camera3Stream* camera3Stream = Camera3Stream::cast(stream->asHalStream());
2183 int64_t usage = 0LL;
2184 if (camera3Stream != nullptr) {
2185 usage = camera3Stream->getUsage();
2186 }
2187 streamStats.emplace_back(stream->getWidth(), stream->getHeight(),
2188 stream->getFormat(), stream->getDataSpace(), usage,
2189 stream->getMaxHalBuffers(),
2190 stream->getMaxTotalBuffers() - stream->getMaxHalBuffers());
2191 }
2192 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002193 }
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07002194
2195 sp<NotificationListener> listener;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002196 {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08002197 std::lock_guard<std::mutex> l(mOutputLock);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07002198 listener = mListener.promote();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002199 }
Eino-Ville Talvala178e8232021-04-16 18:41:39 -07002200 status_t res = OK;
2201 if (listener != nullptr) {
2202 if (idle) {
2203 // Get session stats from the builder, and notify the listener.
2204 int64_t requestCount, resultErrorCount;
2205 bool deviceError;
2206 std::map<int, StreamStats> streamStatsMap;
2207 mSessionStatsBuilder.buildAndReset(&requestCount, &resultErrorCount,
2208 &deviceError, &streamStatsMap);
2209 for (size_t i = 0; i < streamIds.size(); i++) {
2210 int streamId = streamIds[i];
2211 auto stats = streamStatsMap.find(streamId);
2212 if (stats != streamStatsMap.end()) {
2213 streamStats[i].mRequestCount = stats->second.mRequestedFrameCount;
2214 streamStats[i].mErrorCount = stats->second.mDroppedFrameCount;
2215 streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs;
2216 streamStats[i].mHistogramType =
2217 hardware::CameraStreamStats::HISTOGRAM_TYPE_CAPTURE_LATENCY;
2218 streamStats[i].mHistogramBins.assign(
2219 stats->second.mCaptureLatencyBins.begin(),
2220 stats->second.mCaptureLatencyBins.end());
2221 streamStats[i].mHistogramCounts.assign(
2222 stats->second.mCaptureLatencyHistogram.begin(),
2223 stats->second.mCaptureLatencyHistogram.end());
2224 }
Shuzhen Wang316781a2020-08-18 18:11:01 -07002225 }
Eino-Ville Talvala178e8232021-04-16 18:41:39 -07002226 listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
2227 } else {
2228 res = listener->notifyActive();
Shuzhen Wang316781a2020-08-18 18:11:01 -07002229 }
Eino-Ville Talvala178e8232021-04-16 18:41:39 -07002230 }
2231 if (res != OK) {
2232 SET_ERR("Camera access permission lost mid-operation: %s (%d)",
2233 strerror(-res), res);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002234 }
2235}
2236
Shuzhen Wang758c2152017-01-10 18:26:18 -08002237status_t Camera3Device::setConsumerSurfaces(int streamId,
Emilian Peev40ead602017-09-26 15:46:36 +01002238 const std::vector<sp<Surface>>& consumers, std::vector<int> *surfaceIds) {
Zhijun He5d677d12016-05-29 16:52:39 -07002239 ATRACE_CALL();
Shuzhen Wang758c2152017-01-10 18:26:18 -08002240 ALOGV("%s: Camera %s: set consumer surface for stream %d",
2241 __FUNCTION__, mId.string(), streamId);
Emilian Peev40ead602017-09-26 15:46:36 +01002242
2243 if (surfaceIds == nullptr) {
2244 return BAD_VALUE;
2245 }
2246
Zhijun He5d677d12016-05-29 16:52:39 -07002247 Mutex::Autolock il(mInterfaceLock);
2248 Mutex::Autolock l(mLock);
2249
Shuzhen Wang758c2152017-01-10 18:26:18 -08002250 if (consumers.size() == 0) {
2251 CLOGE("No consumer is passed!");
Zhijun He5d677d12016-05-29 16:52:39 -07002252 return BAD_VALUE;
2253 }
2254
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002255 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2256 if (stream == nullptr) {
Zhijun He5d677d12016-05-29 16:52:39 -07002257 CLOGE("Stream %d is unknown", streamId);
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002258 return BAD_VALUE;
Zhijun He5d677d12016-05-29 16:52:39 -07002259 }
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002260
2261 // isConsumerConfigurationDeferred will be off after setConsumers
2262 bool isDeferred = stream->isConsumerConfigurationDeferred();
Shuzhen Wang758c2152017-01-10 18:26:18 -08002263 status_t res = stream->setConsumers(consumers);
Zhijun He5d677d12016-05-29 16:52:39 -07002264 if (res != OK) {
2265 CLOGE("Stream %d set consumer failed (error %d %s) ", streamId, res, strerror(-res));
2266 return res;
2267 }
2268
Emilian Peev40ead602017-09-26 15:46:36 +01002269 for (auto &consumer : consumers) {
2270 int id = stream->getSurfaceId(consumer);
2271 if (id < 0) {
2272 CLOGE("Invalid surface id!");
2273 return BAD_VALUE;
2274 }
2275 surfaceIds->push_back(id);
2276 }
2277
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002278 if (isDeferred) {
Shuzhen Wang0129d522016-10-30 22:43:41 -07002279 if (!stream->isConfiguring()) {
2280 CLOGE("Stream %d was already fully configured.", streamId);
2281 return INVALID_OPERATION;
2282 }
Zhijun He5d677d12016-05-29 16:52:39 -07002283
Shuzhen Wang0129d522016-10-30 22:43:41 -07002284 res = stream->finishConfiguration();
2285 if (res != OK) {
Shuzhen Wang210ba5c2018-07-25 16:47:40 -07002286 // If finishConfiguration fails due to abandoned surface, do not set
2287 // device to error state.
2288 bool isSurfaceAbandoned =
2289 (res == NO_INIT || res == DEAD_OBJECT) && stream->isAbandoned();
2290 if (!isSurfaceAbandoned) {
2291 SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
2292 stream->getId(), strerror(-res), res);
2293 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07002294 return res;
2295 }
Zhijun He5d677d12016-05-29 16:52:39 -07002296 }
2297
2298 return OK;
2299}
2300
Emilian Peev40ead602017-09-26 15:46:36 +01002301status_t Camera3Device::updateStream(int streamId, const std::vector<sp<Surface>> &newSurfaces,
2302 const std::vector<OutputStreamInfo> &outputInfo,
2303 const std::vector<size_t> &removedSurfaceIds, KeyedVector<sp<Surface>, size_t> *outputMap) {
2304 Mutex::Autolock il(mInterfaceLock);
2305 Mutex::Autolock l(mLock);
2306
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002307 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2308 if (stream == nullptr) {
Emilian Peev40ead602017-09-26 15:46:36 +01002309 CLOGE("Stream %d is unknown", streamId);
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002310 return BAD_VALUE;
Emilian Peev40ead602017-09-26 15:46:36 +01002311 }
2312
2313 for (const auto &it : removedSurfaceIds) {
2314 if (mRequestThread->isOutputSurfacePending(streamId, it)) {
2315 CLOGE("Shared surface still part of a pending request!");
2316 return -EBUSY;
2317 }
2318 }
2319
Emilian Peev40ead602017-09-26 15:46:36 +01002320 status_t res = stream->updateStream(newSurfaces, outputInfo, removedSurfaceIds, outputMap);
2321 if (res != OK) {
2322 CLOGE("Stream %d failed to update stream (error %d %s) ",
2323 streamId, res, strerror(-res));
2324 if (res == UNKNOWN_ERROR) {
2325 SET_ERR_L("%s: Stream update failed to revert to previous output configuration!",
2326 __FUNCTION__);
2327 }
2328 return res;
2329 }
2330
2331 return res;
2332}
2333
Chien-Yu Chena936ac22017-10-23 15:59:49 -07002334status_t Camera3Device::dropStreamBuffers(bool dropping, int streamId) {
2335 Mutex::Autolock il(mInterfaceLock);
2336 Mutex::Autolock l(mLock);
2337
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002338 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2339 if (stream == nullptr) {
Chien-Yu Chena936ac22017-10-23 15:59:49 -07002340 ALOGE("%s: Stream %d is not found.", __FUNCTION__, streamId);
2341 return BAD_VALUE;
2342 }
Shuzhen Wang316781a2020-08-18 18:11:01 -07002343
2344 if (dropping) {
2345 mSessionStatsBuilder.stopCounter(streamId);
2346 } else {
2347 mSessionStatsBuilder.startCounter(streamId);
2348 }
Chien-Yu Chena936ac22017-10-23 15:59:49 -07002349 return stream->dropBuffers(dropping);
2350}
2351
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002352/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002353 * Camera3Device private methods
2354 */
2355
2356sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
Emilian Peevaebbe412018-01-15 13:53:24 +00002357 const PhysicalCameraSettingsList &request, const SurfaceMap &surfaceMap) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002358 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002359
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08002360 sp<CaptureRequest> newRequest = new CaptureRequest();
Emilian Peevaebbe412018-01-15 13:53:24 +00002361 newRequest->mSettingsList = request;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002362
2363 camera_metadata_entry_t inputStreams =
Emilian Peevaebbe412018-01-15 13:53:24 +00002364 newRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_INPUT_STREAMS);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002365 if (inputStreams.count > 0) {
2366 if (mInputStream == NULL ||
Zhijun Hed1d64672013-09-06 15:00:01 -07002367 mInputStream->getId() != inputStreams.data.i32[0]) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002368 CLOGE("Request references unknown input stream %d",
2369 inputStreams.data.u8[0]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002370 return NULL;
2371 }
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002372
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002373 if (mInputStream->isConfiguring()) {
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002374 SET_ERR_L("%s: input stream %d is not configured!",
2375 __FUNCTION__, mInputStream->getId());
2376 return NULL;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002377 }
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -07002378 // Check if stream prepare is blocking requests.
2379 if (mInputStream->isBlockedByPrepare()) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002380 CLOGE("Request references an input stream that's being prepared!");
2381 return NULL;
2382 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002383
2384 newRequest->mInputStream = mInputStream;
Emilian Peevaebbe412018-01-15 13:53:24 +00002385 newRequest->mSettingsList.begin()->metadata.erase(ANDROID_REQUEST_INPUT_STREAMS);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002386 }
2387
2388 camera_metadata_entry_t streams =
Emilian Peevaebbe412018-01-15 13:53:24 +00002389 newRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_OUTPUT_STREAMS);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002390 if (streams.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002391 CLOGE("Zero output streams specified!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002392 return NULL;
2393 }
2394
2395 for (size_t i = 0; i < streams.count; i++) {
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002396 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streams.data.i32[i]);
2397 if (stream == nullptr) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002398 CLOGE("Request references unknown stream %d",
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002399 streams.data.i32[i]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002400 return NULL;
2401 }
Zhijun He5d677d12016-05-29 16:52:39 -07002402 // It is illegal to include a deferred consumer output stream into a request
Shuzhen Wang0129d522016-10-30 22:43:41 -07002403 auto iter = surfaceMap.find(streams.data.i32[i]);
2404 if (iter != surfaceMap.end()) {
2405 const std::vector<size_t>& surfaces = iter->second;
2406 for (const auto& surface : surfaces) {
2407 if (stream->isConsumerConfigurationDeferred(surface)) {
2408 CLOGE("Stream %d surface %zu hasn't finished configuration yet "
2409 "due to deferred consumer", stream->getId(), surface);
2410 return NULL;
2411 }
2412 }
Yin-Chia Yeh0b287572018-10-15 12:38:13 -07002413 newRequest->mOutputSurfaces[streams.data.i32[i]] = surfaces;
Zhijun He5d677d12016-05-29 16:52:39 -07002414 }
2415
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002416 if (stream->isConfiguring()) {
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002417 SET_ERR_L("%s: stream %d is not configured!", __FUNCTION__, stream->getId());
2418 return NULL;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002419 }
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -07002420 // Check if stream prepare is blocking requests.
2421 if (stream->isBlockedByPrepare()) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002422 CLOGE("Request references an output stream that's being prepared!");
2423 return NULL;
2424 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002425
2426 newRequest->mOutputStreams.push(stream);
2427 }
Emilian Peevaebbe412018-01-15 13:53:24 +00002428 newRequest->mSettingsList.begin()->metadata.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002429 newRequest->mBatchSize = 1;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002430
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08002431 auto rotateAndCropEntry =
2432 newRequest->mSettingsList.begin()->metadata.find(ANDROID_SCALER_ROTATE_AND_CROP);
2433 if (rotateAndCropEntry.count > 0 &&
2434 rotateAndCropEntry.data.u8[0] == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
2435 newRequest->mRotateAndCropAuto = true;
2436 } else {
2437 newRequest->mRotateAndCropAuto = false;
2438 }
2439
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07002440 auto zoomRatioEntry =
2441 newRequest->mSettingsList.begin()->metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
2442 if (zoomRatioEntry.count > 0 &&
2443 zoomRatioEntry.data.f[0] == 1.0f) {
2444 newRequest->mZoomRatioIs1x = true;
2445 } else {
2446 newRequest->mZoomRatioIs1x = false;
2447 }
2448
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08002449 if (mSupportCameraMute) {
2450 auto testPatternModeEntry =
2451 newRequest->mSettingsList.begin()->metadata.find(ANDROID_SENSOR_TEST_PATTERN_MODE);
2452 newRequest->mOriginalTestPatternMode = testPatternModeEntry.count > 0 ?
2453 testPatternModeEntry.data.i32[0] :
2454 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
2455
2456 auto testPatternDataEntry =
2457 newRequest->mSettingsList.begin()->metadata.find(ANDROID_SENSOR_TEST_PATTERN_DATA);
2458 if (testPatternDataEntry.count > 0) {
2459 memcpy(newRequest->mOriginalTestPatternData, testPatternModeEntry.data.i32,
2460 sizeof(newRequest->mOriginalTestPatternData));
2461 } else {
2462 newRequest->mOriginalTestPatternData[0] = 0;
2463 newRequest->mOriginalTestPatternData[1] = 0;
2464 newRequest->mOriginalTestPatternData[2] = 0;
2465 newRequest->mOriginalTestPatternData[3] = 0;
2466 }
2467 }
2468
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002469 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002470}
2471
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002472void Camera3Device::cancelStreamsConfigurationLocked() {
2473 int res = OK;
2474 if (mInputStream != NULL && mInputStream->isConfiguring()) {
2475 res = mInputStream->cancelConfiguration();
2476 if (res != OK) {
2477 CLOGE("Can't cancel configuring input stream %d: %s (%d)",
2478 mInputStream->getId(), strerror(-res), res);
2479 }
2480 }
2481
2482 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002483 sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002484 if (outputStream->isConfiguring()) {
2485 res = outputStream->cancelConfiguration();
2486 if (res != OK) {
2487 CLOGE("Can't cancel configuring output stream %d: %s (%d)",
2488 outputStream->getId(), strerror(-res), res);
2489 }
2490 }
2491 }
2492
2493 // Return state to that at start of call, so that future configures
2494 // properly clean things up
2495 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
2496 mNeedConfig = true;
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002497
2498 res = mPreparerThread->resume();
2499 if (res != OK) {
2500 ALOGE("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
2501 }
2502}
2503
Emilian Peev0d0191e2020-04-21 17:01:18 -07002504bool Camera3Device::checkAbandonedStreamsLocked() {
2505 if ((mInputStream.get() != nullptr) && (mInputStream->isAbandoned())) {
2506 return true;
2507 }
2508
2509 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2510 auto stream = mOutputStreams[i];
2511 if ((stream.get() != nullptr) && (stream->isAbandoned())) {
2512 return true;
2513 }
2514 }
2515
2516 return false;
2517}
2518
Emilian Peev3bead5f2020-05-28 17:29:08 -07002519bool Camera3Device::reconfigureCamera(const CameraMetadata& sessionParams, int clientStatusId) {
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002520 ATRACE_CALL();
2521 bool ret = false;
2522
Shuzhen Wang316781a2020-08-18 18:11:01 -07002523 nsecs_t startTime = systemTime();
2524
Jayant Chowdhary646c31b2020-01-30 13:09:59 -08002525 Mutex::Autolock il(mInterfaceLock);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002526 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
2527
2528 Mutex::Autolock l(mLock);
Emilian Peev0d0191e2020-04-21 17:01:18 -07002529 if (checkAbandonedStreamsLocked()) {
2530 ALOGW("%s: Abandoned stream detected, session parameters can't be applied correctly!",
2531 __FUNCTION__);
2532 return true;
2533 }
2534
Emilian Peev3bead5f2020-05-28 17:29:08 -07002535 status_t rc = NO_ERROR;
2536 bool markClientActive = false;
2537 if (mStatus == STATUS_ACTIVE) {
2538 markClientActive = true;
2539 mPauseStateNotify = true;
2540 mStatusTracker->markComponentIdle(clientStatusId, Fence::NO_FENCE);
2541
2542 rc = internalPauseAndWaitLocked(maxExpectedDuration);
2543 }
2544
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002545 if (rc == NO_ERROR) {
2546 mNeedConfig = true;
2547 rc = configureStreamsLocked(mOperatingMode, sessionParams, /*notifyRequestThread*/ false);
2548 if (rc == NO_ERROR) {
2549 ret = true;
2550 mPauseStateNotify = false;
2551 //Moving to active state while holding 'mLock' is important.
2552 //There could be pending calls to 'create-/deleteStream' which
2553 //will trigger another stream configuration while the already
2554 //present streams end up with outstanding buffers that will
2555 //not get drained.
2556 internalUpdateStatusLocked(STATUS_ACTIVE);
Shuzhen Wang210ba5c2018-07-25 16:47:40 -07002557 } else if (rc == DEAD_OBJECT) {
2558 // DEAD_OBJECT can be returned if either the consumer surface is
2559 // abandoned, or the HAL has died.
2560 // - If the HAL has died, configureStreamsLocked call will set
2561 // device to error state,
2562 // - If surface is abandoned, we should not set device to error
2563 // state.
2564 ALOGE("Failed to re-configure camera due to abandoned surface");
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002565 } else {
Shuzhen Wang210ba5c2018-07-25 16:47:40 -07002566 SET_ERR_L("Failed to re-configure camera: %d", rc);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002567 }
2568 } else {
2569 ALOGE("%s: Failed to pause streaming: %d", __FUNCTION__, rc);
2570 }
2571
Shuzhen Wang316781a2020-08-18 18:11:01 -07002572 CameraServiceProxyWrapper::logStreamConfigured(mId, mOperatingMode, true /*internalReconfig*/,
2573 ns2ms(systemTime() - startTime));
2574
Emilian Peev3bead5f2020-05-28 17:29:08 -07002575 if (markClientActive) {
2576 mStatusTracker->markComponentActive(clientStatusId);
2577 }
2578
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002579 return ret;
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002580}
2581
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01002582status_t Camera3Device::configureStreamsLocked(int operatingMode,
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002583 const CameraMetadata& sessionParams, bool notifyRequestThread) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002584 ATRACE_CALL();
2585 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002586
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002587 if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002588 CLOGE("Not idle");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002589 return INVALID_OPERATION;
2590 }
2591
Eino-Ville Talvalae7091aa2017-03-07 15:23:06 -08002592 if (operatingMode < 0) {
2593 CLOGE("Invalid operating mode: %d", operatingMode);
2594 return BAD_VALUE;
2595 }
2596
2597 bool isConstrainedHighSpeed =
2598 static_cast<int>(StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ==
2599 operatingMode;
2600
2601 if (mOperatingMode != operatingMode) {
2602 mNeedConfig = true;
2603 mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
2604 mOperatingMode = operatingMode;
2605 }
2606
Shuzhen Wang0cf01cb2019-09-05 13:33:06 -07002607 // In case called from configureStreams, abort queued input buffers not belonging to
2608 // any pending requests.
2609 if (mInputStream != NULL && notifyRequestThread) {
2610 while (true) {
Emilian Peevf4816702020-04-03 15:44:51 -07002611 camera_stream_buffer_t inputBuffer;
Shuzhen Wang83bff122020-11-20 15:51:39 -08002612 camera3::Size inputBufferSize;
Shuzhen Wang0cf01cb2019-09-05 13:33:06 -07002613 status_t res = mInputStream->getInputBuffer(&inputBuffer,
Shuzhen Wang83bff122020-11-20 15:51:39 -08002614 &inputBufferSize, /*respectHalLimit*/ false);
Shuzhen Wang0cf01cb2019-09-05 13:33:06 -07002615 if (res != OK) {
2616 // Exhausted acquiring all input buffers.
2617 break;
2618 }
2619
Emilian Peevf4816702020-04-03 15:44:51 -07002620 inputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
Shuzhen Wang0cf01cb2019-09-05 13:33:06 -07002621 res = mInputStream->returnInputBuffer(inputBuffer);
2622 if (res != OK) {
2623 ALOGE("%s: %d: couldn't return input buffer while clearing input queue: "
2624 "%s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
2625 }
2626 }
2627 }
2628
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07002629 if (!mNeedConfig) {
2630 ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
2631 return OK;
2632 }
2633
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002634 // Workaround for device HALv3.2 or older spec bug - zero streams requires
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002635 // adding a fake stream instead.
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002636 // TODO: Bug: 17321404 for fixing the HAL spec and removing this workaround.
2637 if (mOutputStreams.size() == 0) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002638 addFakeStreamLocked();
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002639 } else {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002640 tryRemoveFakeStreamLocked();
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002641 }
2642
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002643 // Start configuring the streams
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002644 ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.string());
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002645
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002646 mPreparerThread->pause();
2647
Emilian Peevf4816702020-04-03 15:44:51 -07002648 camera_stream_configuration config;
Eino-Ville Talvalabbbbe842017-02-28 17:50:56 -08002649 config.operation_mode = mOperatingMode;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002650 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
Shuzhen Wang83bff122020-11-20 15:51:39 -08002651 config.input_is_multi_resolution = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002652
Emilian Peevf4816702020-04-03 15:44:51 -07002653 Vector<camera3::camera_stream_t*> streams;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002654 streams.setCapacity(config.num_streams);
Emilian Peev192ee832018-01-31 14:46:47 +00002655 std::vector<uint32_t> bufferSizes(config.num_streams, 0);
Yin-Chia Yehfb6e55b2018-01-25 10:50:26 -08002656
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002657
2658 if (mInputStream != NULL) {
Emilian Peevf4816702020-04-03 15:44:51 -07002659 camera3::camera_stream_t *inputStream;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002660 inputStream = mInputStream->startConfiguration();
2661 if (inputStream == NULL) {
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002662 CLOGE("Can't start input stream configuration");
2663 cancelStreamsConfigurationLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002664 return INVALID_OPERATION;
2665 }
2666 streams.add(inputStream);
Shuzhen Wang83bff122020-11-20 15:51:39 -08002667
2668 config.input_is_multi_resolution = mIsInputStreamMultiResolution;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002669 }
2670
Shuzhen Wang99080502021-03-07 21:08:20 -08002671 mGroupIdPhysicalCameraMap.clear();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002672 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Igor Murashkin2fba5842013-04-22 14:03:54 -07002673
2674 // Don't configure bidi streams twice, nor add them twice to the list
2675 if (mOutputStreams[i].get() ==
2676 static_cast<Camera3StreamInterface*>(mInputStream.get())) {
2677
2678 config.num_streams--;
2679 continue;
2680 }
2681
Emilian Peevf4816702020-04-03 15:44:51 -07002682 camera3::camera_stream_t *outputStream;
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002683 outputStream = mOutputStreams[i]->startConfiguration();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002684 if (outputStream == NULL) {
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002685 CLOGE("Can't start output stream configuration");
2686 cancelStreamsConfigurationLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002687 return INVALID_OPERATION;
2688 }
2689 streams.add(outputStream);
Yin-Chia Yehfb6e55b2018-01-25 10:50:26 -08002690
Shuzhen Wangb7ab1e42019-02-20 15:42:23 -08002691 if (outputStream->format == HAL_PIXEL_FORMAT_BLOB) {
Emilian Peev192ee832018-01-31 14:46:47 +00002692 size_t k = i + ((mInputStream != nullptr) ? 1 : 0); // Input stream if present should
2693 // always occupy the initial entry.
Shuzhen Wangb7ab1e42019-02-20 15:42:23 -08002694 if (outputStream->data_space == HAL_DATASPACE_V0_JFIF) {
2695 bufferSizes[k] = static_cast<uint32_t>(
2696 getJpegBufferSize(outputStream->width, outputStream->height));
2697 } else if (outputStream->data_space ==
2698 static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
2699 bufferSizes[k] = outputStream->width * outputStream->height;
2700 } else {
2701 ALOGW("%s: Blob dataSpace %d not supported",
2702 __FUNCTION__, outputStream->data_space);
2703 }
Yin-Chia Yehfb6e55b2018-01-25 10:50:26 -08002704 }
Shuzhen Wang99080502021-03-07 21:08:20 -08002705
2706 if (mOutputStreams[i]->isMultiResolution()) {
2707 int32_t streamGroupId = mOutputStreams[i]->getHalStreamGroupId();
2708 const String8& physicalCameraId = mOutputStreams[i]->getPhysicalCameraId();
2709 mGroupIdPhysicalCameraMap[streamGroupId].insert(physicalCameraId);
2710 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002711 }
2712
2713 config.streams = streams.editArray();
2714
2715 // Do the HAL configuration; will potentially touch stream
Shuzhen Wang92653952019-05-07 15:11:43 -07002716 // max_buffers, usage, and priv fields, as well as data_space and format
2717 // fields for IMPLEMENTATION_DEFINED formats.
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002718
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01002719 const camera_metadata_t *sessionBuffer = sessionParams.getAndLock();
Emilian Peev192ee832018-01-31 14:46:47 +00002720 res = mInterface->configureStreams(sessionBuffer, &config, bufferSizes);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01002721 sessionParams.unlock(sessionBuffer);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002722
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002723 if (res == BAD_VALUE) {
2724 // HAL rejected this set of streams as unsupported, clean up config
2725 // attempt and return to unconfigured state
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002726 CLOGE("Set of requested inputs/outputs not supported by HAL");
2727 cancelStreamsConfigurationLocked();
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002728 return BAD_VALUE;
2729 } else if (res != OK) {
2730 // Some other kind of error from configure_streams - this is not
2731 // expected
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002732 SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
2733 strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002734 return res;
2735 }
2736
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002737 // Finish all stream configuration immediately.
2738 // TODO: Try to relax this later back to lazy completion, which should be
2739 // faster
2740
Igor Murashkin073f8572013-05-02 14:59:28 -07002741 if (mInputStream != NULL && mInputStream->isConfiguring()) {
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002742 bool streamReConfigured = false;
2743 res = mInputStream->finishConfiguration(&streamReConfigured);
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002744 if (res != OK) {
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002745 CLOGE("Can't finish configuring input stream %d: %s (%d)",
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002746 mInputStream->getId(), strerror(-res), res);
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002747 cancelStreamsConfigurationLocked();
Shuzhen Wang210ba5c2018-07-25 16:47:40 -07002748 if ((res == NO_INIT || res == DEAD_OBJECT) && mInputStream->isAbandoned()) {
2749 return DEAD_OBJECT;
2750 }
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002751 return BAD_VALUE;
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002752 }
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002753 if (streamReConfigured) {
2754 mInterface->onStreamReConfigured(mInputStream->getId());
2755 }
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002756 }
2757
2758 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002759 sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
Zhijun He5d677d12016-05-29 16:52:39 -07002760 if (outputStream->isConfiguring() && !outputStream->isConsumerConfigurationDeferred()) {
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002761 bool streamReConfigured = false;
2762 res = outputStream->finishConfiguration(&streamReConfigured);
Igor Murashkin073f8572013-05-02 14:59:28 -07002763 if (res != OK) {
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002764 CLOGE("Can't finish configuring output stream %d: %s (%d)",
Igor Murashkin073f8572013-05-02 14:59:28 -07002765 outputStream->getId(), strerror(-res), res);
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002766 cancelStreamsConfigurationLocked();
Shuzhen Wang210ba5c2018-07-25 16:47:40 -07002767 if ((res == NO_INIT || res == DEAD_OBJECT) && outputStream->isAbandoned()) {
2768 return DEAD_OBJECT;
2769 }
Chien-Yu Chen9b5860b2016-06-10 13:39:09 -07002770 return BAD_VALUE;
Igor Murashkin073f8572013-05-02 14:59:28 -07002771 }
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07002772 if (streamReConfigured) {
2773 mInterface->onStreamReConfigured(outputStream->getId());
2774 }
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07002775 }
2776 }
2777
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002778 // Request thread needs to know to avoid using repeat-last-settings protocol
2779 // across configure_streams() calls
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002780 if (notifyRequestThread) {
Shuzhen Wang99080502021-03-07 21:08:20 -08002781 mRequestThread->configurationComplete(mIsConstrainedHighSpeedConfiguration,
2782 sessionParams, mGroupIdPhysicalCameraMap);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002783 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002784
Zhijun He90f7c372016-08-16 16:19:43 -07002785 char value[PROPERTY_VALUE_MAX];
2786 property_get("camera.fifo.disable", value, "0");
2787 int32_t disableFifo = atoi(value);
2788 if (disableFifo != 1) {
2789 // Boost priority of request thread to SCHED_FIFO.
2790 pid_t requestThreadTid = mRequestThread->getTid();
2791 res = requestPriority(getpid(), requestThreadTid,
Mikhail Naganov83f04272017-02-07 10:45:09 -08002792 kRequestThreadPriority, /*isForApp*/ false, /*asynchronous*/ false);
Zhijun He90f7c372016-08-16 16:19:43 -07002793 if (res != OK) {
2794 ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
2795 strerror(-res), res);
2796 } else {
2797 ALOGD("Set real time priority for request queue thread (tid %d)", requestThreadTid);
2798 }
Eino-Ville Talvalaf99498e2015-09-25 16:52:55 -07002799 }
2800
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002801 // Update device state
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01002802 const camera_metadata_t *newSessionParams = sessionParams.getAndLock();
2803 const camera_metadata_t *currentSessionParams = mSessionParams.getAndLock();
2804 bool updateSessionParams = (newSessionParams != currentSessionParams) ? true : false;
2805 sessionParams.unlock(newSessionParams);
2806 mSessionParams.unlock(currentSessionParams);
2807 if (updateSessionParams) {
2808 mSessionParams = sessionParams;
2809 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002810
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07002811 mNeedConfig = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002812
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002813 internalUpdateStatusLocked((mFakeStreamId == NO_STREAM) ?
Ruben Brunk183f0562015-08-12 12:55:02 -07002814 STATUS_CONFIGURED : STATUS_UNCONFIGURED);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002815
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002816 ALOGV("%s: Camera %s: Stream configuration complete", __FUNCTION__, mId.string());
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002817
Zhijun He0a210512014-07-24 13:45:15 -07002818 // tear down the deleted streams after configure streams.
2819 mDeletedStreams.clear();
2820
Emilian Peevac3ce6c2017-12-12 15:27:02 +00002821 auto rc = mPreparerThread->resume();
2822 if (rc != OK) {
2823 SET_ERR_L("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
2824 return rc;
2825 }
2826
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002827 if (mFakeStreamId == NO_STREAM) {
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07002828 mRequestBufferSM.onStreamsConfigured();
2829 }
2830
Cliff Wuc2ad9c82021-04-21 00:58:58 +08002831 // Since the streams configuration of the injection camera is based on the internal camera, we
2832 // must wait until the internal camera configure streams before calling injectCamera() to
2833 // configure the injection streams.
2834 if (mInjectionMethods->isInjecting()) {
2835 ALOGV("%s: Injection camera %s: Start to configure streams.",
2836 __FUNCTION__, mInjectionMethods->getInjectedCamId().string());
2837 res = mInjectionMethods->injectCamera(config, bufferSizes);
2838 if (res != OK) {
2839 ALOGE("Can't finish inject camera process!");
2840 return res;
2841 }
2842 }
2843
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002844 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002845}
2846
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002847status_t Camera3Device::addFakeStreamLocked() {
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002848 ATRACE_CALL();
2849 status_t res;
2850
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002851 if (mFakeStreamId != NO_STREAM) {
2852 // Should never be adding a second fake stream when one is already
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002853 // active
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002854 SET_ERR_L("%s: Camera %s: A fake stream already exists!",
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002855 __FUNCTION__, mId.string());
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002856 return INVALID_OPERATION;
2857 }
2858
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002859 ALOGV("%s: Camera %s: Adding a fake stream", __FUNCTION__, mId.string());
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002860
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002861 sp<Camera3OutputStreamInterface> fakeStream =
2862 new Camera3FakeStream(mNextStreamId);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002863
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002864 res = mOutputStreams.add(mNextStreamId, fakeStream);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002865 if (res < 0) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002866 SET_ERR_L("Can't add fake stream to set: %s (%d)", strerror(-res), res);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002867 return res;
2868 }
2869
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002870 mFakeStreamId = mNextStreamId;
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002871 mNextStreamId++;
2872
2873 return OK;
2874}
2875
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002876status_t Camera3Device::tryRemoveFakeStreamLocked() {
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002877 ATRACE_CALL();
2878 status_t res;
2879
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002880 if (mFakeStreamId == NO_STREAM) return OK;
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002881 if (mOutputStreams.size() == 1) return OK;
2882
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002883 ALOGV("%s: Camera %s: Removing the fake stream", __FUNCTION__, mId.string());
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002884
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002885 // Ok, have a fake stream and there's at least one other output stream,
2886 // so remove the fake
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002887
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002888 sp<Camera3StreamInterface> deletedStream = mOutputStreams.get(mFakeStreamId);
Yin-Chia Yeh4ee35432018-10-10 13:52:31 -07002889 if (deletedStream == nullptr) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002890 SET_ERR_L("Fake stream %d does not appear to exist", mFakeStreamId);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002891 return INVALID_OPERATION;
2892 }
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002893 mOutputStreams.remove(mFakeStreamId);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002894
2895 // Free up the stream endpoint so that it can be used by some other stream
2896 res = deletedStream->disconnect();
2897 if (res != OK) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002898 SET_ERR_L("Can't disconnect deleted fake stream %d", mFakeStreamId);
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002899 // fall through since we want to still list the stream as deleted.
2900 }
2901 mDeletedStreams.add(deletedStream);
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04002902 mFakeStreamId = NO_STREAM;
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07002903
2904 return res;
2905}
2906
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002907void Camera3Device::setErrorState(const char *fmt, ...) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07002908 ATRACE_CALL();
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002909 Mutex::Autolock l(mLock);
2910 va_list args;
2911 va_start(args, fmt);
2912
2913 setErrorStateLockedV(fmt, args);
2914
2915 va_end(args);
2916}
2917
2918void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07002919 ATRACE_CALL();
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002920 Mutex::Autolock l(mLock);
2921 setErrorStateLockedV(fmt, args);
2922}
2923
2924void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
2925 va_list args;
2926 va_start(args, fmt);
2927
2928 setErrorStateLockedV(fmt, args);
2929
2930 va_end(args);
2931}
2932
2933void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002934 // Print out all error messages to log
2935 String8 errorCause = String8::formatV(fmt, args);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08002936 ALOGE("Camera %s: %s", mId.string(), errorCause.string());
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002937
2938 // But only do error state transition steps for the first error
Zhijun Heb05eeae2013-06-06 13:51:22 -07002939 if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002940
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002941 mErrorCause = errorCause;
2942
Yin-Chia Yeh3d145ae2017-07-27 12:47:03 -07002943 if (mRequestThread != nullptr) {
2944 mRequestThread->setPaused(true);
2945 }
Ruben Brunk183f0562015-08-12 12:55:02 -07002946 internalUpdateStatusLocked(STATUS_ERROR);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002947
2948 // Notify upstream about a device error
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07002949 sp<NotificationListener> listener = mListener.promote();
2950 if (listener != NULL) {
2951 listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002952 CaptureResultExtras());
Shuzhen Wang316781a2020-08-18 18:11:01 -07002953 mSessionStatsBuilder.onDeviceError();
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002954 }
2955
2956 // Save stack trace. View by dumping it later.
2957 CameraTraces::saveTrace();
2958 // TODO: consider adding errorCause and client pid/procname
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002959}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002960
2961/**
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002962 * In-flight request management
2963 */
2964
Jianing Weicb0652e2014-03-12 18:29:36 -07002965status_t Camera3Device::registerInFlight(uint32_t frameNumber,
Chien-Yu Chend196d612015-06-22 19:49:01 -07002966 int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
Shuzhen Wang5c22c152017-12-31 17:12:25 -08002967 bool hasAppCallback, nsecs_t maxExpectedDuration,
Shuzhen Wang99080502021-03-07 21:08:20 -08002968 const std::set<std::set<String8>>& physicalCameraIds,
2969 bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto,
2970 const std::set<std::string>& cameraIdsWithZoom,
Shuzhen Wang316781a2020-08-18 18:11:01 -07002971 const SurfaceMap& outputSurfaces, nsecs_t requestTimeNs) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002972 ATRACE_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08002973 std::lock_guard<std::mutex> l(mInFlightLock);
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002974
2975 ssize_t res;
Chien-Yu Chend196d612015-06-22 19:49:01 -07002976 res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07002977 hasAppCallback, maxExpectedDuration, physicalCameraIds, isStillCapture, isZslCapture,
Shuzhen Wang316781a2020-08-18 18:11:01 -07002978 rotateAndCropAuto, cameraIdsWithZoom, requestTimeNs, outputSurfaces));
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002979 if (res < 0) return res;
2980
Eino-Ville Talvala24b366e2016-07-21 12:53:07 -07002981 if (mInFlightMap.size() == 1) {
Emilian Peev26d975d2018-07-05 14:52:57 +01002982 // Hold a separate dedicated tracker lock to prevent race with disconnect and also
2983 // avoid a deadlock during reprocess requests.
2984 Mutex::Autolock l(mTrackerLock);
Yin-Chia Yeh38dfde52017-06-27 17:13:33 -07002985 if (mStatusTracker != nullptr) {
2986 mStatusTracker->markComponentActive(mInFlightStatusId);
2987 }
Eino-Ville Talvala24b366e2016-07-21 12:53:07 -07002988 }
2989
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07002990 mExpectedInflightDuration += maxExpectedDuration;
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002991 return OK;
2992}
2993
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08002994void Camera3Device::onInflightEntryRemovedLocked(nsecs_t duration) {
Shuzhen Wangcadb3302016-11-04 14:17:56 -07002995 // Indicate idle inFlightMap to the status tracker
2996 if (mInFlightMap.size() == 0) {
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07002997 mRequestBufferSM.onInflightMapEmpty();
Emilian Peev26d975d2018-07-05 14:52:57 +01002998 // Hold a separate dedicated tracker lock to prevent race with disconnect and also
2999 // avoid a deadlock during reprocess requests.
3000 Mutex::Autolock l(mTrackerLock);
Yin-Chia Yeh38dfde52017-06-27 17:13:33 -07003001 if (mStatusTracker != nullptr) {
3002 mStatusTracker->markComponentIdle(mInFlightStatusId, Fence::NO_FENCE);
3003 }
Shuzhen Wangcadb3302016-11-04 14:17:56 -07003004 }
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07003005 mExpectedInflightDuration -= duration;
Shuzhen Wangcadb3302016-11-04 14:17:56 -07003006}
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08003007
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003008void Camera3Device::checkInflightMapLengthLocked() {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04003009 // Validation check - if we have too many in-flight frames with long total inflight duration,
Yin-Chia Yeh99fd0972019-06-27 14:22:44 -07003010 // something has likely gone wrong. This might still be legit only if application send in
3011 // a long burst of long exposure requests.
3012 if (mExpectedInflightDuration > kMinWarnInflightDuration) {
3013 if (!mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() > kInFlightWarnLimit) {
3014 CLOGW("In-flight list too large: %zu, total inflight duration %" PRIu64,
3015 mInFlightMap.size(), mExpectedInflightDuration);
3016 } else if (mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() >
3017 kInFlightWarnLimitHighSpeed) {
3018 CLOGW("In-flight list too large for high speed configuration: %zu,"
3019 "total inflight duration %" PRIu64,
3020 mInFlightMap.size(), mExpectedInflightDuration);
3021 }
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08003022 }
3023}
3024
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003025void Camera3Device::onInflightMapFlushedLocked() {
3026 mExpectedInflightDuration = 0;
3027}
3028
3029void Camera3Device::removeInFlightMapEntryLocked(int idx) {
Jayant Chowdharyd4776262020-06-23 23:45:57 -07003030 ATRACE_HFR_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003031 nsecs_t duration = mInFlightMap.valueAt(idx).maxExpectedDuration;
3032 mInFlightMap.removeItemsAt(idx, 1);
3033
3034 onInflightEntryRemovedLocked(duration);
3035}
3036
3037
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -07003038void Camera3Device::flushInflightRequests() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07003039 ATRACE_CALL();
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07003040 sp<NotificationListener> listener;
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07003041 {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003042 std::lock_guard<std::mutex> l(mOutputLock);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07003043 listener = mListener.promote();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07003044 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08003045
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003046 FlushInflightReqStates states {
3047 mId, mInFlightLock, mInFlightMap, mUseHalBufManager,
Shuzhen Wang316781a2020-08-18 18:11:01 -07003048 listener, *this, *mInterface, *this, mSessionStatsBuilder};
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07003049
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003050 camera3::flushInflightRequests(states);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07003051}
3052
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003053CameraMetadata Camera3Device::getLatestRequestLocked() {
Igor Murashkin1e479c02013-09-06 16:55:14 -07003054 ALOGV("%s", __FUNCTION__);
3055
Igor Murashkin1e479c02013-09-06 16:55:14 -07003056 CameraMetadata retVal;
3057
3058 if (mRequestThread != NULL) {
3059 retVal = mRequestThread->getLatestRequest();
3060 }
3061
Igor Murashkin1e479c02013-09-06 16:55:14 -07003062 return retVal;
3063}
3064
Eino-Ville Talvala4d453832016-07-15 11:56:53 -07003065void Camera3Device::monitorMetadata(TagMonitor::eventSource source,
Shuzhen Wangc2cba122018-05-17 18:10:24 -07003066 int64_t frameNumber, nsecs_t timestamp, const CameraMetadata& metadata,
3067 const std::unordered_map<std::string, CameraMetadata>& physicalMetadata) {
3068
3069 mTagMonitor.monitorMetadata(source, frameNumber, timestamp, metadata,
3070 physicalMetadata);
Eino-Ville Talvala4d453832016-07-15 11:56:53 -07003071}
3072
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08003073/**
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003074 * HalInterface inner class methods
3075 */
3076
Yifan Hongf79b5542017-04-11 14:44:25 -07003077Camera3Device::HalInterface::HalInterface(
3078 sp<ICameraDeviceSession> &session,
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003079 std::shared_ptr<RequestMetadataQueue> queue,
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003080 bool useHalBufManager, bool supportOfflineProcessing) :
Yifan Hongf79b5542017-04-11 14:44:25 -07003081 mHidlSession(session),
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003082 mRequestMetadataQueue(queue),
Emilian Peev4ec17882019-01-24 17:16:58 -08003083 mUseHalBufManager(useHalBufManager),
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003084 mIsReconfigurationQuerySupported(true),
3085 mSupportOfflineProcessing(supportOfflineProcessing) {
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003086 // Check with hardware service manager if we can downcast these interfaces
3087 // Somewhat expensive, so cache the results at startup
Shuzhen Wang83bff122020-11-20 15:51:39 -08003088 auto castResult_3_7 = device::V3_7::ICameraDeviceSession::castFrom(mHidlSession);
3089 if (castResult_3_7.isOk()) {
3090 mHidlSession_3_7 = castResult_3_7;
3091 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003092 auto castResult_3_6 = device::V3_6::ICameraDeviceSession::castFrom(mHidlSession);
3093 if (castResult_3_6.isOk()) {
3094 mHidlSession_3_6 = castResult_3_6;
3095 }
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07003096 auto castResult_3_5 = device::V3_5::ICameraDeviceSession::castFrom(mHidlSession);
3097 if (castResult_3_5.isOk()) {
3098 mHidlSession_3_5 = castResult_3_5;
3099 }
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003100 auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
3101 if (castResult_3_4.isOk()) {
3102 mHidlSession_3_4 = castResult_3_4;
3103 }
3104 auto castResult_3_3 = device::V3_3::ICameraDeviceSession::castFrom(mHidlSession);
3105 if (castResult_3_3.isOk()) {
3106 mHidlSession_3_3 = castResult_3_3;
3107 }
3108}
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003109
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003110Camera3Device::HalInterface::HalInterface() :
3111 mUseHalBufManager(false),
3112 mSupportOfflineProcessing(false) {}
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003113
3114Camera3Device::HalInterface::HalInterface(const HalInterface& other) :
Yifan Hongf79b5542017-04-11 14:44:25 -07003115 mHidlSession(other.mHidlSession),
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003116 mRequestMetadataQueue(other.mRequestMetadataQueue),
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003117 mUseHalBufManager(other.mUseHalBufManager),
3118 mSupportOfflineProcessing(other.mSupportOfflineProcessing) {}
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003119
3120bool Camera3Device::HalInterface::valid() {
Emilian Peev31abd0a2017-05-11 18:37:46 +01003121 return (mHidlSession != nullptr);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003122}
3123
3124void Camera3Device::HalInterface::clear() {
Shuzhen Wang83bff122020-11-20 15:51:39 -08003125 mHidlSession_3_7.clear();
Yin-Chia Yehb978c382019-10-30 00:22:37 -07003126 mHidlSession_3_6.clear();
Emilian Peev644a3e12018-11-23 13:52:39 +00003127 mHidlSession_3_5.clear();
Emilian Peev9e740b02018-01-30 18:28:03 +00003128 mHidlSession_3_4.clear();
3129 mHidlSession_3_3.clear();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003130 mHidlSession.clear();
3131}
3132
3133status_t Camera3Device::HalInterface::constructDefaultRequestSettings(
Emilian Peevf4816702020-04-03 15:44:51 -07003134 camera_request_template_t templateId,
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003135 /*out*/ camera_metadata_t **requestTemplate) {
3136 ATRACE_NAME("CameraHal::constructDefaultRequestSettings");
3137 if (!valid()) return INVALID_OPERATION;
3138 status_t res = OK;
3139
Emilian Peev31abd0a2017-05-11 18:37:46 +01003140 common::V1_0::Status status;
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003141
3142 auto requestCallback = [&status, &requestTemplate]
Emilian Peev31abd0a2017-05-11 18:37:46 +01003143 (common::V1_0::Status s, const device::V3_2::CameraMetadata& request) {
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003144 status = s;
3145 if (status == common::V1_0::Status::OK) {
3146 const camera_metadata *r =
3147 reinterpret_cast<const camera_metadata_t*>(request.data());
3148 size_t expectedSize = request.size();
3149 int ret = validate_camera_metadata_structure(r, &expectedSize);
3150 if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
3151 *requestTemplate = clone_camera_metadata(r);
3152 if (*requestTemplate == nullptr) {
3153 ALOGE("%s: Unable to clone camera metadata received from HAL",
3154 __FUNCTION__);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003155 status = common::V1_0::Status::INTERNAL_ERROR;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003156 }
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003157 } else {
3158 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
3159 status = common::V1_0::Status::INTERNAL_ERROR;
Emilian Peev31abd0a2017-05-11 18:37:46 +01003160 }
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003161 }
3162 };
3163 hardware::Return<void> err;
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003164 RequestTemplate id;
3165 switch (templateId) {
Emilian Peevf4816702020-04-03 15:44:51 -07003166 case CAMERA_TEMPLATE_PREVIEW:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003167 id = RequestTemplate::PREVIEW;
3168 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003169 case CAMERA_TEMPLATE_STILL_CAPTURE:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003170 id = RequestTemplate::STILL_CAPTURE;
3171 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003172 case CAMERA_TEMPLATE_VIDEO_RECORD:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003173 id = RequestTemplate::VIDEO_RECORD;
3174 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003175 case CAMERA_TEMPLATE_VIDEO_SNAPSHOT:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003176 id = RequestTemplate::VIDEO_SNAPSHOT;
3177 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003178 case CAMERA_TEMPLATE_ZERO_SHUTTER_LAG:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003179 id = RequestTemplate::ZERO_SHUTTER_LAG;
3180 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003181 case CAMERA_TEMPLATE_MANUAL:
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003182 id = RequestTemplate::MANUAL;
3183 break;
3184 default:
3185 // Unknown template ID, or this HAL is too old to support it
3186 return BAD_VALUE;
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003187 }
Eino-Ville Talvala96441462018-02-06 11:41:55 -08003188 err = mHidlSession->constructDefaultRequestSettings(id, requestCallback);
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003189
Emilian Peev31abd0a2017-05-11 18:37:46 +01003190 if (!err.isOk()) {
3191 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3192 res = DEAD_OBJECT;
3193 } else {
3194 res = CameraProviderManager::mapToStatusT(status);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003195 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01003196
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003197 return res;
3198}
3199
Emilian Peev4ec17882019-01-24 17:16:58 -08003200bool Camera3Device::HalInterface::isReconfigurationRequired(CameraMetadata& oldSessionParams,
3201 CameraMetadata& newSessionParams) {
3202 // We do reconfiguration by default;
3203 bool ret = true;
3204 if ((mHidlSession_3_5 != nullptr) && mIsReconfigurationQuerySupported) {
3205 android::hardware::hidl_vec<uint8_t> oldParams, newParams;
3206 camera_metadata_t* oldSessioMeta = const_cast<camera_metadata_t*>(
3207 oldSessionParams.getAndLock());
3208 camera_metadata_t* newSessioMeta = const_cast<camera_metadata_t*>(
3209 newSessionParams.getAndLock());
3210 oldParams.setToExternal(reinterpret_cast<uint8_t*>(oldSessioMeta),
3211 get_camera_metadata_size(oldSessioMeta));
3212 newParams.setToExternal(reinterpret_cast<uint8_t*>(newSessioMeta),
3213 get_camera_metadata_size(newSessioMeta));
3214 hardware::camera::common::V1_0::Status callStatus;
3215 bool required;
3216 auto hidlCb = [&callStatus, &required] (hardware::camera::common::V1_0::Status s,
3217 bool requiredFlag) {
3218 callStatus = s;
3219 required = requiredFlag;
3220 };
3221 auto err = mHidlSession_3_5->isReconfigurationRequired(oldParams, newParams, hidlCb);
3222 oldSessionParams.unlock(oldSessioMeta);
3223 newSessionParams.unlock(newSessioMeta);
3224 if (err.isOk()) {
3225 switch (callStatus) {
3226 case hardware::camera::common::V1_0::Status::OK:
3227 ret = required;
3228 break;
3229 case hardware::camera::common::V1_0::Status::METHOD_NOT_SUPPORTED:
3230 mIsReconfigurationQuerySupported = false;
3231 ret = true;
3232 break;
3233 default:
3234 ALOGV("%s: Reconfiguration query failed: %d", __FUNCTION__, callStatus);
3235 ret = true;
3236 }
3237 } else {
3238 ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, err.description().c_str());
3239 ret = true;
3240 }
3241 }
3242
3243 return ret;
3244}
3245
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01003246status_t Camera3Device::HalInterface::configureStreams(const camera_metadata_t *sessionParams,
Emilian Peevf4816702020-04-03 15:44:51 -07003247 camera_stream_configuration *config, const std::vector<uint32_t>& bufferSizes) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003248 ATRACE_NAME("CameraHal::configureStreams");
3249 if (!valid()) return INVALID_OPERATION;
3250 status_t res = OK;
3251
Shuzhen Wang83bff122020-11-20 15:51:39 -08003252 if (config->input_is_multi_resolution && mHidlSession_3_7 == nullptr) {
3253 ALOGE("%s: Camera device doesn't support multi-resolution input stream", __FUNCTION__);
3254 return BAD_VALUE;
3255 }
3256
Emilian Peev31abd0a2017-05-11 18:37:46 +01003257 // Convert stream config to HIDL
3258 std::set<int> activeStreams;
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003259 device::V3_2::StreamConfiguration requestedConfiguration3_2;
3260 device::V3_4::StreamConfiguration requestedConfiguration3_4;
Shuzhen Wang83bff122020-11-20 15:51:39 -08003261 device::V3_7::StreamConfiguration requestedConfiguration3_7;
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003262 requestedConfiguration3_2.streams.resize(config->num_streams);
3263 requestedConfiguration3_4.streams.resize(config->num_streams);
Shuzhen Wang83bff122020-11-20 15:51:39 -08003264 requestedConfiguration3_7.streams.resize(config->num_streams);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003265 for (size_t i = 0; i < config->num_streams; i++) {
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003266 device::V3_2::Stream &dst3_2 = requestedConfiguration3_2.streams[i];
3267 device::V3_4::Stream &dst3_4 = requestedConfiguration3_4.streams[i];
Shuzhen Wang83bff122020-11-20 15:51:39 -08003268 device::V3_7::Stream &dst3_7 = requestedConfiguration3_7.streams[i];
Emilian Peevf4816702020-04-03 15:44:51 -07003269 camera3::camera_stream_t *src = config->streams[i];
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003270
Emilian Peev31abd0a2017-05-11 18:37:46 +01003271 Camera3Stream* cam3stream = Camera3Stream::cast(src);
3272 cam3stream->setBufferFreedListener(this);
3273 int streamId = cam3stream->getId();
3274 StreamType streamType;
3275 switch (src->stream_type) {
Emilian Peevf4816702020-04-03 15:44:51 -07003276 case CAMERA_STREAM_OUTPUT:
Emilian Peev31abd0a2017-05-11 18:37:46 +01003277 streamType = StreamType::OUTPUT;
3278 break;
Emilian Peevf4816702020-04-03 15:44:51 -07003279 case CAMERA_STREAM_INPUT:
Emilian Peev31abd0a2017-05-11 18:37:46 +01003280 streamType = StreamType::INPUT;
3281 break;
3282 default:
3283 ALOGE("%s: Stream %d: Unsupported stream type %d",
3284 __FUNCTION__, streamId, config->streams[i]->stream_type);
3285 return BAD_VALUE;
3286 }
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003287 dst3_2.id = streamId;
3288 dst3_2.streamType = streamType;
3289 dst3_2.width = src->width;
3290 dst3_2.height = src->height;
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003291 dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
Emilian Peevf4816702020-04-03 15:44:51 -07003292 dst3_2.rotation = mapToStreamRotation((camera_stream_rotation_t) src->rotation);
Shuzhen Wang92653952019-05-07 15:11:43 -07003293 // For HidlSession version 3.5 or newer, the format and dataSpace sent
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08003294 // to HAL are original, not the overridden ones.
Shuzhen Wang92653952019-05-07 15:11:43 -07003295 if (mHidlSession_3_5 != nullptr) {
3296 dst3_2.format = mapToPixelFormat(cam3stream->isFormatOverridden() ?
3297 cam3stream->getOriginalFormat() : src->format);
3298 dst3_2.dataSpace = mapToHidlDataspace(cam3stream->isDataSpaceOverridden() ?
3299 cam3stream->getOriginalDataSpace() : src->data_space);
3300 } else {
3301 dst3_2.format = mapToPixelFormat(src->format);
3302 dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
3303 }
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003304 dst3_4.v3_2 = dst3_2;
Emilian Peev192ee832018-01-31 14:46:47 +00003305 dst3_4.bufferSize = bufferSizes[i];
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003306 if (src->physical_camera_id != nullptr) {
3307 dst3_4.physicalCameraId = src->physical_camera_id;
3308 }
Shuzhen Wang83bff122020-11-20 15:51:39 -08003309 dst3_7.v3_4 = dst3_4;
3310 dst3_7.groupId = cam3stream->getHalStreamGroupId();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08003311 dst3_7.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
3312 size_t j = 0;
3313 for (int mode : src->sensor_pixel_modes_used) {
3314 dst3_7.sensorPixelModesUsed[j++] =
3315 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
3316 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01003317 activeStreams.insert(streamId);
3318 // Create Buffer ID map if necessary
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003319 mBufferRecords.tryCreateBufferCache(streamId);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003320 }
3321 // remove BufferIdMap for deleted streams
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003322 mBufferRecords.removeInactiveBufferCaches(activeStreams);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003323
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003324 StreamConfigurationMode operationMode;
Emilian Peev31abd0a2017-05-11 18:37:46 +01003325 res = mapToStreamConfigurationMode(
Emilian Peevf4816702020-04-03 15:44:51 -07003326 (camera_stream_configuration_mode_t) config->operation_mode,
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003327 /*out*/ &operationMode);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003328 if (res != OK) {
3329 return res;
3330 }
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003331 requestedConfiguration3_2.operationMode = operationMode;
3332 requestedConfiguration3_4.operationMode = operationMode;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08003333 requestedConfiguration3_7.operationMode = operationMode;
3334 size_t sessionParamSize = get_camera_metadata_size(sessionParams);
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003335 requestedConfiguration3_4.sessionParams.setToExternal(
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01003336 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08003337 sessionParamSize);
Shuzhen Wang83bff122020-11-20 15:51:39 -08003338 requestedConfiguration3_7.operationMode = operationMode;
3339 requestedConfiguration3_7.sessionParams.setToExternal(
3340 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08003341 sessionParamSize);
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01003342
Emilian Peev31abd0a2017-05-11 18:37:46 +01003343 // Invoke configureStreams
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003344 device::V3_3::HalStreamConfiguration finalConfiguration;
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003345 device::V3_4::HalStreamConfiguration finalConfiguration3_4;
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003346 device::V3_6::HalStreamConfiguration finalConfiguration3_6;
Emilian Peev31abd0a2017-05-11 18:37:46 +01003347 common::V1_0::Status status;
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003348
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003349 auto configStream34Cb = [&status, &finalConfiguration3_4]
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003350 (common::V1_0::Status s, const device::V3_4::HalStreamConfiguration& halConfiguration) {
3351 finalConfiguration3_4 = halConfiguration;
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01003352 status = s;
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003353 };
3354
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003355 auto configStream36Cb = [&status, &finalConfiguration3_6]
3356 (common::V1_0::Status s, const device::V3_6::HalStreamConfiguration& halConfiguration) {
3357 finalConfiguration3_6 = halConfiguration;
3358 status = s;
3359 };
3360
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003361 auto postprocConfigStream34 = [&finalConfiguration, &finalConfiguration3_4]
3362 (hardware::Return<void>& err) -> status_t {
3363 if (!err.isOk()) {
3364 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3365 return DEAD_OBJECT;
3366 }
3367 finalConfiguration.streams.resize(finalConfiguration3_4.streams.size());
3368 for (size_t i = 0; i < finalConfiguration3_4.streams.size(); i++) {
3369 finalConfiguration.streams[i] = finalConfiguration3_4.streams[i].v3_3;
3370 }
3371 return OK;
3372 };
3373
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003374 auto postprocConfigStream36 = [&finalConfiguration, &finalConfiguration3_6]
3375 (hardware::Return<void>& err) -> status_t {
3376 if (!err.isOk()) {
3377 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3378 return DEAD_OBJECT;
3379 }
3380 finalConfiguration.streams.resize(finalConfiguration3_6.streams.size());
3381 for (size_t i = 0; i < finalConfiguration3_6.streams.size(); i++) {
3382 finalConfiguration.streams[i] = finalConfiguration3_6.streams[i].v3_4.v3_3;
3383 }
3384 return OK;
3385 };
3386
Shuzhen Wang92653952019-05-07 15:11:43 -07003387 // See which version of HAL we have
Shuzhen Wang83bff122020-11-20 15:51:39 -08003388 if (mHidlSession_3_7 != nullptr) {
3389 ALOGV("%s: v3.7 device found", __FUNCTION__);
3390 requestedConfiguration3_7.streamConfigCounter = mNextStreamConfigCounter++;
3391 requestedConfiguration3_7.multiResolutionInputImage = config->input_is_multi_resolution;
3392 auto err = mHidlSession_3_7->configureStreams_3_7(
3393 requestedConfiguration3_7, configStream36Cb);
3394 res = postprocConfigStream36(err);
3395 if (res != OK) {
3396 return res;
3397 }
3398 } else if (mHidlSession_3_6 != nullptr) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003399 ALOGV("%s: v3.6 device found", __FUNCTION__);
3400 device::V3_5::StreamConfiguration requestedConfiguration3_5;
3401 requestedConfiguration3_5.v3_4 = requestedConfiguration3_4;
3402 requestedConfiguration3_5.streamConfigCounter = mNextStreamConfigCounter++;
3403 auto err = mHidlSession_3_6->configureStreams_3_6(
3404 requestedConfiguration3_5, configStream36Cb);
3405 res = postprocConfigStream36(err);
3406 if (res != OK) {
3407 return res;
3408 }
3409 } else if (mHidlSession_3_5 != nullptr) {
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003410 ALOGV("%s: v3.5 device found", __FUNCTION__);
3411 device::V3_5::StreamConfiguration requestedConfiguration3_5;
3412 requestedConfiguration3_5.v3_4 = requestedConfiguration3_4;
3413 requestedConfiguration3_5.streamConfigCounter = mNextStreamConfigCounter++;
3414 auto err = mHidlSession_3_5->configureStreams_3_5(
3415 requestedConfiguration3_5, configStream34Cb);
3416 res = postprocConfigStream34(err);
3417 if (res != OK) {
3418 return res;
Emilian Peev5fbe0ba2017-10-20 15:45:45 +01003419 }
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003420 } else if (mHidlSession_3_4 != nullptr) {
3421 // We do; use v3.4 for the call
3422 ALOGV("%s: v3.4 device found", __FUNCTION__);
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07003423 auto err = mHidlSession_3_4->configureStreams_3_4(
3424 requestedConfiguration3_4, configStream34Cb);
3425 res = postprocConfigStream34(err);
3426 if (res != OK) {
3427 return res;
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003428 }
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003429 } else if (mHidlSession_3_3 != nullptr) {
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003430 // We do; use v3.3 for the call
3431 ALOGV("%s: v3.3 device found", __FUNCTION__);
Eino-Ville Talvala1a86df52018-01-17 16:00:35 -08003432 auto err = mHidlSession_3_3->configureStreams_3_3(requestedConfiguration3_2,
Emilian Peev31abd0a2017-05-11 18:37:46 +01003433 [&status, &finalConfiguration]
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003434 (common::V1_0::Status s, const device::V3_3::HalStreamConfiguration& halConfiguration) {
Emilian Peev31abd0a2017-05-11 18:37:46 +01003435 finalConfiguration = halConfiguration;
3436 status = s;
3437 });
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003438 if (!err.isOk()) {
3439 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3440 return DEAD_OBJECT;
3441 }
3442 } else {
3443 // We don't; use v3.2 call and construct a v3.3 HalStreamConfiguration
3444 ALOGV("%s: v3.2 device found", __FUNCTION__);
3445 HalStreamConfiguration finalConfiguration_3_2;
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003446 auto err = mHidlSession->configureStreams(requestedConfiguration3_2,
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003447 [&status, &finalConfiguration_3_2]
3448 (common::V1_0::Status s, const HalStreamConfiguration& halConfiguration) {
3449 finalConfiguration_3_2 = halConfiguration;
3450 status = s;
3451 });
3452 if (!err.isOk()) {
3453 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3454 return DEAD_OBJECT;
3455 }
3456 finalConfiguration.streams.resize(finalConfiguration_3_2.streams.size());
3457 for (size_t i = 0; i < finalConfiguration_3_2.streams.size(); i++) {
3458 finalConfiguration.streams[i].v3_2 = finalConfiguration_3_2.streams[i];
3459 finalConfiguration.streams[i].overrideDataSpace =
Shuzhen Wangc28189a2017-11-27 23:05:10 -08003460 requestedConfiguration3_2.streams[i].dataSpace;
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003461 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01003462 }
3463
3464 if (status != common::V1_0::Status::OK ) {
3465 return CameraProviderManager::mapToStatusT(status);
3466 }
3467
3468 // And convert output stream configuration from HIDL
3469
3470 for (size_t i = 0; i < config->num_streams; i++) {
Emilian Peevf4816702020-04-03 15:44:51 -07003471 camera3::camera_stream_t *dst = config->streams[i];
Emilian Peev31abd0a2017-05-11 18:37:46 +01003472 int streamId = Camera3Stream::cast(dst)->getId();
3473
3474 // Start scan at i, with the assumption that the stream order matches
3475 size_t realIdx = i;
3476 bool found = false;
Eino-Ville Talvala370875f2019-04-12 12:40:27 -07003477 size_t halStreamCount = finalConfiguration.streams.size();
3478 for (size_t idx = 0; idx < halStreamCount; idx++) {
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003479 if (finalConfiguration.streams[realIdx].v3_2.id == streamId) {
Emilian Peev31abd0a2017-05-11 18:37:46 +01003480 found = true;
3481 break;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003482 }
Eino-Ville Talvala370875f2019-04-12 12:40:27 -07003483 realIdx = (realIdx >= halStreamCount - 1) ? 0 : realIdx + 1;
Emilian Peev31abd0a2017-05-11 18:37:46 +01003484 }
3485 if (!found) {
3486 ALOGE("%s: Stream %d not found in stream configuration response from HAL",
3487 __FUNCTION__, streamId);
3488 return INVALID_OPERATION;
3489 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003490 device::V3_3::HalStream &src = finalConfiguration.streams[realIdx];
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003491 device::V3_6::HalStream &src_36 = finalConfiguration3_6.streams[realIdx];
Yin-Chia Yeh77327052017-01-09 18:23:07 -08003492
Emilian Peev710c1422017-08-30 11:19:38 +01003493 Camera3Stream* dstStream = Camera3Stream::cast(dst);
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003494 int overrideFormat = mapToFrameworkFormat(src.v3_2.overrideFormat);
3495 android_dataspace overrideDataSpace = mapToFrameworkDataspace(src.overrideDataSpace);
3496
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003497 if (mHidlSession_3_6 != nullptr) {
3498 dstStream->setOfflineProcessingSupport(src_36.supportOffline);
3499 }
3500
Yin-Chia Yeh90667662019-07-01 15:45:00 -07003501 if (dstStream->getOriginalFormat() != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
Shuzhen Wang92653952019-05-07 15:11:43 -07003502 dstStream->setFormatOverride(false);
3503 dstStream->setDataSpaceOverride(false);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003504 if (dst->format != overrideFormat) {
3505 ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
3506 streamId, dst->format);
Yin-Chia Yeh77327052017-01-09 18:23:07 -08003507 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003508 if (dst->data_space != overrideDataSpace) {
3509 ALOGE("%s: Stream %d: DataSpace override not allowed for format 0x%x", __FUNCTION__,
3510 streamId, dst->format);
3511 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01003512 } else {
Shuzhen Wang92653952019-05-07 15:11:43 -07003513 bool needFormatOverride =
3514 requestedConfiguration3_2.streams[i].format != src.v3_2.overrideFormat;
3515 bool needDataspaceOverride =
3516 requestedConfiguration3_2.streams[i].dataSpace != src.overrideDataSpace;
Emilian Peev31abd0a2017-05-11 18:37:46 +01003517 // Override allowed with IMPLEMENTATION_DEFINED
Shuzhen Wang92653952019-05-07 15:11:43 -07003518 dstStream->setFormatOverride(needFormatOverride);
3519 dstStream->setDataSpaceOverride(needDataspaceOverride);
Emilian Peev31abd0a2017-05-11 18:37:46 +01003520 dst->format = overrideFormat;
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003521 dst->data_space = overrideDataSpace;
Yin-Chia Yeh77327052017-01-09 18:23:07 -08003522 }
3523
Emilian Peevf4816702020-04-03 15:44:51 -07003524 if (dst->stream_type == CAMERA_STREAM_INPUT) {
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003525 if (src.v3_2.producerUsage != 0) {
Emilian Peev31abd0a2017-05-11 18:37:46 +01003526 ALOGE("%s: Stream %d: INPUT streams must have 0 for producer usage",
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003527 __FUNCTION__, streamId);
3528 return INVALID_OPERATION;
3529 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003530 dstStream->setUsage(
3531 mapConsumerToFrameworkUsage(src.v3_2.consumerUsage));
Emilian Peev31abd0a2017-05-11 18:37:46 +01003532 } else {
3533 // OUTPUT
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003534 if (src.v3_2.consumerUsage != 0) {
Emilian Peev31abd0a2017-05-11 18:37:46 +01003535 ALOGE("%s: Stream %d: OUTPUT streams must have 0 for consumer usage",
3536 __FUNCTION__, streamId);
3537 return INVALID_OPERATION;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003538 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003539 dstStream->setUsage(
3540 mapProducerToFrameworkUsage(src.v3_2.producerUsage));
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003541 }
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -07003542 dst->max_buffers = src.v3_2.maxBuffers;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003543 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01003544
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003545 return res;
3546}
3547
Cliff Wuc2ad9c82021-04-21 00:58:58 +08003548status_t Camera3Device::HalInterface::configureInjectedStreams(
3549 const camera_metadata_t* sessionParams, camera_stream_configuration* config,
3550 const std::vector<uint32_t>& bufferSizes,
3551 const CameraMetadata& cameraCharacteristics) {
3552 ATRACE_NAME("InjectionCameraHal::configureStreams");
3553 if (!valid()) return INVALID_OPERATION;
3554 status_t res = OK;
3555
3556 if (config->input_is_multi_resolution) {
3557 ALOGE("%s: Injection camera device doesn't support multi-resolution input "
3558 "stream", __FUNCTION__);
3559 return BAD_VALUE;
3560 }
3561
3562 // Convert stream config to HIDL
3563 std::set<int> activeStreams;
3564 device::V3_2::StreamConfiguration requestedConfiguration3_2;
3565 device::V3_4::StreamConfiguration requestedConfiguration3_4;
3566 device::V3_7::StreamConfiguration requestedConfiguration3_7;
3567 requestedConfiguration3_2.streams.resize(config->num_streams);
3568 requestedConfiguration3_4.streams.resize(config->num_streams);
3569 requestedConfiguration3_7.streams.resize(config->num_streams);
3570 for (size_t i = 0; i < config->num_streams; i++) {
3571 device::V3_2::Stream& dst3_2 = requestedConfiguration3_2.streams[i];
3572 device::V3_4::Stream& dst3_4 = requestedConfiguration3_4.streams[i];
3573 device::V3_7::Stream& dst3_7 = requestedConfiguration3_7.streams[i];
3574 camera3::camera_stream_t* src = config->streams[i];
3575
3576 Camera3Stream* cam3stream = Camera3Stream::cast(src);
3577 cam3stream->setBufferFreedListener(this);
3578 int streamId = cam3stream->getId();
3579 StreamType streamType;
3580 switch (src->stream_type) {
3581 case CAMERA_STREAM_OUTPUT:
3582 streamType = StreamType::OUTPUT;
3583 break;
3584 case CAMERA_STREAM_INPUT:
3585 streamType = StreamType::INPUT;
3586 break;
3587 default:
3588 ALOGE("%s: Stream %d: Unsupported stream type %d", __FUNCTION__,
3589 streamId, config->streams[i]->stream_type);
3590 return BAD_VALUE;
3591 }
3592 dst3_2.id = streamId;
3593 dst3_2.streamType = streamType;
3594 dst3_2.width = src->width;
3595 dst3_2.height = src->height;
3596 dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
3597 dst3_2.rotation =
3598 mapToStreamRotation((camera_stream_rotation_t)src->rotation);
3599 // For HidlSession version 3.5 or newer, the format and dataSpace sent
3600 // to HAL are original, not the overridden ones.
3601 if (mHidlSession_3_5 != nullptr) {
3602 dst3_2.format = mapToPixelFormat(cam3stream->isFormatOverridden()
3603 ? cam3stream->getOriginalFormat()
3604 : src->format);
3605 dst3_2.dataSpace =
3606 mapToHidlDataspace(cam3stream->isDataSpaceOverridden()
3607 ? cam3stream->getOriginalDataSpace()
3608 : src->data_space);
3609 } else {
3610 dst3_2.format = mapToPixelFormat(src->format);
3611 dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
3612 }
3613 dst3_4.v3_2 = dst3_2;
3614 dst3_4.bufferSize = bufferSizes[i];
3615 if (src->physical_camera_id != nullptr) {
3616 dst3_4.physicalCameraId = src->physical_camera_id;
3617 }
3618 dst3_7.v3_4 = dst3_4;
3619 dst3_7.groupId = cam3stream->getHalStreamGroupId();
3620 dst3_7.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
3621 size_t j = 0;
3622 for (int mode : src->sensor_pixel_modes_used) {
3623 dst3_7.sensorPixelModesUsed[j++] =
3624 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
3625 }
3626 activeStreams.insert(streamId);
3627 // Create Buffer ID map if necessary
3628 mBufferRecords.tryCreateBufferCache(streamId);
3629 }
3630 // remove BufferIdMap for deleted streams
3631 mBufferRecords.removeInactiveBufferCaches(activeStreams);
3632
3633 StreamConfigurationMode operationMode;
3634 res = mapToStreamConfigurationMode(
3635 (camera_stream_configuration_mode_t)config->operation_mode,
3636 /*out*/ &operationMode);
3637 if (res != OK) {
3638 return res;
3639 }
3640 requestedConfiguration3_7.operationMode = operationMode;
3641 size_t sessionParamSize = get_camera_metadata_size(sessionParams);
3642 requestedConfiguration3_7.operationMode = operationMode;
3643 requestedConfiguration3_7.sessionParams.setToExternal(
3644 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
3645 sessionParamSize);
3646
3647 // See which version of HAL we have
3648 if (mHidlSession_3_7 != nullptr) {
3649 requestedConfiguration3_7.streamConfigCounter = mNextStreamConfigCounter++;
3650 requestedConfiguration3_7.multiResolutionInputImage =
3651 config->input_is_multi_resolution;
3652
3653 const camera_metadata_t* rawMetadata = cameraCharacteristics.getAndLock();
3654 ::android::hardware::camera::device::V3_2::CameraMetadata hidlChars = {};
3655 hidlChars.setToExternal(
3656 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(rawMetadata)),
3657 get_camera_metadata_size(rawMetadata));
3658 cameraCharacteristics.unlock(rawMetadata);
3659
3660 sp<hardware::camera::device::V3_7::ICameraInjectionSession>
3661 hidlInjectionSession_3_7;
3662 auto castInjectionResult_3_7 =
3663 device::V3_7::ICameraInjectionSession::castFrom(mHidlSession_3_7);
3664 if (castInjectionResult_3_7.isOk()) {
3665 hidlInjectionSession_3_7 = castInjectionResult_3_7;
3666 } else {
3667 ALOGE("%s: Transaction error: %s", __FUNCTION__,
3668 castInjectionResult_3_7.description().c_str());
3669 return DEAD_OBJECT;
3670 }
3671
3672 auto err = hidlInjectionSession_3_7->configureInjectionStreams(
3673 requestedConfiguration3_7, hidlChars);
3674 if (!err.isOk()) {
3675 ALOGE("%s: Transaction error: %s", __FUNCTION__,
3676 err.description().c_str());
3677 return DEAD_OBJECT;
3678 }
3679 } else {
3680 ALOGE("%s: mHidlSession_3_7 does not exist, the lowest version of injection "
3681 "session is 3.7", __FUNCTION__);
3682 return DEAD_OBJECT;
3683 }
3684
3685 return res;
3686}
3687
Emilian Peevf4816702020-04-03 15:44:51 -07003688status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera_capture_request_t* request,
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003689 /*out*/device::V3_2::CaptureRequest* captureRequest,
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003690 /*out*/std::vector<native_handle_t*>* handlesCreated,
3691 /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07003692 ATRACE_CALL();
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003693 if (captureRequest == nullptr || handlesCreated == nullptr || inflightBuffers == nullptr) {
3694 ALOGE("%s: captureRequest (%p), handlesCreated (%p), and inflightBuffers(%p) "
3695 "must not be null", __FUNCTION__, captureRequest, handlesCreated, inflightBuffers);
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003696 return BAD_VALUE;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003697 }
3698
3699 captureRequest->frameNumber = request->frame_number;
Yifan Hongf79b5542017-04-11 14:44:25 -07003700
3701 captureRequest->fmqSettingsSize = 0;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003702
3703 {
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003704 if (request->input_buffer != nullptr) {
3705 int32_t streamId = Camera3Stream::cast(request->input_buffer->stream)->getId();
3706 buffer_handle_t buf = *(request->input_buffer->buffer);
3707 auto pair = getBufferId(buf, streamId);
3708 bool isNewBuffer = pair.first;
3709 uint64_t bufferId = pair.second;
3710 captureRequest->inputBuffer.streamId = streamId;
3711 captureRequest->inputBuffer.bufferId = bufferId;
3712 captureRequest->inputBuffer.buffer = (isNewBuffer) ? buf : nullptr;
3713 captureRequest->inputBuffer.status = BufferStatus::OK;
3714 native_handle_t *acquireFence = nullptr;
3715 if (request->input_buffer->acquire_fence != -1) {
3716 acquireFence = native_handle_create(1,0);
3717 acquireFence->data[0] = request->input_buffer->acquire_fence;
3718 handlesCreated->push_back(acquireFence);
3719 }
3720 captureRequest->inputBuffer.acquireFence = acquireFence;
3721 captureRequest->inputBuffer.releaseFence = nullptr;
3722
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003723 mBufferRecords.pushInflightBuffer(captureRequest->frameNumber, streamId,
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003724 request->input_buffer->buffer);
3725 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003726 } else {
3727 captureRequest->inputBuffer.streamId = -1;
3728 captureRequest->inputBuffer.bufferId = BUFFER_ID_NO_BUFFER;
3729 }
3730
3731 captureRequest->outputBuffers.resize(request->num_output_buffers);
3732 for (size_t i = 0; i < request->num_output_buffers; i++) {
Emilian Peevf4816702020-04-03 15:44:51 -07003733 const camera_stream_buffer_t *src = request->output_buffers + i;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003734 StreamBuffer &dst = captureRequest->outputBuffers[i];
3735 int32_t streamId = Camera3Stream::cast(src->stream)->getId();
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003736 if (src->buffer != nullptr) {
3737 buffer_handle_t buf = *(src->buffer);
3738 auto pair = getBufferId(buf, streamId);
3739 bool isNewBuffer = pair.first;
3740 dst.bufferId = pair.second;
3741 dst.buffer = isNewBuffer ? buf : nullptr;
3742 native_handle_t *acquireFence = nullptr;
3743 if (src->acquire_fence != -1) {
3744 acquireFence = native_handle_create(1,0);
3745 acquireFence->data[0] = src->acquire_fence;
3746 handlesCreated->push_back(acquireFence);
3747 }
3748 dst.acquireFence = acquireFence;
3749 } else if (mUseHalBufManager) {
3750 // HAL buffer management path
3751 dst.bufferId = BUFFER_ID_NO_BUFFER;
3752 dst.buffer = nullptr;
3753 dst.acquireFence = nullptr;
3754 } else {
3755 ALOGE("%s: cannot send a null buffer in capture request!", __FUNCTION__);
3756 return BAD_VALUE;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003757 }
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003758 dst.streamId = streamId;
3759 dst.status = BufferStatus::OK;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003760 dst.releaseFence = nullptr;
3761
Yin-Chia Yeh5f840f82019-03-05 11:59:04 -08003762 // Output buffers are empty when using HAL buffer manager
3763 if (!mUseHalBufManager) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003764 mBufferRecords.pushInflightBuffer(
3765 captureRequest->frameNumber, streamId, src->buffer);
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003766 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
Yin-Chia Yeh5f840f82019-03-05 11:59:04 -08003767 }
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003768 }
3769 }
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003770 return OK;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003771}
3772
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003773void Camera3Device::HalInterface::cleanupNativeHandles(
3774 std::vector<native_handle_t*> *handles, bool closeFd) {
3775 if (handles == nullptr) {
3776 return;
3777 }
3778 if (closeFd) {
3779 for (auto& handle : *handles) {
3780 native_handle_close(handle);
3781 }
3782 }
3783 for (auto& handle : *handles) {
3784 native_handle_delete(handle);
3785 }
3786 handles->clear();
3787 return;
3788}
3789
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003790status_t Camera3Device::HalInterface::processBatchCaptureRequests(
Emilian Peevf4816702020-04-03 15:44:51 -07003791 std::vector<camera_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003792 ATRACE_NAME("CameraHal::processBatchCaptureRequests");
3793 if (!valid()) return INVALID_OPERATION;
3794
Emilian Peevaebbe412018-01-15 13:53:24 +00003795 sp<device::V3_4::ICameraDeviceSession> hidlSession_3_4;
Shuzhen Wang83bff122020-11-20 15:51:39 -08003796 sp<device::V3_7::ICameraDeviceSession> hidlSession_3_7;
3797 auto castResult_3_7 = device::V3_7::ICameraDeviceSession::castFrom(mHidlSession);
3798 if (castResult_3_7.isOk()) {
3799 hidlSession_3_7 = castResult_3_7;
3800 }
Emilian Peevaebbe412018-01-15 13:53:24 +00003801 auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
3802 if (castResult_3_4.isOk()) {
3803 hidlSession_3_4 = castResult_3_4;
3804 }
3805
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003806 hardware::hidl_vec<device::V3_2::CaptureRequest> captureRequests;
Emilian Peevaebbe412018-01-15 13:53:24 +00003807 hardware::hidl_vec<device::V3_4::CaptureRequest> captureRequests_3_4;
Shuzhen Wang83bff122020-11-20 15:51:39 -08003808 hardware::hidl_vec<device::V3_7::CaptureRequest> captureRequests_3_7;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003809 size_t batchSize = requests.size();
Shuzhen Wang83bff122020-11-20 15:51:39 -08003810 if (hidlSession_3_7 != nullptr) {
3811 captureRequests_3_7.resize(batchSize);
3812 } else if (hidlSession_3_4 != nullptr) {
Emilian Peevaebbe412018-01-15 13:53:24 +00003813 captureRequests_3_4.resize(batchSize);
3814 } else {
3815 captureRequests.resize(batchSize);
3816 }
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003817 std::vector<native_handle_t*> handlesCreated;
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003818 std::vector<std::pair<int32_t, int32_t>> inflightBuffers;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003819
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003820 status_t res = OK;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003821 for (size_t i = 0; i < batchSize; i++) {
Shuzhen Wang83bff122020-11-20 15:51:39 -08003822 if (hidlSession_3_7 != nullptr) {
3823 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_7[i].v3_4.v3_2,
3824 /*out*/&handlesCreated, /*out*/&inflightBuffers);
3825 } else if (hidlSession_3_4 != nullptr) {
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003826 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_4[i].v3_2,
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003827 /*out*/&handlesCreated, /*out*/&inflightBuffers);
Emilian Peevaebbe412018-01-15 13:53:24 +00003828 } else {
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003829 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests[i],
3830 /*out*/&handlesCreated, /*out*/&inflightBuffers);
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003831 }
3832 if (res != OK) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003833 mBufferRecords.popInflightBuffers(inflightBuffers);
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003834 cleanupNativeHandles(&handlesCreated);
Yin-Chia Yeh651fe2e2018-11-13 11:49:31 -08003835 return res;
Emilian Peevaebbe412018-01-15 13:53:24 +00003836 }
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003837 }
3838
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07003839 std::vector<device::V3_2::BufferCache> cachesToRemove;
3840 {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003841 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07003842 for (auto& pair : mFreedBuffers) {
3843 // The stream might have been removed since onBufferFreed
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003844 if (mBufferRecords.isStreamCached(pair.first)) {
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07003845 cachesToRemove.push_back({pair.first, pair.second});
3846 }
3847 }
3848 mFreedBuffers.clear();
3849 }
3850
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003851 common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR;
3852 *numRequestProcessed = 0;
Yifan Hongf79b5542017-04-11 14:44:25 -07003853
3854 // Write metadata to FMQ.
3855 for (size_t i = 0; i < batchSize; i++) {
Emilian Peevf4816702020-04-03 15:44:51 -07003856 camera_capture_request_t* request = requests[i];
Emilian Peevaebbe412018-01-15 13:53:24 +00003857 device::V3_2::CaptureRequest* captureRequest;
Shuzhen Wang83bff122020-11-20 15:51:39 -08003858 if (hidlSession_3_7 != nullptr) {
3859 captureRequest = &captureRequests_3_7[i].v3_4.v3_2;
3860 } else if (hidlSession_3_4 != nullptr) {
Emilian Peevaebbe412018-01-15 13:53:24 +00003861 captureRequest = &captureRequests_3_4[i].v3_2;
3862 } else {
3863 captureRequest = &captureRequests[i];
3864 }
Yifan Hongf79b5542017-04-11 14:44:25 -07003865
3866 if (request->settings != nullptr) {
3867 size_t settingsSize = get_camera_metadata_size(request->settings);
3868 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
3869 reinterpret_cast<const uint8_t*>(request->settings), settingsSize)) {
3870 captureRequest->settings.resize(0);
3871 captureRequest->fmqSettingsSize = settingsSize;
3872 } else {
3873 if (mRequestMetadataQueue != nullptr) {
3874 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
3875 }
3876 captureRequest->settings.setToExternal(
3877 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(request->settings)),
3878 get_camera_metadata_size(request->settings));
3879 captureRequest->fmqSettingsSize = 0u;
3880 }
3881 } else {
3882 // A null request settings maps to a size-0 CameraMetadata
3883 captureRequest->settings.resize(0);
3884 captureRequest->fmqSettingsSize = 0u;
3885 }
Emilian Peevaebbe412018-01-15 13:53:24 +00003886
Shuzhen Wang83bff122020-11-20 15:51:39 -08003887 // hidl session 3.7 specific handling.
3888 if (hidlSession_3_7 != nullptr) {
3889 captureRequests_3_7[i].inputWidth = request->input_width;
3890 captureRequests_3_7[i].inputHeight = request->input_height;
3891 }
3892
3893 // hidl session 3.7 and 3.4 specific handling.
3894 if (hidlSession_3_7 != nullptr || hidlSession_3_4 != nullptr) {
3895 hardware::hidl_vec<device::V3_4::PhysicalCameraSetting>& physicalCameraSettings =
3896 (hidlSession_3_7 != nullptr) ?
3897 captureRequests_3_7[i].v3_4.physicalCameraSettings :
3898 captureRequests_3_4[i].physicalCameraSettings;
3899 physicalCameraSettings.resize(request->num_physcam_settings);
Emilian Peevaebbe412018-01-15 13:53:24 +00003900 for (size_t j = 0; j < request->num_physcam_settings; j++) {
Emilian Peev00420d22018-02-05 21:33:13 +00003901 if (request->physcam_settings != nullptr) {
3902 size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]);
3903 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
3904 reinterpret_cast<const uint8_t*>(request->physcam_settings[j]),
3905 settingsSize)) {
Shuzhen Wang83bff122020-11-20 15:51:39 -08003906 physicalCameraSettings[j].settings.resize(0);
3907 physicalCameraSettings[j].fmqSettingsSize = settingsSize;
Emilian Peev00420d22018-02-05 21:33:13 +00003908 } else {
3909 if (mRequestMetadataQueue != nullptr) {
3910 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
3911 }
Shuzhen Wang83bff122020-11-20 15:51:39 -08003912 physicalCameraSettings[j].settings.setToExternal(
Emilian Peev00420d22018-02-05 21:33:13 +00003913 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(
3914 request->physcam_settings[j])),
3915 get_camera_metadata_size(request->physcam_settings[j]));
Shuzhen Wang83bff122020-11-20 15:51:39 -08003916 physicalCameraSettings[j].fmqSettingsSize = 0u;
Emilian Peevaebbe412018-01-15 13:53:24 +00003917 }
Emilian Peev00420d22018-02-05 21:33:13 +00003918 } else {
Yin-Chia Yeha2849702021-03-10 10:11:33 -08003919 physicalCameraSettings[j].fmqSettingsSize = 0u;
3920 physicalCameraSettings[j].settings.resize(0);
Emilian Peevaebbe412018-01-15 13:53:24 +00003921 }
Shuzhen Wang83bff122020-11-20 15:51:39 -08003922 physicalCameraSettings[j].physicalCameraId = request->physcam_id[j];
Emilian Peevaebbe412018-01-15 13:53:24 +00003923 }
3924 }
Yifan Hongf79b5542017-04-11 14:44:25 -07003925 }
Emilian Peevaebbe412018-01-15 13:53:24 +00003926
3927 hardware::details::return_status err;
Jayant Chowdharyc8d581e2018-07-16 14:46:23 -07003928 auto resultCallback =
3929 [&status, &numRequestProcessed] (auto s, uint32_t n) {
3930 status = s;
3931 *numRequestProcessed = n;
3932 };
Shuzhen Wang83bff122020-11-20 15:51:39 -08003933 if (hidlSession_3_7 != nullptr) {
3934 err = hidlSession_3_7->processCaptureRequest_3_7(captureRequests_3_7, cachesToRemove,
3935 resultCallback);
3936 } else if (hidlSession_3_4 != nullptr) {
Emilian Peevaebbe412018-01-15 13:53:24 +00003937 err = hidlSession_3_4->processCaptureRequest_3_4(captureRequests_3_4, cachesToRemove,
Jayant Chowdharyc8d581e2018-07-16 14:46:23 -07003938 resultCallback);
Emilian Peevaebbe412018-01-15 13:53:24 +00003939 } else {
3940 err = mHidlSession->processCaptureRequest(captureRequests, cachesToRemove,
Jayant Chowdharyc8d581e2018-07-16 14:46:23 -07003941 resultCallback);
Emilian Peevaebbe412018-01-15 13:53:24 +00003942 }
Eino-Ville Talvalac5cbb872017-04-27 12:48:33 -07003943 if (!err.isOk()) {
3944 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003945 status = common::V1_0::Status::CAMERA_DISCONNECTED;
Eino-Ville Talvalac5cbb872017-04-27 12:48:33 -07003946 }
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003947
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003948 if (status == common::V1_0::Status::OK && *numRequestProcessed != batchSize) {
3949 ALOGE("%s: processCaptureRequest returns OK but processed %d/%zu requests",
3950 __FUNCTION__, *numRequestProcessed, batchSize);
3951 status = common::V1_0::Status::INTERNAL_ERROR;
3952 }
3953
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003954 res = CameraProviderManager::mapToStatusT(status);
3955 if (res == OK) {
3956 if (mHidlSession->isRemote()) {
3957 // Only close acquire fence FDs when the HIDL transaction succeeds (so the FDs have been
3958 // sent to camera HAL processes)
3959 cleanupNativeHandles(&handlesCreated, /*closeFd*/true);
3960 } else {
3961 // In passthrough mode the FDs are now owned by HAL
3962 cleanupNativeHandles(&handlesCreated);
3963 }
3964 } else {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08003965 mBufferRecords.popInflightBuffers(inflightBuffers);
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003966 cleanupNativeHandles(&handlesCreated);
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003967 }
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07003968 return res;
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08003969}
3970
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003971status_t Camera3Device::HalInterface::flush() {
3972 ATRACE_NAME("CameraHal::flush");
3973 if (!valid()) return INVALID_OPERATION;
3974 status_t res = OK;
3975
Emilian Peev31abd0a2017-05-11 18:37:46 +01003976 auto err = mHidlSession->flush();
3977 if (!err.isOk()) {
3978 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3979 res = DEAD_OBJECT;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003980 } else {
Emilian Peev31abd0a2017-05-11 18:37:46 +01003981 res = CameraProviderManager::mapToStatusT(err);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003982 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01003983
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003984 return res;
3985}
3986
Emilian Peev31abd0a2017-05-11 18:37:46 +01003987status_t Camera3Device::HalInterface::dump(int /*fd*/) {
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003988 ATRACE_NAME("CameraHal::dump");
3989 if (!valid()) return INVALID_OPERATION;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003990
Emilian Peev31abd0a2017-05-11 18:37:46 +01003991 // Handled by CameraProviderManager::dump
3992
3993 return OK;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08003994}
3995
3996status_t Camera3Device::HalInterface::close() {
3997 ATRACE_NAME("CameraHal::close()");
3998 if (!valid()) return INVALID_OPERATION;
3999 status_t res = OK;
4000
Emilian Peev31abd0a2017-05-11 18:37:46 +01004001 auto err = mHidlSession->close();
4002 // Interface will be dead shortly anyway, so don't log errors
4003 if (!err.isOk()) {
4004 res = DEAD_OBJECT;
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004005 }
Emilian Peev31abd0a2017-05-11 18:37:46 +01004006
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004007 return res;
4008}
4009
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07004010void Camera3Device::HalInterface::signalPipelineDrain(const std::vector<int>& streamIds) {
4011 ATRACE_NAME("CameraHal::signalPipelineDrain");
4012 if (!valid() || mHidlSession_3_5 == nullptr) {
4013 ALOGE("%s called on invalid camera!", __FUNCTION__);
4014 return;
4015 }
4016
Yin-Chia Yehc300a072019-02-13 14:56:57 -08004017 auto err = mHidlSession_3_5->signalStreamFlush(streamIds, mNextStreamConfigCounter - 1);
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07004018 if (!err.isOk()) {
4019 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
4020 return;
4021 }
4022}
4023
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004024status_t Camera3Device::HalInterface::switchToOffline(
4025 const std::vector<int32_t>& streamsToKeep,
4026 /*out*/hardware::camera::device::V3_6::CameraOfflineSessionInfo* offlineSessionInfo,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004027 /*out*/sp<hardware::camera::device::V3_6::ICameraOfflineSession>* offlineSession,
4028 /*out*/camera3::BufferRecords* bufferRecords) {
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004029 ATRACE_NAME("CameraHal::switchToOffline");
4030 if (!valid() || mHidlSession_3_6 == nullptr) {
4031 ALOGE("%s called on invalid camera!", __FUNCTION__);
4032 return INVALID_OPERATION;
4033 }
4034
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004035 if (offlineSessionInfo == nullptr || offlineSession == nullptr || bufferRecords == nullptr) {
4036 ALOGE("%s: output arguments must not be null!", __FUNCTION__);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004037 return INVALID_OPERATION;
4038 }
4039
4040 common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR;
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004041 auto resultCallback =
4042 [&status, &offlineSessionInfo, &offlineSession] (auto s, auto info, auto session) {
4043 status = s;
4044 *offlineSessionInfo = info;
4045 *offlineSession = session;
4046 };
4047 auto err = mHidlSession_3_6->switchToOffline(streamsToKeep, resultCallback);
4048
4049 if (!err.isOk()) {
4050 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
4051 return DEAD_OBJECT;
4052 }
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004053
4054 status_t ret = CameraProviderManager::mapToStatusT(status);
4055 if (ret != OK) {
4056 return ret;
4057 }
4058
4059 // TODO: assert no ongoing requestBuffer/returnBuffer call here
4060 // TODO: update RequestBufferStateMachine to block requestBuffer/returnBuffer once HAL
4061 // returns from switchToOffline.
4062
4063
4064 // Validate buffer caches
4065 std::vector<int32_t> streams;
4066 streams.reserve(offlineSessionInfo->offlineStreams.size());
4067 for (auto offlineStream : offlineSessionInfo->offlineStreams) {
4068 int32_t id = offlineStream.id;
4069 streams.push_back(id);
4070 // Verify buffer caches
4071 std::vector<uint64_t> bufIds(offlineStream.circulatingBufferIds.begin(),
4072 offlineStream.circulatingBufferIds.end());
4073 if (!verifyBufferIds(id, bufIds)) {
4074 ALOGE("%s: stream ID %d buffer cache records mismatch!", __FUNCTION__, id);
4075 return UNKNOWN_ERROR;
4076 }
4077 }
4078
4079 // Move buffer records
4080 bufferRecords->takeBufferCaches(mBufferRecords, streams);
4081 bufferRecords->takeInflightBufferMap(mBufferRecords);
4082 bufferRecords->takeRequestedBufferMap(mBufferRecords);
4083 return ret;
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004084}
4085
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -07004086void Camera3Device::HalInterface::getInflightBufferKeys(
4087 std::vector<std::pair<int32_t, int32_t>>* out) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004088 mBufferRecords.getInflightBufferKeys(out);
Yin-Chia Yehf3fe36f2017-07-07 18:23:18 -07004089 return;
4090}
4091
Yin-Chia Yeh84be5782019-03-01 11:47:02 -08004092void Camera3Device::HalInterface::getInflightRequestBufferKeys(
4093 std::vector<uint64_t>* out) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004094 mBufferRecords.getInflightRequestBufferKeys(out);
Yin-Chia Yeh84be5782019-03-01 11:47:02 -08004095 return;
4096}
4097
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004098bool Camera3Device::HalInterface::verifyBufferIds(
4099 int32_t streamId, std::vector<uint64_t>& bufIds) {
4100 return mBufferRecords.verifyBufferIds(streamId, bufIds);
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004101}
4102
4103status_t Camera3Device::HalInterface::popInflightBuffer(
Yin-Chia Yehf4650602017-01-10 13:13:39 -08004104 int32_t frameNumber, int32_t streamId,
4105 /*out*/ buffer_handle_t **buffer) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004106 return mBufferRecords.popInflightBuffer(frameNumber, streamId, buffer);
Yin-Chia Yehf8e28fb2019-05-16 11:46:54 -07004107}
4108
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07004109status_t Camera3Device::HalInterface::pushInflightRequestBuffer(
Yin-Chia Yeh84be5782019-03-01 11:47:02 -08004110 uint64_t bufferId, buffer_handle_t* buf, int32_t streamId) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004111 return mBufferRecords.pushInflightRequestBuffer(bufferId, buf, streamId);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07004112}
4113
4114// Find and pop a buffer_handle_t based on bufferId
4115status_t Camera3Device::HalInterface::popInflightRequestBuffer(
Yin-Chia Yeh84be5782019-03-01 11:47:02 -08004116 uint64_t bufferId,
4117 /*out*/ buffer_handle_t** buffer,
4118 /*optional out*/ int32_t* streamId) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004119 return mBufferRecords.popInflightRequestBuffer(bufferId, buffer, streamId);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07004120}
4121
Yin-Chia Yeh77327052017-01-09 18:23:07 -08004122std::pair<bool, uint64_t> Camera3Device::HalInterface::getBufferId(
4123 const buffer_handle_t& buf, int streamId) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004124 return mBufferRecords.getBufferId(buf, streamId);
Yin-Chia Yeh77327052017-01-09 18:23:07 -08004125}
4126
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07004127void Camera3Device::HalInterface::onBufferFreed(
4128 int streamId, const native_handle_t* handle) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004129 uint32_t bufferId = mBufferRecords.removeOneBufferCache(streamId, handle);
4130 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
4131 if (bufferId != BUFFER_ID_NO_BUFFER) {
4132 mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07004133 }
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07004134}
4135
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07004136void Camera3Device::HalInterface::onStreamReConfigured(int streamId) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08004137 std::vector<uint64_t> bufIds = mBufferRecords.clearBufferCaches(streamId);
4138 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
4139 for (auto bufferId : bufIds) {
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07004140 mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
4141 }
Yin-Chia Yeh573a2702019-04-17 10:08:55 -07004142}
4143
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004144/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004145 * RequestThread inner class methods
4146 */
4147
4148Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004149 sp<StatusTracker> statusTracker,
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07004150 sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys,
4151 bool useHalBufManager) :
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07004152 Thread(/*canCallJava*/false),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004153 mParent(parent),
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004154 mStatusTracker(statusTracker),
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004155 mInterface(interface),
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07004156 mListener(nullptr),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07004157 mId(getId(parent)),
Shuzhen Wang316781a2020-08-18 18:11:01 -07004158 mFirstRepeating(false),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004159 mReconfigured(false),
4160 mDoPause(false),
4161 mPaused(true),
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07004162 mNotifyPipelineDrain(false),
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004163 mFrameNumber(0),
Jianing Weicb0652e2014-03-12 18:29:36 -07004164 mLatestRequestId(NAME_NOT_FOUND),
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07004165 mCurrentAfTriggerId(0),
4166 mCurrentPreCaptureTriggerId(0),
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08004167 mRotateAndCropOverride(ANDROID_SCALER_ROTATE_AND_CROP_NONE),
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08004168 mCameraMute(false),
4169 mCameraMuteChanged(false),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08004170 mRepeatingLastFrameNumber(
4171 hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES),
Shuzhen Wang686f6442017-06-20 16:16:04 -07004172 mPrepareVideoStream(false),
Emilian Peeva14b4dd2018-05-15 11:00:31 +01004173 mConstrainedMode(false),
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004174 mRequestLatency(kRequestLatencyBinSize),
4175 mSessionParamKeys(sessionParamKeys),
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07004176 mLatestSessionParams(sessionParamKeys.size()),
4177 mUseHalBufManager(useHalBufManager) {
Yin-Chia Yeh87b3ec02019-06-03 10:44:39 -07004178 mStatusId = statusTracker->addComponent("RequestThread");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004179}
4180
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004181Camera3Device::RequestThread::~RequestThread() {}
4182
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07004183void Camera3Device::RequestThread::setNotificationListener(
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07004184 wp<NotificationListener> listener) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004185 ATRACE_CALL();
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004186 Mutex::Autolock l(mRequestLock);
4187 mListener = listener;
4188}
4189
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004190void Camera3Device::RequestThread::configurationComplete(bool isConstrainedHighSpeed,
Shuzhen Wang99080502021-03-07 21:08:20 -08004191 const CameraMetadata& sessionParams,
4192 const std::map<int32_t, std::set<String8>>& groupIdPhysicalCameraMap) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004193 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004194 Mutex::Autolock l(mRequestLock);
4195 mReconfigured = true;
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004196 mLatestSessionParams = sessionParams;
Shuzhen Wang99080502021-03-07 21:08:20 -08004197 mGroupIdPhysicalCameraMap = groupIdPhysicalCameraMap;
Chien-Yu Chenc66969b2016-05-19 16:37:51 -07004198 // Prepare video stream for high speed recording.
4199 mPrepareVideoStream = isConstrainedHighSpeed;
Emilian Peeva14b4dd2018-05-15 11:00:31 +01004200 mConstrainedMode = isConstrainedHighSpeed;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004201}
4202
Jianing Wei90e59c92014-03-12 18:29:36 -07004203status_t Camera3Device::RequestThread::queueRequestList(
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004204 List<sp<CaptureRequest> > &requests,
4205 /*out*/
4206 int64_t *lastFrameNumber) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004207 ATRACE_CALL();
Jianing Wei90e59c92014-03-12 18:29:36 -07004208 Mutex::Autolock l(mRequestLock);
4209 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
4210 ++it) {
4211 mRequestQueue.push_back(*it);
4212 }
4213
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004214 if (lastFrameNumber != NULL) {
4215 *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
4216 ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
4217 __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
4218 *lastFrameNumber);
4219 }
Jianing Weicb0652e2014-03-12 18:29:36 -07004220
Jianing Wei90e59c92014-03-12 18:29:36 -07004221 unpauseForNewRequests();
4222
4223 return OK;
4224}
4225
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004226
4227status_t Camera3Device::RequestThread::queueTrigger(
4228 RequestTrigger trigger[],
4229 size_t count) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004230 ATRACE_CALL();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004231 Mutex::Autolock l(mTriggerMutex);
4232 status_t ret;
4233
4234 for (size_t i = 0; i < count; ++i) {
4235 ret = queueTriggerLocked(trigger[i]);
4236
4237 if (ret != OK) {
4238 return ret;
4239 }
4240 }
4241
4242 return OK;
4243}
4244
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004245const String8& Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
4246 static String8 deadId("<DeadDevice>");
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07004247 sp<Camera3Device> d = device.promote();
Eino-Ville Talvala0b1cb142016-12-19 16:29:17 -08004248 if (d != nullptr) return d->mId;
4249 return deadId;
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07004250}
4251
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004252status_t Camera3Device::RequestThread::queueTriggerLocked(
4253 RequestTrigger trigger) {
4254
4255 uint32_t tag = trigger.metadataTag;
4256 ssize_t index = mTriggerMap.indexOfKey(tag);
4257
4258 switch (trigger.getTagType()) {
4259 case TYPE_BYTE:
4260 // fall-through
4261 case TYPE_INT32:
4262 break;
4263 default:
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07004264 ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
4265 trigger.getTagType());
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004266 return INVALID_OPERATION;
4267 }
4268
4269 /**
4270 * Collect only the latest trigger, since we only have 1 field
4271 * in the request settings per trigger tag, and can't send more than 1
4272 * trigger per request.
4273 */
4274 if (index != NAME_NOT_FOUND) {
4275 mTriggerMap.editValueAt(index) = trigger;
4276 } else {
4277 mTriggerMap.add(tag, trigger);
4278 }
4279
4280 return OK;
4281}
4282
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004283status_t Camera3Device::RequestThread::setRepeatingRequests(
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004284 const RequestList &requests,
4285 /*out*/
4286 int64_t *lastFrameNumber) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004287 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004288 Mutex::Autolock l(mRequestLock);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004289 if (lastFrameNumber != NULL) {
4290 *lastFrameNumber = mRepeatingLastFrameNumber;
4291 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004292 mRepeatingRequests.clear();
Shuzhen Wang316781a2020-08-18 18:11:01 -07004293 mFirstRepeating = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004294 mRepeatingRequests.insert(mRepeatingRequests.begin(),
4295 requests.begin(), requests.end());
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07004296
4297 unpauseForNewRequests();
4298
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08004299 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004300 return OK;
4301}
4302
Chih-Hung Hsieh8b0b9712016-08-09 14:25:53 -07004303bool Camera3Device::RequestThread::isRepeatingRequestLocked(const sp<CaptureRequest>& requestIn) {
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07004304 if (mRepeatingRequests.empty()) {
4305 return false;
4306 }
4307 int32_t requestId = requestIn->mResultExtras.requestId;
4308 const RequestList &repeatRequests = mRepeatingRequests;
4309 // All repeating requests are guaranteed to have same id so only check first quest
4310 const sp<CaptureRequest> firstRequest = *repeatRequests.begin();
4311 return (firstRequest->mResultExtras.requestId == requestId);
4312}
4313
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004314status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004315 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004316 Mutex::Autolock l(mRequestLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004317 return clearRepeatingRequestsLocked(lastFrameNumber);
4318
4319}
4320
4321status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(/*out*/int64_t *lastFrameNumber) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004322 mRepeatingRequests.clear();
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004323 if (lastFrameNumber != NULL) {
4324 *lastFrameNumber = mRepeatingLastFrameNumber;
4325 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08004326 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004327 return OK;
4328}
4329
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004330status_t Camera3Device::RequestThread::clear(
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004331 /*out*/int64_t *lastFrameNumber) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004332 ATRACE_CALL();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07004333 Mutex::Autolock l(mRequestLock);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004334 ALOGV("RequestThread::%s:", __FUNCTION__);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004335
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07004336 mRepeatingRequests.clear();
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07004337
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004338 // Send errors for all requests pending in the request queue, including
4339 // pending repeating requests
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07004340 sp<NotificationListener> listener = mListener.promote();
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004341 if (listener != NULL) {
4342 for (RequestList::iterator it = mRequestQueue.begin();
4343 it != mRequestQueue.end(); ++it) {
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07004344 // Abort the input buffers for reprocess requests.
4345 if ((*it)->mInputStream != NULL) {
Emilian Peevf4816702020-04-03 15:44:51 -07004346 camera_stream_buffer_t inputBuffer;
Shuzhen Wang83bff122020-11-20 15:51:39 -08004347 camera3::Size inputBufferSize;
Eino-Ville Talvalaba435252017-06-21 16:07:25 -07004348 status_t res = (*it)->mInputStream->getInputBuffer(&inputBuffer,
Shuzhen Wang83bff122020-11-20 15:51:39 -08004349 &inputBufferSize, /*respectHalLimit*/ false);
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07004350 if (res != OK) {
4351 ALOGW("%s: %d: couldn't get input buffer while clearing the request "
4352 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
4353 } else {
Emilian Peevf4816702020-04-03 15:44:51 -07004354 inputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07004355 res = (*it)->mInputStream->returnInputBuffer(inputBuffer);
4356 if (res != OK) {
4357 ALOGE("%s: %d: couldn't return input buffer while clearing the request "
4358 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
4359 }
4360 }
4361 }
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004362 // Set the frame number this request would have had, if it
4363 // had been submitted; this frame number will not be reused.
4364 // The requestId and burstId fields were set when the request was
4365 // submitted originally (in convertMetadataListToRequestListLocked)
4366 (*it)->mResultExtras.frameNumber = mFrameNumber++;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08004367 listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
Eino-Ville Talvala17543512014-08-06 14:32:02 -07004368 (*it)->mResultExtras);
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07004369 }
4370 }
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07004371 mRequestQueue.clear();
Jinguang Dongb26e7a02016-11-14 16:04:02 +08004372
4373 Mutex::Autolock al(mTriggerMutex);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07004374 mTriggerMap.clear();
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07004375 if (lastFrameNumber != NULL) {
4376 *lastFrameNumber = mRepeatingLastFrameNumber;
4377 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08004378 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
Emilian Peev8dae54c2019-12-02 15:17:17 -08004379 mRequestSignal.signal();
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07004380 return OK;
4381}
4382
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004383status_t Camera3Device::RequestThread::flush() {
4384 ATRACE_CALL();
4385 Mutex::Autolock l(mFlushLock);
4386
Emilian Peev08dd2452017-04-06 16:55:14 +01004387 return mInterface->flush();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004388}
4389
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004390void Camera3Device::RequestThread::setPaused(bool paused) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004391 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004392 Mutex::Autolock l(mPauseLock);
4393 mDoPause = paused;
4394 mDoPauseSignal.signal();
4395}
4396
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004397status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
4398 int32_t requestId, nsecs_t timeout) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004399 ATRACE_CALL();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004400 Mutex::Autolock l(mLatestRequestMutex);
4401 status_t res;
4402 while (mLatestRequestId != requestId) {
4403 nsecs_t startTime = systemTime();
4404
4405 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
4406 if (res != OK) return res;
4407
4408 timeout -= (systemTime() - startTime);
4409 }
4410
4411 return OK;
4412}
4413
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004414void Camera3Device::RequestThread::requestExit() {
4415 // Call parent to set up shutdown
4416 Thread::requestExit();
4417 // The exit from any possible waits
4418 mDoPauseSignal.signal();
4419 mRequestSignal.signal();
Shuzhen Wang686f6442017-06-20 16:16:04 -07004420
4421 mRequestLatency.log("ProcessCaptureRequest latency histogram");
4422 mRequestLatency.reset();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004423}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004424
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004425void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004426 ATRACE_CALL();
Yin-Chia Yeh473fad92016-05-23 15:54:41 -07004427 bool surfaceAbandoned = false;
4428 int64_t lastFrameNumber = 0;
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07004429 sp<NotificationListener> listener;
Yin-Chia Yeh473fad92016-05-23 15:54:41 -07004430 {
4431 Mutex::Autolock l(mRequestLock);
4432 // Check all streams needed by repeating requests are still valid. Otherwise, stop
4433 // repeating requests.
4434 for (const auto& request : mRepeatingRequests) {
4435 for (const auto& s : request->mOutputStreams) {
4436 if (s->isAbandoned()) {
4437 surfaceAbandoned = true;
4438 clearRepeatingRequestsLocked(&lastFrameNumber);
4439 break;
4440 }
4441 }
4442 if (surfaceAbandoned) {
4443 break;
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004444 }
4445 }
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07004446 listener = mListener.promote();
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004447 }
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07004448
4449 if (listener != NULL && surfaceAbandoned) {
4450 listener->notifyRepeatingRequestError(lastFrameNumber);
Yin-Chia Yeh473fad92016-05-23 15:54:41 -07004451 }
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004452}
4453
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004454bool Camera3Device::RequestThread::sendRequestsBatch() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07004455 ATRACE_CALL();
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004456 status_t res;
4457 size_t batchSize = mNextRequests.size();
Emilian Peevf4816702020-04-03 15:44:51 -07004458 std::vector<camera_capture_request_t*> requests(batchSize);
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004459 uint32_t numRequestProcessed = 0;
4460 for (size_t i = 0; i < batchSize; i++) {
4461 requests[i] = &mNextRequests.editItemAt(i).halRequest;
Yin-Chia Yeh885691c2018-05-01 15:54:24 -07004462 ATRACE_ASYNC_BEGIN("frame capture", mNextRequests[i].halRequest.frame_number);
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004463 }
4464
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004465 res = mInterface->processBatchCaptureRequests(requests, &numRequestProcessed);
4466
4467 bool triggerRemoveFailed = false;
4468 NextRequest& triggerFailedRequest = mNextRequests.editItemAt(0);
4469 for (size_t i = 0; i < numRequestProcessed; i++) {
4470 NextRequest& nextRequest = mNextRequests.editItemAt(i);
4471 nextRequest.submitted = true;
4472
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004473 updateNextRequest(nextRequest);
Emilian Peevaebbe412018-01-15 13:53:24 +00004474
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004475 if (!triggerRemoveFailed) {
4476 // Remove any previously queued triggers (after unlock)
4477 status_t removeTriggerRes = removeTriggers(mPrevRequest);
4478 if (removeTriggerRes != OK) {
4479 triggerRemoveFailed = true;
4480 triggerFailedRequest = nextRequest;
4481 }
4482 }
4483 }
4484
4485 if (triggerRemoveFailed) {
4486 SET_ERR("RequestThread: Unable to remove triggers "
4487 "(capture request %d, HAL device: %s (%d)",
4488 triggerFailedRequest.halRequest.frame_number, strerror(-res), res);
4489 cleanUpFailedRequests(/*sendRequestError*/ false);
4490 return false;
4491 }
4492
4493 if (res != OK) {
4494 // Should only get a failure here for malformed requests or device-level
4495 // errors, so consider all errors fatal. Bad metadata failures should
4496 // come through notify.
4497 SET_ERR("RequestThread: Unable to submit capture request %d to HAL device: %s (%d)",
4498 mNextRequests[numRequestProcessed].halRequest.frame_number,
4499 strerror(-res), res);
4500 cleanUpFailedRequests(/*sendRequestError*/ false);
4501 return false;
4502 }
4503 return true;
4504}
4505
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07004506nsecs_t Camera3Device::RequestThread::calculateMaxExpectedDuration(const camera_metadata_t *request) {
4507 nsecs_t maxExpectedDuration = kDefaultExpectedDuration;
4508 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
4509 find_camera_metadata_ro_entry(request,
4510 ANDROID_CONTROL_AE_MODE,
4511 &e);
4512 if (e.count == 0) return maxExpectedDuration;
4513
4514 switch (e.data.u8[0]) {
4515 case ANDROID_CONTROL_AE_MODE_OFF:
4516 find_camera_metadata_ro_entry(request,
4517 ANDROID_SENSOR_EXPOSURE_TIME,
4518 &e);
4519 if (e.count > 0) {
4520 maxExpectedDuration = e.data.i64[0];
4521 }
4522 find_camera_metadata_ro_entry(request,
4523 ANDROID_SENSOR_FRAME_DURATION,
4524 &e);
4525 if (e.count > 0) {
4526 maxExpectedDuration = std::max(e.data.i64[0], maxExpectedDuration);
4527 }
4528 break;
4529 default:
4530 find_camera_metadata_ro_entry(request,
4531 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
4532 &e);
4533 if (e.count > 1) {
4534 maxExpectedDuration = 1e9 / e.data.u8[0];
4535 }
4536 break;
4537 }
4538
4539 return maxExpectedDuration;
4540}
4541
Emilian Peeva14b4dd2018-05-15 11:00:31 +01004542bool Camera3Device::RequestThread::skipHFRTargetFPSUpdate(int32_t tag,
4543 const camera_metadata_ro_entry_t& newEntry, const camera_metadata_entry_t& currentEntry) {
4544 if (mConstrainedMode && (ANDROID_CONTROL_AE_TARGET_FPS_RANGE == tag) &&
4545 (newEntry.count == currentEntry.count) && (currentEntry.count == 2) &&
4546 (currentEntry.data.i32[1] == newEntry.data.i32[1])) {
4547 return true;
4548 }
4549
4550 return false;
4551}
4552
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004553void Camera3Device::RequestThread::updateNextRequest(NextRequest& nextRequest) {
4554 // Update the latest request sent to HAL
Shuzhen Wang83bff122020-11-20 15:51:39 -08004555 camera_capture_request_t& halRequest = nextRequest.halRequest;
4556 if (halRequest.settings != NULL) { // Don't update if they were unchanged
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004557 Mutex::Autolock al(mLatestRequestMutex);
4558
Shuzhen Wang83bff122020-11-20 15:51:39 -08004559 camera_metadata_t* cloned = clone_camera_metadata(halRequest.settings);
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004560 mLatestRequest.acquire(cloned);
4561
4562 mLatestPhysicalRequest.clear();
Shuzhen Wang83bff122020-11-20 15:51:39 -08004563 for (uint32_t i = 0; i < halRequest.num_physcam_settings; i++) {
4564 cloned = clone_camera_metadata(halRequest.physcam_settings[i]);
4565 mLatestPhysicalRequest.emplace(halRequest.physcam_id[i],
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004566 CameraMetadata(cloned));
4567 }
4568
4569 sp<Camera3Device> parent = mParent.promote();
4570 if (parent != NULL) {
4571 parent->monitorMetadata(TagMonitor::REQUEST,
Shuzhen Wang83bff122020-11-20 15:51:39 -08004572 halRequest.frame_number,
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004573 0, mLatestRequest, mLatestPhysicalRequest);
4574 }
4575 }
4576
Shuzhen Wang83bff122020-11-20 15:51:39 -08004577 if (halRequest.settings != NULL) {
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004578 nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock(
Shuzhen Wang83bff122020-11-20 15:51:39 -08004579 halRequest.settings);
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004580 }
4581
Shuzhen Wang83bff122020-11-20 15:51:39 -08004582 cleanupPhysicalSettings(nextRequest.captureRequest, &halRequest);
Shuzhen Wangc2cba122018-05-17 18:10:24 -07004583}
4584
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004585bool Camera3Device::RequestThread::updateSessionParameters(const CameraMetadata& settings) {
4586 ATRACE_CALL();
4587 bool updatesDetected = false;
4588
Emilian Peev4ec17882019-01-24 17:16:58 -08004589 CameraMetadata updatedParams(mLatestSessionParams);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004590 for (auto tag : mSessionParamKeys) {
4591 camera_metadata_ro_entry entry = settings.find(tag);
Emilian Peev4ec17882019-01-24 17:16:58 -08004592 camera_metadata_entry lastEntry = updatedParams.find(tag);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004593
4594 if (entry.count > 0) {
4595 bool isDifferent = false;
4596 if (lastEntry.count > 0) {
4597 // Have a last value, compare to see if changed
4598 if (lastEntry.type == entry.type &&
4599 lastEntry.count == entry.count) {
4600 // Same type and count, compare values
4601 size_t bytesPerValue = camera_metadata_type_size[lastEntry.type];
4602 size_t entryBytes = bytesPerValue * lastEntry.count;
4603 int cmp = memcmp(entry.data.u8, lastEntry.data.u8, entryBytes);
4604 if (cmp != 0) {
4605 isDifferent = true;
4606 }
4607 } else {
4608 // Count or type has changed
4609 isDifferent = true;
4610 }
4611 } else {
4612 // No last entry, so always consider to be different
4613 isDifferent = true;
4614 }
4615
4616 if (isDifferent) {
4617 ALOGV("%s: Session parameter tag id %d changed", __FUNCTION__, tag);
Emilian Peeva14b4dd2018-05-15 11:00:31 +01004618 if (!skipHFRTargetFPSUpdate(tag, entry, lastEntry)) {
4619 updatesDetected = true;
4620 }
Emilian Peev4ec17882019-01-24 17:16:58 -08004621 updatedParams.update(entry);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004622 }
4623 } else if (lastEntry.count > 0) {
4624 // Value has been removed
4625 ALOGV("%s: Session parameter tag id %d removed", __FUNCTION__, tag);
Emilian Peev4ec17882019-01-24 17:16:58 -08004626 updatedParams.erase(tag);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004627 updatesDetected = true;
4628 }
4629 }
4630
Emilian Peev4ec17882019-01-24 17:16:58 -08004631 bool reconfigureRequired;
4632 if (updatesDetected) {
4633 reconfigureRequired = mInterface->isReconfigurationRequired(mLatestSessionParams,
4634 updatedParams);
4635 mLatestSessionParams = updatedParams;
4636 } else {
4637 reconfigureRequired = false;
4638 }
4639
4640 return reconfigureRequired;
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004641}
4642
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004643bool Camera3Device::RequestThread::threadLoop() {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004644 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004645 status_t res;
Jayant Chowdhary37eca242019-11-18 08:55:56 -08004646 // Any function called from threadLoop() must not hold mInterfaceLock since
4647 // it could lead to deadlocks (disconnect() -> hold mInterfaceMutex -> wait for request thread
4648 // to finish -> request thread waits on mInterfaceMutex) http://b/143513518
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004649
4650 // Handle paused state.
4651 if (waitIfPaused()) {
4652 return true;
4653 }
4654
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004655 // Wait for the next batch of requests.
4656 waitForNextRequestBatch();
4657 if (mNextRequests.size() == 0) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004658 return true;
4659 }
4660
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004661 // Get the latest request ID, if any
4662 int latestRequestId;
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004663 camera_metadata_entry_t requestIdEntry = mNextRequests[mNextRequests.size() - 1].
Emilian Peevaebbe412018-01-15 13:53:24 +00004664 captureRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_ID);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004665 if (requestIdEntry.count > 0) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004666 latestRequestId = requestIdEntry.data.i32[0];
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004667 } else {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004668 ALOGW("%s: Did not have android.request.id set in the request.", __FUNCTION__);
4669 latestRequestId = NAME_NOT_FOUND;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07004670 }
4671
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004672 // 'mNextRequests' will at this point contain either a set of HFR batched requests
4673 // or a single request from streaming or burst. In either case the first element
4674 // should contain the latest camera settings that we need to check for any session
4675 // parameter updates.
Emilian Peevaebbe412018-01-15 13:53:24 +00004676 if (updateSessionParameters(mNextRequests[0].captureRequest->mSettingsList.begin()->metadata)) {
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004677 res = OK;
4678
4679 //Input stream buffers are already acquired at this point so an input stream
4680 //will not be able to move to idle state unless we force it.
4681 if (mNextRequests[0].captureRequest->mInputStream != nullptr) {
4682 res = mNextRequests[0].captureRequest->mInputStream->forceToIdle();
4683 if (res != OK) {
4684 ALOGE("%s: Failed to force idle input stream: %d", __FUNCTION__, res);
4685 cleanUpFailedRequests(/*sendRequestError*/ false);
4686 return false;
4687 }
4688 }
4689
4690 if (res == OK) {
Emilian Peev3bead5f2020-05-28 17:29:08 -07004691 sp<Camera3Device> parent = mParent.promote();
4692 if (parent != nullptr) {
4693 mReconfigured |= parent->reconfigureCamera(mLatestSessionParams, mStatusId);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004694 }
Emilian Peev3bead5f2020-05-28 17:29:08 -07004695 setPaused(false);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00004696
4697 if (mNextRequests[0].captureRequest->mInputStream != nullptr) {
4698 mNextRequests[0].captureRequest->mInputStream->restoreConfiguredState();
4699 if (res != OK) {
4700 ALOGE("%s: Failed to restore configured input stream: %d", __FUNCTION__, res);
4701 cleanUpFailedRequests(/*sendRequestError*/ false);
4702 return false;
4703 }
4704 }
4705 }
4706 }
4707
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004708 // Prepare a batch of HAL requests and output buffers.
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004709 res = prepareHalRequests();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004710 if (res == TIMED_OUT) {
4711 // Not a fatal error if getting output buffers time out.
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004712 cleanUpFailedRequests(/*sendRequestError*/ true);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07004713 // Check if any stream is abandoned.
4714 checkAndStopRepeatingRequest();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004715 return true;
4716 } else if (res != OK) {
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004717 cleanUpFailedRequests(/*sendRequestError*/ false);
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07004718 return false;
4719 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004720
Zhijun Hecc27e112013-10-03 16:12:43 -07004721 // Inform waitUntilRequestProcessed thread of a new request ID
4722 {
4723 Mutex::Autolock al(mLatestRequestMutex);
4724
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004725 mLatestRequestId = latestRequestId;
Zhijun Hecc27e112013-10-03 16:12:43 -07004726 mLatestRequestSignal.signal();
4727 }
4728
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004729 // Submit a batch of requests to HAL.
4730 // Use flush lock only when submitting multilple requests in a batch.
4731 // TODO: The problem with flush lock is flush() will be blocked by process_capture_request()
4732 // which may take a long time to finish so synchronizing flush() and
4733 // process_capture_request() defeats the purpose of cancelling requests ASAP with flush().
4734 // For now, only synchronize for high speed recording and we should figure something out for
4735 // removing the synchronization.
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004736 bool useFlushLock = mNextRequests.size() > 1;
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07004737
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004738 if (useFlushLock) {
4739 mFlushLock.lock();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004740 }
4741
Zhijun Hef0645c12016-08-02 00:58:11 -07004742 ALOGVV("%s: %d: submitting %zu requests in a batch.", __FUNCTION__, __LINE__,
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004743 mNextRequests.size());
Igor Murashkin1e479c02013-09-06 16:55:14 -07004744
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -08004745 sp<Camera3Device> parent = mParent.promote();
4746 if (parent != nullptr) {
4747 parent->mRequestBufferSM.onSubmittingRequest();
4748 }
4749
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004750 bool submitRequestSuccess = false;
Shuzhen Wang686f6442017-06-20 16:16:04 -07004751 nsecs_t tRequestStart = systemTime(SYSTEM_TIME_MONOTONIC);
Yin-Chia Yeh11648852019-05-16 10:42:54 -07004752 submitRequestSuccess = sendRequestsBatch();
4753
Shuzhen Wang686f6442017-06-20 16:16:04 -07004754 nsecs_t tRequestEnd = systemTime(SYSTEM_TIME_MONOTONIC);
4755 mRequestLatency.add(tRequestStart, tRequestEnd);
Igor Murashkin1e479c02013-09-06 16:55:14 -07004756
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004757 if (useFlushLock) {
4758 mFlushLock.unlock();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004759 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07004760
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07004761 // Unset as current request
4762 {
4763 Mutex::Autolock l(mRequestLock);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004764 mNextRequests.clear();
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07004765 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07004766 mRequestSubmittedSignal.signal();
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07004767
Yin-Chia Yeh94c68e02017-03-06 14:09:44 -08004768 return submitRequestSuccess;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08004769}
4770
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07004771status_t Camera3Device::RequestThread::prepareHalRequests() {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004772 ATRACE_CALL();
4773
Yin-Chia Yehd07b11e2018-06-01 12:50:02 -07004774 bool batchedRequest = mNextRequests[0].captureRequest->mBatchSize > 1;
Shuzhen Wang4a472662017-02-26 23:29:04 -08004775 for (size_t i = 0; i < mNextRequests.size(); i++) {
4776 auto& nextRequest = mNextRequests.editItemAt(i);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004777 sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
Emilian Peevf4816702020-04-03 15:44:51 -07004778 camera_capture_request_t* halRequest = &nextRequest.halRequest;
4779 Vector<camera_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004780
4781 // Prepare a request to HAL
4782 halRequest->frame_number = captureRequest->mResultExtras.frameNumber;
4783
4784 // Insert any queued triggers (before metadata is locked)
4785 status_t res = insertTriggers(captureRequest);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004786 if (res < 0) {
4787 SET_ERR("RequestThread: Unable to insert triggers "
4788 "(capture request %d, HAL device: %s (%d)",
4789 halRequest->frame_number, strerror(-res), res);
4790 return INVALID_OPERATION;
4791 }
Eino-Ville Talvala7b8a1fd2018-05-22 15:30:35 -07004792
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004793 int triggerCount = res;
4794 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
4795 mPrevTriggers = triggerCount;
4796
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08004797 bool rotateAndCropChanged = overrideAutoRotateAndCrop(captureRequest);
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08004798 bool testPatternChanged = overrideTestPattern(captureRequest);
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08004799
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08004800 // If the request is the same as last, or we had triggers now or last time or
4801 // changing overrides this time
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08004802 bool newRequest =
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08004803 (mPrevRequest != captureRequest || triggersMixedIn ||
4804 rotateAndCropChanged || testPatternChanged) &&
Yin-Chia Yehd07b11e2018-06-01 12:50:02 -07004805 // Request settings are all the same within one batch, so only treat the first
4806 // request in a batch as new
Zhijun He54c36822018-07-18 09:33:39 -07004807 !(batchedRequest && i > 0);
Emilian Peev00420d22018-02-05 21:33:13 +00004808 if (newRequest) {
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08004809 std::set<std::string> cameraIdsWithZoom;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004810 /**
4811 * HAL workaround:
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04004812 * Insert a fake trigger ID if a trigger is set but no trigger ID is
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004813 */
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04004814 res = addFakeTriggerIds(captureRequest);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004815 if (res != OK) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04004816 SET_ERR("RequestThread: Unable to insert fake trigger IDs "
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004817 "(capture request %d, HAL device: %s (%d)",
4818 halRequest->frame_number, strerror(-res), res);
4819 return INVALID_OPERATION;
4820 }
4821
Eino-Ville Talvala7b8a1fd2018-05-22 15:30:35 -07004822 {
4823 // Correct metadata regions for distortion correction if enabled
4824 sp<Camera3Device> parent = mParent.promote();
4825 if (parent != nullptr) {
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -07004826 List<PhysicalCameraSettings>::iterator it;
4827 for (it = captureRequest->mSettingsList.begin();
4828 it != captureRequest->mSettingsList.end(); it++) {
4829 if (parent->mDistortionMappers.find(it->cameraId) ==
4830 parent->mDistortionMappers.end()) {
4831 continue;
4832 }
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07004833
4834 if (!captureRequest->mDistortionCorrectionUpdated) {
4835 res = parent->mDistortionMappers[it->cameraId].correctCaptureRequest(
4836 &(it->metadata));
4837 if (res != OK) {
4838 SET_ERR("RequestThread: Unable to correct capture requests "
4839 "for lens distortion for request %d: %s (%d)",
4840 halRequest->frame_number, strerror(-res), res);
4841 return INVALID_OPERATION;
4842 }
4843 captureRequest->mDistortionCorrectionUpdated = true;
Shuzhen Wang4f6fa9d2019-03-29 10:40:35 -07004844 }
Eino-Ville Talvala7b8a1fd2018-05-22 15:30:35 -07004845 }
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08004846
4847 for (it = captureRequest->mSettingsList.begin();
4848 it != captureRequest->mSettingsList.end(); it++) {
4849 if (parent->mZoomRatioMappers.find(it->cameraId) ==
4850 parent->mZoomRatioMappers.end()) {
4851 continue;
4852 }
4853
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07004854 if (!captureRequest->mZoomRatioIs1x) {
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08004855 cameraIdsWithZoom.insert(it->cameraId);
4856 }
4857
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07004858 if (!captureRequest->mZoomRatioUpdated) {
4859 res = parent->mZoomRatioMappers[it->cameraId].updateCaptureRequest(
4860 &(it->metadata));
4861 if (res != OK) {
4862 SET_ERR("RequestThread: Unable to correct capture requests "
4863 "for zoom ratio for request %d: %s (%d)",
4864 halRequest->frame_number, strerror(-res), res);
4865 return INVALID_OPERATION;
4866 }
4867 captureRequest->mZoomRatioUpdated = true;
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08004868 }
4869 }
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07004870 if (captureRequest->mRotateAndCropAuto &&
4871 !captureRequest->mRotationAndCropUpdated) {
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08004872 for (it = captureRequest->mSettingsList.begin();
4873 it != captureRequest->mSettingsList.end(); it++) {
4874 auto mapper = parent->mRotateAndCropMappers.find(it->cameraId);
4875 if (mapper != parent->mRotateAndCropMappers.end()) {
4876 res = mapper->second.updateCaptureRequest(&(it->metadata));
4877 if (res != OK) {
4878 SET_ERR("RequestThread: Unable to correct capture requests "
4879 "for rotate-and-crop for request %d: %s (%d)",
4880 halRequest->frame_number, strerror(-res), res);
4881 return INVALID_OPERATION;
4882 }
4883 }
4884 }
Shuzhen Wangd1d051a2020-08-20 15:42:23 -07004885 captureRequest->mRotationAndCropUpdated = true;
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08004886 }
Eino-Ville Talvala7b8a1fd2018-05-22 15:30:35 -07004887 }
4888 }
4889
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004890 /**
4891 * The request should be presorted so accesses in HAL
4892 * are O(logn). Sidenote, sorting a sorted metadata is nop.
4893 */
Emilian Peevaebbe412018-01-15 13:53:24 +00004894 captureRequest->mSettingsList.begin()->metadata.sort();
4895 halRequest->settings = captureRequest->mSettingsList.begin()->metadata.getAndLock();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004896 mPrevRequest = captureRequest;
Shuzhen Wangdbdf72b2019-11-13 11:22:12 -08004897 mPrevCameraIdsWithZoom = cameraIdsWithZoom;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004898 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
4899
4900 IF_ALOGV() {
4901 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
4902 find_camera_metadata_ro_entry(
4903 halRequest->settings,
4904 ANDROID_CONTROL_AF_TRIGGER,
4905 &e
4906 );
4907 if (e.count > 0) {
4908 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
4909 __FUNCTION__,
4910 halRequest->frame_number,
4911 e.data.u8[0]);
4912 }
4913 }
4914 } else {
4915 // leave request.settings NULL to indicate 'reuse latest given'
4916 ALOGVV("%s: Request settings are REUSED",
4917 __FUNCTION__);
4918 }
4919
Emilian Peevaebbe412018-01-15 13:53:24 +00004920 if (captureRequest->mSettingsList.size() > 1) {
4921 halRequest->num_physcam_settings = captureRequest->mSettingsList.size() - 1;
4922 halRequest->physcam_id = new const char* [halRequest->num_physcam_settings];
Emilian Peev00420d22018-02-05 21:33:13 +00004923 if (newRequest) {
4924 halRequest->physcam_settings =
4925 new const camera_metadata* [halRequest->num_physcam_settings];
4926 } else {
4927 halRequest->physcam_settings = nullptr;
4928 }
Emilian Peevaebbe412018-01-15 13:53:24 +00004929 auto it = ++captureRequest->mSettingsList.begin();
4930 size_t i = 0;
4931 for (; it != captureRequest->mSettingsList.end(); it++, i++) {
4932 halRequest->physcam_id[i] = it->cameraId.c_str();
Emilian Peev00420d22018-02-05 21:33:13 +00004933 if (newRequest) {
4934 it->metadata.sort();
4935 halRequest->physcam_settings[i] = it->metadata.getAndLock();
4936 }
Emilian Peevaebbe412018-01-15 13:53:24 +00004937 }
4938 }
4939
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004940 uint32_t totalNumBuffers = 0;
4941
4942 // Fill in buffers
4943 if (captureRequest->mInputStream != NULL) {
4944 halRequest->input_buffer = &captureRequest->mInputBuffer;
Shuzhen Wang83bff122020-11-20 15:51:39 -08004945
4946 halRequest->input_width = captureRequest->mInputBufferSize.width;
4947 halRequest->input_height = captureRequest->mInputBufferSize.height;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004948 totalNumBuffers += 1;
4949 } else {
4950 halRequest->input_buffer = NULL;
4951 }
4952
Emilian Peevf4816702020-04-03 15:44:51 -07004953 outputBuffers->insertAt(camera_stream_buffer_t(), 0,
Chien-Yu Chen85a64552015-08-28 15:46:12 -07004954 captureRequest->mOutputStreams.size());
4955 halRequest->output_buffers = outputBuffers->array();
Shuzhen Wang99080502021-03-07 21:08:20 -08004956 std::set<std::set<String8>> requestedPhysicalCameras;
Yin-Chia Yehb3a80b12018-09-04 12:13:05 -07004957
4958 sp<Camera3Device> parent = mParent.promote();
4959 if (parent == NULL) {
4960 // Should not happen, and nowhere to send errors to, so just log it
4961 CLOGE("RequestThread: Parent is gone");
4962 return INVALID_OPERATION;
4963 }
4964 nsecs_t waitDuration = kBaseGetBufferWait + parent->getExpectedInFlightDuration();
4965
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07004966 SurfaceMap uniqueSurfaceIdMap;
Shuzhen Wang4a472662017-02-26 23:29:04 -08004967 for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) {
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07004968 sp<Camera3OutputStreamInterface> outputStream =
4969 captureRequest->mOutputStreams.editItemAt(j);
4970 int streamId = outputStream->getId();
Chien-Yu Chenc66969b2016-05-19 16:37:51 -07004971
4972 // Prepare video buffers for high speed recording on the first video request.
4973 if (mPrepareVideoStream && outputStream->isVideoStream()) {
4974 // Only try to prepare video stream on the first video request.
4975 mPrepareVideoStream = false;
4976
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -07004977 res = outputStream->startPrepare(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX,
4978 false /*blockRequest*/);
Chien-Yu Chenc66969b2016-05-19 16:37:51 -07004979 while (res == NOT_ENOUGH_DATA) {
4980 res = outputStream->prepareNextBuffer();
4981 }
4982 if (res != OK) {
4983 ALOGW("%s: Preparing video buffers for high speed failed: %s (%d)",
4984 __FUNCTION__, strerror(-res), res);
4985 outputStream->cancelPrepare();
4986 }
4987 }
4988
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07004989 std::vector<size_t> uniqueSurfaceIds;
4990 res = outputStream->getUniqueSurfaceIds(
4991 captureRequest->mOutputSurfaces[streamId],
4992 &uniqueSurfaceIds);
4993 // INVALID_OPERATION is normal output for streams not supporting surfaceIds
4994 if (res != OK && res != INVALID_OPERATION) {
4995 ALOGE("%s: failed to query stream %d unique surface IDs",
4996 __FUNCTION__, streamId);
4997 return res;
4998 }
4999 if (res == OK) {
5000 uniqueSurfaceIdMap.insert({streamId, std::move(uniqueSurfaceIds)});
5001 }
5002
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005003 if (mUseHalBufManager) {
Yin-Chia Yeh110342b2018-11-19 11:47:46 -08005004 if (outputStream->isAbandoned()) {
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -07005005 ALOGV("%s: stream %d is abandoned, skipping request", __FUNCTION__, streamId);
Yin-Chia Yeh110342b2018-11-19 11:47:46 -08005006 return TIMED_OUT;
5007 }
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005008 // HAL will request buffer through requestStreamBuffer API
Emilian Peevf4816702020-04-03 15:44:51 -07005009 camera_stream_buffer_t& buffer = outputBuffers->editItemAt(j);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005010 buffer.stream = outputStream->asHalStream();
5011 buffer.buffer = nullptr;
Emilian Peevf4816702020-04-03 15:44:51 -07005012 buffer.status = CAMERA_BUFFER_STATUS_OK;
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005013 buffer.acquire_fence = -1;
5014 buffer.release_fence = -1;
Emilian Peevf0348ae2021-01-13 13:39:45 -08005015 // Mark the output stream as unpreparable to block clients from calling
5016 // 'prepare' after this request reaches CameraHal and before the respective
5017 // buffers are requested.
5018 outputStream->markUnpreparable();
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005019 } else {
5020 res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
5021 waitDuration,
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07005022 captureRequest->mOutputSurfaces[streamId]);
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005023 if (res != OK) {
5024 // Can't get output buffer from gralloc queue - this could be due to
5025 // abandoned queue or other consumer misbehavior, so not a fatal
5026 // error
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -07005027 ALOGV("RequestThread: Can't get output buffer, skipping request:"
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -07005028 " %s (%d)", strerror(-res), res);
5029
5030 return TIMED_OUT;
5031 }
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005032 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08005033
5034 {
5035 sp<Camera3Device> parent = mParent.promote();
5036 if (parent != nullptr) {
5037 const String8& streamCameraId = outputStream->getPhysicalCameraId();
5038 for (const auto& settings : captureRequest->mSettingsList) {
5039 if ((streamCameraId.isEmpty() &&
5040 parent->getId() == settings.cameraId.c_str()) ||
5041 streamCameraId == settings.cameraId.c_str()) {
5042 outputStream->fireBufferRequestForFrameNumber(
5043 captureRequest->mResultExtras.frameNumber,
5044 settings.metadata);
5045 }
5046 }
5047 }
5048 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07005049
Shuzhen Wang5c22c152017-12-31 17:12:25 -08005050 String8 physicalCameraId = outputStream->getPhysicalCameraId();
Shuzhen Wang99080502021-03-07 21:08:20 -08005051 int32_t streamGroupId = outputStream->getHalStreamGroupId();
5052 if (streamGroupId != -1 && mGroupIdPhysicalCameraMap.count(streamGroupId) == 1) {
5053 requestedPhysicalCameras.insert(mGroupIdPhysicalCameraMap[streamGroupId]);
5054 } else if (!physicalCameraId.isEmpty()) {
5055 requestedPhysicalCameras.insert(std::set<String8>({physicalCameraId}));
Shuzhen Wang5c22c152017-12-31 17:12:25 -08005056 }
5057 halRequest->num_output_buffers++;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005058 }
5059 totalNumBuffers += halRequest->num_output_buffers;
5060
5061 // Log request in the in-flight queue
Shuzhen Wang4a472662017-02-26 23:29:04 -08005062 // If this request list is for constrained high speed recording (not
5063 // preview), and the current request is not the last one in the batch,
5064 // do not send callback to the app.
5065 bool hasCallback = true;
Yin-Chia Yehd07b11e2018-06-01 12:50:02 -07005066 if (batchedRequest && i != mNextRequests.size()-1) {
Shuzhen Wang4a472662017-02-26 23:29:04 -08005067 hasCallback = false;
5068 }
Emilian Peev9dd21f42018-08-03 13:39:29 +01005069 bool isStillCapture = false;
Shuzhen Wang26abaf42018-08-28 15:41:20 -07005070 bool isZslCapture = false;
Yin-Chia Yehf7057ca2020-11-16 14:11:40 -08005071 const camera_metadata_t* settings = halRequest->settings;
5072 bool shouldUnlockSettings = false;
5073 if (settings == nullptr) {
5074 shouldUnlockSettings = true;
5075 settings = captureRequest->mSettingsList.begin()->metadata.getAndLock();
5076 }
Emilian Peev9dd21f42018-08-03 13:39:29 +01005077 if (!mNextRequests[0].captureRequest->mSettingsList.begin()->metadata.isEmpty()) {
5078 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
Yin-Chia Yehf7057ca2020-11-16 14:11:40 -08005079 find_camera_metadata_ro_entry(settings, ANDROID_CONTROL_CAPTURE_INTENT, &e);
Emilian Peev9dd21f42018-08-03 13:39:29 +01005080 if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE)) {
5081 isStillCapture = true;
5082 ATRACE_ASYNC_BEGIN("still capture", mNextRequests[i].halRequest.frame_number);
5083 }
Shuzhen Wang26abaf42018-08-28 15:41:20 -07005084
Emilian Peevaf8416e2021-02-04 17:52:43 -08005085 e = camera_metadata_ro_entry_t();
Yin-Chia Yehf7057ca2020-11-16 14:11:40 -08005086 find_camera_metadata_ro_entry(settings, ANDROID_CONTROL_ENABLE_ZSL, &e);
Shuzhen Wang26abaf42018-08-28 15:41:20 -07005087 if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_ENABLE_ZSL_TRUE)) {
5088 isZslCapture = true;
5089 }
Emilian Peev9dd21f42018-08-03 13:39:29 +01005090 }
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005091 res = parent->registerInFlight(halRequest->frame_number,
5092 totalNumBuffers, captureRequest->mResultExtras,
5093 /*hasInput*/halRequest->input_buffer != NULL,
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07005094 hasCallback,
Yin-Chia Yehf7057ca2020-11-16 14:11:40 -08005095 calculateMaxExpectedDuration(settings),
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08005096 requestedPhysicalCameras, isStillCapture, isZslCapture,
5097 captureRequest->mRotateAndCropAuto, mPrevCameraIdsWithZoom,
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07005098 (mUseHalBufManager) ? uniqueSurfaceIdMap :
Shuzhen Wang316781a2020-08-18 18:11:01 -07005099 SurfaceMap{}, captureRequest->mRequestTimeNs);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005100 ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
5101 ", burstId = %" PRId32 ".",
5102 __FUNCTION__,
5103 captureRequest->mResultExtras.requestId, captureRequest->mResultExtras.frameNumber,
5104 captureRequest->mResultExtras.burstId);
Yin-Chia Yehf7057ca2020-11-16 14:11:40 -08005105
5106 if (shouldUnlockSettings) {
5107 captureRequest->mSettingsList.begin()->metadata.unlock(settings);
5108 }
5109
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005110 if (res != OK) {
5111 SET_ERR("RequestThread: Unable to register new in-flight request:"
5112 " %s (%d)", strerror(-res), res);
5113 return INVALID_OPERATION;
5114 }
5115 }
5116
5117 return OK;
5118}
5119
Igor Murashkin1e479c02013-09-06 16:55:14 -07005120CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005121 ATRACE_CALL();
Igor Murashkin1e479c02013-09-06 16:55:14 -07005122 Mutex::Autolock al(mLatestRequestMutex);
5123
5124 ALOGV("RequestThread::%s", __FUNCTION__);
5125
5126 return mLatestRequest;
5127}
5128
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005129bool Camera3Device::RequestThread::isStreamPending(
5130 sp<Camera3StreamInterface>& stream) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005131 ATRACE_CALL();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005132 Mutex::Autolock l(mRequestLock);
5133
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005134 for (const auto& nextRequest : mNextRequests) {
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005135 if (!nextRequest.submitted) {
5136 for (const auto& s : nextRequest.captureRequest->mOutputStreams) {
5137 if (stream == s) return true;
5138 }
5139 if (stream == nextRequest.captureRequest->mInputStream) return true;
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07005140 }
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07005141 }
5142
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005143 for (const auto& request : mRequestQueue) {
5144 for (const auto& s : request->mOutputStreams) {
5145 if (stream == s) return true;
5146 }
5147 if (stream == request->mInputStream) return true;
5148 }
5149
5150 for (const auto& request : mRepeatingRequests) {
5151 for (const auto& s : request->mOutputStreams) {
5152 if (stream == s) return true;
5153 }
5154 if (stream == request->mInputStream) return true;
5155 }
5156
5157 return false;
5158}
Jianing Weicb0652e2014-03-12 18:29:36 -07005159
Emilian Peev40ead602017-09-26 15:46:36 +01005160bool Camera3Device::RequestThread::isOutputSurfacePending(int streamId, size_t surfaceId) {
5161 ATRACE_CALL();
5162 Mutex::Autolock l(mRequestLock);
5163
5164 for (const auto& nextRequest : mNextRequests) {
5165 for (const auto& s : nextRequest.captureRequest->mOutputSurfaces) {
5166 if (s.first == streamId) {
5167 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
5168 if (it != s.second.end()) {
5169 return true;
5170 }
5171 }
5172 }
5173 }
5174
5175 for (const auto& request : mRequestQueue) {
5176 for (const auto& s : request->mOutputSurfaces) {
5177 if (s.first == streamId) {
5178 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
5179 if (it != s.second.end()) {
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07005180 return true;
Emilian Peev40ead602017-09-26 15:46:36 +01005181 }
5182 }
5183 }
5184 }
5185
5186 for (const auto& request : mRepeatingRequests) {
5187 for (const auto& s : request->mOutputSurfaces) {
5188 if (s.first == streamId) {
5189 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
5190 if (it != s.second.end()) {
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -07005191 return true;
Emilian Peev40ead602017-09-26 15:46:36 +01005192 }
5193 }
5194 }
5195 }
5196
5197 return false;
5198}
5199
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07005200void Camera3Device::RequestThread::signalPipelineDrain(const std::vector<int>& streamIds) {
5201 if (!mUseHalBufManager) {
5202 ALOGE("%s called for camera device not supporting HAL buffer management", __FUNCTION__);
5203 return;
5204 }
5205
5206 Mutex::Autolock pl(mPauseLock);
5207 if (mPaused) {
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07005208 mInterface->signalPipelineDrain(streamIds);
5209 return;
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07005210 }
5211 // If request thread is still busy, wait until paused then notify HAL
5212 mNotifyPipelineDrain = true;
5213 mStreamIdsToBeDrained = streamIds;
5214}
5215
Yin-Chia Yehe52b8fa2020-07-28 00:17:58 -07005216void Camera3Device::RequestThread::resetPipelineDrain() {
5217 Mutex::Autolock pl(mPauseLock);
5218 mNotifyPipelineDrain = false;
5219 mStreamIdsToBeDrained.clear();
5220}
5221
Emilian Peevc0fe54c2020-03-11 14:05:07 -07005222void Camera3Device::RequestThread::clearPreviousRequest() {
5223 Mutex::Autolock l(mRequestLock);
5224 mPrevRequest.clear();
5225}
5226
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005227status_t Camera3Device::RequestThread::switchToOffline(
5228 const std::vector<int32_t>& streamsToKeep,
5229 /*out*/hardware::camera::device::V3_6::CameraOfflineSessionInfo* offlineSessionInfo,
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005230 /*out*/sp<hardware::camera::device::V3_6::ICameraOfflineSession>* offlineSession,
5231 /*out*/camera3::BufferRecords* bufferRecords) {
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005232 Mutex::Autolock l(mRequestLock);
5233 clearRepeatingRequestsLocked(/*lastFrameNumber*/nullptr);
5234
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005235 // Wait until request thread is fully stopped
5236 // TBD: check if request thread is being paused by other APIs (shouldn't be)
5237
5238 // We could also check for mRepeatingRequests.empty(), but the API interface
5239 // is serialized by Camera3Device::mInterfaceLock so no one should be able to submit any
5240 // new requests during the call; hence skip that check.
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005241 bool queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
5242 while (!queueEmpty) {
5243 status_t res = mRequestSubmittedSignal.waitRelative(mRequestLock, kRequestSubmitTimeout);
5244 if (res == TIMED_OUT) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005245 ALOGE("%s: request thread failed to submit one request within timeout!", __FUNCTION__);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005246 return res;
5247 } else if (res != OK) {
5248 ALOGE("%s: request thread failed to submit a request: %s (%d)!",
5249 __FUNCTION__, strerror(-res), res);
5250 return res;
5251 }
5252 queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
5253 }
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005254
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005255 return mInterface->switchToOffline(
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005256 streamsToKeep, offlineSessionInfo, offlineSession, bufferRecords);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07005257}
5258
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08005259status_t Camera3Device::RequestThread::setRotateAndCropAutoBehavior(
5260 camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue) {
5261 ATRACE_CALL();
5262 Mutex::Autolock l(mTriggerMutex);
5263 if (rotateAndCropValue == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
5264 return BAD_VALUE;
5265 }
5266 mRotateAndCropOverride = rotateAndCropValue;
5267 return OK;
5268}
5269
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08005270status_t Camera3Device::RequestThread::setCameraMute(bool enabled) {
5271 ATRACE_CALL();
5272 Mutex::Autolock l(mTriggerMutex);
5273 if (enabled != mCameraMute) {
5274 mCameraMute = enabled;
5275 mCameraMuteChanged = true;
5276 }
5277 return OK;
5278}
5279
Yin-Chia Yeh598fc602017-07-24 11:37:23 -07005280nsecs_t Camera3Device::getExpectedInFlightDuration() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005281 ATRACE_CALL();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005282 std::lock_guard<std::mutex> l(mInFlightLock);
Eino-Ville Talvala10bd57e2017-06-23 16:22:44 -07005283 return mExpectedInflightDuration > kMinInflightDuration ?
5284 mExpectedInflightDuration : kMinInflightDuration;
5285}
5286
Emilian Peevaebbe412018-01-15 13:53:24 +00005287void Camera3Device::RequestThread::cleanupPhysicalSettings(sp<CaptureRequest> request,
Emilian Peevf4816702020-04-03 15:44:51 -07005288 camera_capture_request_t *halRequest) {
Emilian Peevaebbe412018-01-15 13:53:24 +00005289 if ((request == nullptr) || (halRequest == nullptr)) {
5290 ALOGE("%s: Invalid request!", __FUNCTION__);
5291 return;
5292 }
5293
5294 if (halRequest->num_physcam_settings > 0) {
5295 if (halRequest->physcam_id != nullptr) {
5296 delete [] halRequest->physcam_id;
5297 halRequest->physcam_id = nullptr;
5298 }
5299 if (halRequest->physcam_settings != nullptr) {
5300 auto it = ++(request->mSettingsList.begin());
5301 size_t i = 0;
5302 for (; it != request->mSettingsList.end(); it++, i++) {
5303 it->metadata.unlock(halRequest->physcam_settings[i]);
5304 }
5305 delete [] halRequest->physcam_settings;
5306 halRequest->physcam_settings = nullptr;
5307 }
5308 }
5309}
5310
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005311void Camera3Device::RequestThread::cleanUpFailedRequests(bool sendRequestError) {
5312 if (mNextRequests.empty()) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005313 return;
5314 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005315
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005316 for (auto& nextRequest : mNextRequests) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005317 // Skip the ones that have been submitted successfully.
5318 if (nextRequest.submitted) {
5319 continue;
5320 }
5321
5322 sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
Emilian Peevf4816702020-04-03 15:44:51 -07005323 camera_capture_request_t* halRequest = &nextRequest.halRequest;
5324 Vector<camera_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005325
5326 if (halRequest->settings != NULL) {
Emilian Peevaebbe412018-01-15 13:53:24 +00005327 captureRequest->mSettingsList.begin()->metadata.unlock(halRequest->settings);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005328 }
5329
Emilian Peevaebbe412018-01-15 13:53:24 +00005330 cleanupPhysicalSettings(captureRequest, halRequest);
5331
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005332 if (captureRequest->mInputStream != NULL) {
Emilian Peevf4816702020-04-03 15:44:51 -07005333 captureRequest->mInputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005334 captureRequest->mInputStream->returnInputBuffer(captureRequest->mInputBuffer);
5335 }
5336
Yin-Chia Yeh21cb47b2019-01-18 15:08:17 -08005337 // No output buffer can be returned when using HAL buffer manager
5338 if (!mUseHalBufManager) {
5339 for (size_t i = 0; i < halRequest->num_output_buffers; i++) {
5340 //Buffers that failed processing could still have
5341 //valid acquire fence.
5342 int acquireFence = (*outputBuffers)[i].acquire_fence;
5343 if (0 <= acquireFence) {
5344 close(acquireFence);
5345 outputBuffers->editItemAt(i).acquire_fence = -1;
5346 }
Emilian Peevf4816702020-04-03 15:44:51 -07005347 outputBuffers->editItemAt(i).status = CAMERA_BUFFER_STATUS_ERROR;
Yin-Chia Yeh21cb47b2019-01-18 15:08:17 -08005348 captureRequest->mOutputStreams.editItemAt(i)->returnBuffer((*outputBuffers)[i], 0,
5349 /*timestampIncreasing*/true, std::vector<size_t> (),
5350 captureRequest->mResultExtras.frameNumber);
Emilian Peevc58cf4c2017-05-11 17:23:41 +01005351 }
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005352 }
5353
5354 if (sendRequestError) {
5355 Mutex::Autolock l(mRequestLock);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07005356 sp<NotificationListener> listener = mListener.promote();
5357 if (listener != NULL) {
5358 listener->notifyError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08005359 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005360 captureRequest->mResultExtras);
5361 }
5362 }
Shuzhen Wangcadb3302016-11-04 14:17:56 -07005363
5364 // Remove yet-to-be submitted inflight request from inflightMap
5365 {
5366 sp<Camera3Device> parent = mParent.promote();
5367 if (parent != NULL) {
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08005368 std::lock_guard<std::mutex> l(parent->mInFlightLock);
Shuzhen Wangcadb3302016-11-04 14:17:56 -07005369 ssize_t idx = parent->mInFlightMap.indexOfKey(captureRequest->mResultExtras.frameNumber);
5370 if (idx >= 0) {
5371 ALOGV("%s: Remove inflight request from queue: frameNumber %" PRId64,
5372 __FUNCTION__, captureRequest->mResultExtras.frameNumber);
5373 parent->removeInFlightMapEntryLocked(idx);
5374 }
5375 }
5376 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005377 }
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07005378
5379 Mutex::Autolock l(mRequestLock);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005380 mNextRequests.clear();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005381}
5382
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005383void Camera3Device::RequestThread::waitForNextRequestBatch() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005384 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005385 // Optimized a bit for the simple steady-state case (single repeating
5386 // request), to avoid putting that request in the queue temporarily.
5387 Mutex::Autolock l(mRequestLock);
5388
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005389 assert(mNextRequests.empty());
5390
5391 NextRequest nextRequest;
5392 nextRequest.captureRequest = waitForNextRequestLocked();
5393 if (nextRequest.captureRequest == nullptr) {
5394 return;
5395 }
5396
Emilian Peevf4816702020-04-03 15:44:51 -07005397 nextRequest.halRequest = camera_capture_request_t();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005398 nextRequest.submitted = false;
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005399 mNextRequests.add(nextRequest);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005400
5401 // Wait for additional requests
5402 const size_t batchSize = nextRequest.captureRequest->mBatchSize;
5403
5404 for (size_t i = 1; i < batchSize; i++) {
5405 NextRequest additionalRequest;
5406 additionalRequest.captureRequest = waitForNextRequestLocked();
5407 if (additionalRequest.captureRequest == nullptr) {
5408 break;
5409 }
5410
Emilian Peevf4816702020-04-03 15:44:51 -07005411 additionalRequest.halRequest = camera_capture_request_t();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005412 additionalRequest.submitted = false;
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005413 mNextRequests.add(additionalRequest);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005414 }
5415
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005416 if (mNextRequests.size() < batchSize) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08005417 ALOGE("RequestThread: only get %zu out of %zu requests. Skipping requests.",
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07005418 mNextRequests.size(), batchSize);
5419 cleanUpFailedRequests(/*sendRequestError*/true);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07005420 }
5421
5422 return;
5423}
5424
5425sp<Camera3Device::CaptureRequest>
5426 Camera3Device::RequestThread::waitForNextRequestLocked() {
5427 status_t res;
5428 sp<CaptureRequest> nextRequest;
5429
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005430 while (mRequestQueue.empty()) {
5431 if (!mRepeatingRequests.empty()) {
5432 // Always atomically enqueue all requests in a repeating request
5433 // list. Guarantees a complete in-sequence set of captures to
5434 // application.
5435 const RequestList &requests = mRepeatingRequests;
Shuzhen Wang316781a2020-08-18 18:11:01 -07005436 if (mFirstRepeating) {
5437 mFirstRepeating = false;
5438 } else {
5439 for (auto& request : requests) {
5440 // For repeating requests, override timestamp request using
5441 // the time a request is inserted into the request queue,
5442 // because the original repeating request will have an old
5443 // fixed timestamp.
5444 request->mRequestTimeNs = systemTime();
5445 }
5446 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005447 RequestList::const_iterator firstRequest =
5448 requests.begin();
5449 nextRequest = *firstRequest;
5450 mRequestQueue.insert(mRequestQueue.end(),
5451 ++firstRequest,
5452 requests.end());
5453 // No need to wait any longer
Jianing Weicb0652e2014-03-12 18:29:36 -07005454
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07005455 mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
Jianing Weicb0652e2014-03-12 18:29:36 -07005456
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005457 break;
5458 }
5459
5460 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
5461
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005462 if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
5463 exitPending()) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005464 Mutex::Autolock pl(mPauseLock);
5465 if (mPaused == false) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005466 ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005467 mPaused = true;
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07005468 if (mNotifyPipelineDrain) {
5469 mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
5470 mNotifyPipelineDrain = false;
5471 mStreamIdsToBeDrained.clear();
5472 }
Yin-Chia Yehc300a072019-02-13 14:56:57 -08005473 // Let the tracker know
5474 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5475 if (statusTracker != 0) {
5476 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
5477 }
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07005478 sp<Camera3Device> parent = mParent.promote();
5479 if (parent != nullptr) {
5480 parent->mRequestBufferSM.onRequestThreadPaused();
5481 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005482 }
5483 // Stop waiting for now and let thread management happen
5484 return NULL;
5485 }
5486 }
5487
5488 if (nextRequest == NULL) {
5489 // Don't have a repeating request already in hand, so queue
5490 // must have an entry now.
5491 RequestList::iterator firstRequest =
5492 mRequestQueue.begin();
5493 nextRequest = *firstRequest;
5494 mRequestQueue.erase(firstRequest);
Shuzhen Wang9d066012016-09-30 11:30:20 -07005495 if (mRequestQueue.empty() && !nextRequest->mRepeating) {
5496 sp<NotificationListener> listener = mListener.promote();
5497 if (listener != NULL) {
5498 listener->notifyRequestQueueEmpty();
5499 }
5500 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005501 }
5502
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07005503 // In case we've been unpaused by setPaused clearing mDoPause, need to
5504 // update internal pause state (capture/setRepeatingRequest unpause
5505 // directly).
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005506 Mutex::Autolock pl(mPauseLock);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005507 if (mPaused) {
5508 ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
5509 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5510 if (statusTracker != 0) {
5511 statusTracker->markComponentActive(mStatusId);
5512 }
5513 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005514 mPaused = false;
5515
5516 // Check if we've reconfigured since last time, and reset the preview
5517 // request if so. Can't use 'NULL request == repeat' across configure calls.
5518 if (mReconfigured) {
5519 mPrevRequest.clear();
5520 mReconfigured = false;
5521 }
5522
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07005523 if (nextRequest != NULL) {
5524 nextRequest->mResultExtras.frameNumber = mFrameNumber++;
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07005525 nextRequest->mResultExtras.afTriggerId = mCurrentAfTriggerId;
5526 nextRequest->mResultExtras.precaptureTriggerId = mCurrentPreCaptureTriggerId;
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07005527
5528 // Since RequestThread::clear() removes buffers from the input stream,
5529 // get the right buffer here before unlocking mRequestLock
5530 if (nextRequest->mInputStream != NULL) {
Shuzhen Wang83bff122020-11-20 15:51:39 -08005531 res = nextRequest->mInputStream->getInputBuffer(&nextRequest->mInputBuffer,
5532 &nextRequest->mInputBufferSize);
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07005533 if (res != OK) {
5534 // Can't get input buffer from gralloc queue - this could be due to
5535 // disconnected queue or other producer misbehavior, so not a fatal
5536 // error
5537 ALOGE("%s: Can't get input buffer, skipping request:"
5538 " %s (%d)", __FUNCTION__, strerror(-res), res);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07005539
5540 sp<NotificationListener> listener = mListener.promote();
5541 if (listener != NULL) {
5542 listener->notifyError(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08005543 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07005544 nextRequest->mResultExtras);
5545 }
5546 return NULL;
5547 }
5548 }
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07005549 }
Chien-Yu Chend196d612015-06-22 19:49:01 -07005550
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005551 return nextRequest;
5552}
5553
5554bool Camera3Device::RequestThread::waitIfPaused() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005555 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005556 status_t res;
5557 Mutex::Autolock l(mPauseLock);
5558 while (mDoPause) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005559 if (mPaused == false) {
5560 mPaused = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005561 ALOGV("%s: RequestThread: Paused", __FUNCTION__);
Yin-Chia Yeh7447f0f2018-10-11 15:28:12 -07005562 if (mNotifyPipelineDrain) {
5563 mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
5564 mNotifyPipelineDrain = false;
5565 mStreamIdsToBeDrained.clear();
5566 }
Yin-Chia Yehc300a072019-02-13 14:56:57 -08005567 // Let the tracker know
5568 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5569 if (statusTracker != 0) {
5570 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
5571 }
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07005572 sp<Camera3Device> parent = mParent.promote();
5573 if (parent != nullptr) {
5574 parent->mRequestBufferSM.onRequestThreadPaused();
5575 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005576 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005577
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005578 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005579 if (res == TIMED_OUT || exitPending()) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08005580 return true;
5581 }
5582 }
5583 // We don't set mPaused to false here, because waitForNextRequest needs
5584 // to further manage the paused state in case of starvation.
5585 return false;
5586}
5587
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07005588void Camera3Device::RequestThread::unpauseForNewRequests() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005589 ATRACE_CALL();
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07005590 // With work to do, mark thread as unpaused.
5591 // If paused by request (setPaused), don't resume, to avoid
5592 // extra signaling/waiting overhead to waitUntilPaused
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005593 mRequestSignal.signal();
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07005594 Mutex::Autolock p(mPauseLock);
5595 if (!mDoPause) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07005596 ALOGV("%s: RequestThread: Going active", __FUNCTION__);
5597 if (mPaused) {
5598 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5599 if (statusTracker != 0) {
5600 statusTracker->markComponentActive(mStatusId);
5601 }
5602 }
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07005603 mPaused = false;
5604 }
5605}
5606
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07005607void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
5608 sp<Camera3Device> parent = mParent.promote();
5609 if (parent != NULL) {
5610 va_list args;
5611 va_start(args, fmt);
5612
5613 parent->setErrorStateV(fmt, args);
5614
5615 va_end(args);
5616 }
5617}
5618
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005619status_t Camera3Device::RequestThread::insertTriggers(
5620 const sp<CaptureRequest> &request) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005621 ATRACE_CALL();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005622 Mutex::Autolock al(mTriggerMutex);
5623
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07005624 sp<Camera3Device> parent = mParent.promote();
5625 if (parent == NULL) {
5626 CLOGE("RequestThread: Parent is gone");
5627 return DEAD_OBJECT;
5628 }
5629
Emilian Peevaebbe412018-01-15 13:53:24 +00005630 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005631 size_t count = mTriggerMap.size();
5632
5633 for (size_t i = 0; i < count; ++i) {
5634 RequestTrigger trigger = mTriggerMap.valueAt(i);
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005635 uint32_t tag = trigger.metadataTag;
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07005636
5637 if (tag == ANDROID_CONTROL_AF_TRIGGER_ID || tag == ANDROID_CONTROL_AE_PRECAPTURE_ID) {
5638 bool isAeTrigger = (trigger.metadataTag == ANDROID_CONTROL_AE_PRECAPTURE_ID);
5639 uint32_t triggerId = static_cast<uint32_t>(trigger.entryValue);
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07005640 if (isAeTrigger) {
5641 request->mResultExtras.precaptureTriggerId = triggerId;
5642 mCurrentPreCaptureTriggerId = triggerId;
5643 } else {
5644 request->mResultExtras.afTriggerId = triggerId;
5645 mCurrentAfTriggerId = triggerId;
5646 }
Emilian Peev7e25e5e2017-04-07 15:48:49 +01005647 continue;
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07005648 }
5649
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005650 camera_metadata_entry entry = metadata.find(tag);
5651
5652 if (entry.count > 0) {
5653 /**
5654 * Already has an entry for this trigger in the request.
5655 * Rewrite it with our requested trigger value.
5656 */
5657 RequestTrigger oldTrigger = trigger;
5658
5659 oldTrigger.entryValue = entry.data.u8[0];
5660
5661 mTriggerReplacedMap.add(tag, oldTrigger);
5662 } else {
5663 /**
5664 * More typical, no trigger entry, so we just add it
5665 */
5666 mTriggerRemovedMap.add(tag, trigger);
5667 }
5668
5669 status_t res;
5670
5671 switch (trigger.getTagType()) {
5672 case TYPE_BYTE: {
5673 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
5674 res = metadata.update(tag,
5675 &entryValue,
5676 /*count*/1);
5677 break;
5678 }
5679 case TYPE_INT32:
5680 res = metadata.update(tag,
5681 &trigger.entryValue,
5682 /*count*/1);
5683 break;
5684 default:
5685 ALOGE("%s: Type not supported: 0x%x",
5686 __FUNCTION__,
5687 trigger.getTagType());
5688 return INVALID_OPERATION;
5689 }
5690
5691 if (res != OK) {
5692 ALOGE("%s: Failed to update request metadata with trigger tag %s"
5693 ", value %d", __FUNCTION__, trigger.getTagName(),
5694 trigger.entryValue);
5695 return res;
5696 }
5697
5698 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
5699 trigger.getTagName(),
5700 trigger.entryValue);
5701 }
5702
5703 mTriggerMap.clear();
5704
5705 return count;
5706}
5707
5708status_t Camera3Device::RequestThread::removeTriggers(
5709 const sp<CaptureRequest> &request) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005710 ATRACE_CALL();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005711 Mutex::Autolock al(mTriggerMutex);
5712
Emilian Peevaebbe412018-01-15 13:53:24 +00005713 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005714
5715 /**
5716 * Replace all old entries with their old values.
5717 */
5718 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
5719 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
5720
5721 status_t res;
5722
5723 uint32_t tag = trigger.metadataTag;
5724 switch (trigger.getTagType()) {
5725 case TYPE_BYTE: {
5726 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
5727 res = metadata.update(tag,
5728 &entryValue,
5729 /*count*/1);
5730 break;
5731 }
5732 case TYPE_INT32:
5733 res = metadata.update(tag,
5734 &trigger.entryValue,
5735 /*count*/1);
5736 break;
5737 default:
5738 ALOGE("%s: Type not supported: 0x%x",
5739 __FUNCTION__,
5740 trigger.getTagType());
5741 return INVALID_OPERATION;
5742 }
5743
5744 if (res != OK) {
5745 ALOGE("%s: Failed to restore request metadata with trigger tag %s"
5746 ", trigger value %d", __FUNCTION__,
5747 trigger.getTagName(), trigger.entryValue);
5748 return res;
5749 }
5750 }
5751 mTriggerReplacedMap.clear();
5752
5753 /**
5754 * Remove all new entries.
5755 */
5756 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
5757 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
5758 status_t res = metadata.erase(trigger.metadataTag);
5759
5760 if (res != OK) {
5761 ALOGE("%s: Failed to erase metadata with trigger tag %s"
5762 ", trigger value %d", __FUNCTION__,
5763 trigger.getTagName(), trigger.entryValue);
5764 return res;
5765 }
5766 }
5767 mTriggerRemovedMap.clear();
5768
5769 return OK;
5770}
5771
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005772status_t Camera3Device::RequestThread::addFakeTriggerIds(
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005773 const sp<CaptureRequest> &request) {
Eino-Ville Talvalad309fb92015-11-25 12:12:45 -08005774 // Trigger ID 0 had special meaning in the HAL2 spec, so avoid it here
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005775 static const int32_t fakeTriggerId = 1;
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005776 status_t res;
5777
Emilian Peevaebbe412018-01-15 13:53:24 +00005778 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005779
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005780 // If AF trigger is active, insert a fake AF trigger ID if none already
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005781 // exists
5782 camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
5783 camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
5784 if (afTrigger.count > 0 &&
5785 afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
5786 afId.count == 0) {
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005787 res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &fakeTriggerId, 1);
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005788 if (res != OK) return res;
5789 }
5790
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005791 // If AE precapture trigger is active, insert a fake precapture trigger ID
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005792 // if none already exists
5793 camera_metadata_entry pcTrigger =
5794 metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
5795 camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
5796 if (pcTrigger.count > 0 &&
5797 pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
5798 pcId.count == 0) {
5799 res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -04005800 &fakeTriggerId, 1);
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07005801 if (res != OK) return res;
5802 }
5803
5804 return OK;
5805}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07005806
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08005807bool Camera3Device::RequestThread::overrideAutoRotateAndCrop(
5808 const sp<CaptureRequest> &request) {
5809 ATRACE_CALL();
5810
5811 if (request->mRotateAndCropAuto) {
5812 Mutex::Autolock l(mTriggerMutex);
5813 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
5814
5815 auto rotateAndCropEntry = metadata.find(ANDROID_SCALER_ROTATE_AND_CROP);
5816 if (rotateAndCropEntry.count > 0) {
5817 if (rotateAndCropEntry.data.u8[0] == mRotateAndCropOverride) {
5818 return false;
5819 } else {
5820 rotateAndCropEntry.data.u8[0] = mRotateAndCropOverride;
5821 return true;
5822 }
5823 } else {
5824 uint8_t rotateAndCrop_u8 = mRotateAndCropOverride;
5825 metadata.update(ANDROID_SCALER_ROTATE_AND_CROP,
5826 &rotateAndCrop_u8, 1);
5827 return true;
5828 }
5829 }
5830 return false;
5831}
5832
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08005833bool Camera3Device::RequestThread::overrideTestPattern(
5834 const sp<CaptureRequest> &request) {
5835 ATRACE_CALL();
5836
5837 Mutex::Autolock l(mTriggerMutex);
5838
5839 bool changed = false;
5840
5841 int32_t testPatternMode = request->mOriginalTestPatternMode;
5842 int32_t testPatternData[4] = {
5843 request->mOriginalTestPatternData[0],
5844 request->mOriginalTestPatternData[1],
5845 request->mOriginalTestPatternData[2],
5846 request->mOriginalTestPatternData[3]
5847 };
5848
5849 if (mCameraMute) {
5850 testPatternMode = ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR;
5851 testPatternData[0] = 0;
5852 testPatternData[1] = 0;
5853 testPatternData[2] = 0;
5854 testPatternData[3] = 0;
5855 }
5856
5857 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
5858
5859 auto testPatternEntry = metadata.find(ANDROID_SENSOR_TEST_PATTERN_MODE);
5860 if (testPatternEntry.count > 0) {
5861 if (testPatternEntry.data.i32[0] != testPatternMode) {
5862 testPatternEntry.data.i32[0] = testPatternMode;
5863 changed = true;
5864 }
5865 } else {
5866 metadata.update(ANDROID_SENSOR_TEST_PATTERN_MODE,
5867 &testPatternMode, 1);
5868 changed = true;
5869 }
5870
5871 auto testPatternColor = metadata.find(ANDROID_SENSOR_TEST_PATTERN_DATA);
5872 if (testPatternColor.count > 0) {
5873 for (size_t i = 0; i < 4; i++) {
5874 if (testPatternColor.data.i32[i] != (int32_t)testPatternData[i]) {
5875 testPatternColor.data.i32[i] = testPatternData[i];
5876 changed = true;
5877 }
5878 }
5879 } else {
5880 metadata.update(ANDROID_SENSOR_TEST_PATTERN_DATA,
5881 (int32_t*)testPatternData, 4);
5882 changed = true;
5883 }
5884
5885 return changed;
5886}
5887
Cliff Wuc2ad9c82021-04-21 00:58:58 +08005888status_t Camera3Device::RequestThread::setHalInterface(
5889 sp<HalInterface> newHalInterface) {
5890 if (newHalInterface.get() == nullptr) {
5891 ALOGE("%s: The newHalInterface does not exist!", __FUNCTION__);
5892 return DEAD_OBJECT;
5893 }
5894
5895 mInterface = newHalInterface;
5896
5897 return OK;
5898}
5899
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005900/**
5901 * PreparerThread inner class methods
5902 */
5903
5904Camera3Device::PreparerThread::PreparerThread() :
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07005905 Thread(/*canCallJava*/false), mListener(nullptr),
Emilian Peevac3ce6c2017-12-12 15:27:02 +00005906 mActive(false), mCancelNow(false), mCurrentMaxCount(0), mCurrentPrepareComplete(false) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005907}
5908
5909Camera3Device::PreparerThread::~PreparerThread() {
5910 Thread::requestExitAndWait();
5911 if (mCurrentStream != nullptr) {
5912 mCurrentStream->cancelPrepare();
5913 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
5914 mCurrentStream.clear();
5915 }
5916 clear();
5917}
5918
Ruben Brunkc78ac262015-08-13 17:58:46 -07005919status_t Camera3Device::PreparerThread::prepare(int maxCount, sp<Camera3StreamInterface>& stream) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07005920 ATRACE_CALL();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005921 status_t res;
5922
5923 Mutex::Autolock l(mLock);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07005924 sp<NotificationListener> listener = mListener.promote();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005925
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -07005926 res = stream->startPrepare(maxCount, true /*blockRequest*/);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005927 if (res == OK) {
5928 // No preparation needed, fire listener right off
5929 ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId());
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07005930 if (listener != NULL) {
5931 listener->notifyPrepared(stream->getId());
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005932 }
5933 return OK;
5934 } else if (res != NOT_ENOUGH_DATA) {
5935 return res;
5936 }
5937
5938 // Need to prepare, start up thread if necessary
5939 if (!mActive) {
5940 // mRunning will change to false before the thread fully shuts down, so wait to be sure it
5941 // isn't running
5942 Thread::requestExitAndWait();
5943 res = Thread::run("C3PrepThread", PRIORITY_BACKGROUND);
5944 if (res != OK) {
5945 ALOGE("%s: Unable to start preparer stream: %d (%s)", __FUNCTION__, res, strerror(-res));
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07005946 if (listener != NULL) {
5947 listener->notifyPrepared(stream->getId());
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005948 }
5949 return res;
5950 }
5951 mCancelNow = false;
5952 mActive = true;
5953 ALOGV("%s: Preparer stream started", __FUNCTION__);
5954 }
5955
5956 // queue up the work
Emilian Peevac3ce6c2017-12-12 15:27:02 +00005957 mPendingStreams.emplace(maxCount, stream);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07005958 ALOGV("%s: Stream %d queued for preparing", __FUNCTION__, stream->getId());
5959
5960 return OK;
5961}
5962
Emilian Peevac3ce6c2017-12-12 15:27:02 +00005963void Camera3Device::PreparerThread::pause() {
5964 ATRACE_CALL();
5965
5966 Mutex::Autolock l(mLock);
5967
5968 std::unordered_map<int, sp<camera3::Camera3StreamInterface> > pendingStreams;
5969 pendingStreams.insert(mPendingStreams.begin(), mPendingStreams.end());
5970 sp<camera3::Camera3StreamInterface> currentStream = mCurrentStream;
5971 int currentMaxCount = mCurrentMaxCount;
5972 mPendingStreams.clear();
5973 mCancelNow = true;
5974 while (mActive) {
5975 auto res = mThreadActiveSignal.waitRelative(mLock, kActiveTimeout);
5976 if (res == TIMED_OUT) {
5977 ALOGE("%s: Timed out waiting on prepare thread!", __FUNCTION__);
5978 return;
5979 } else if (res != OK) {
5980 ALOGE("%s: Encountered an error: %d waiting on prepare thread!", __FUNCTION__, res);
5981 return;
5982 }
5983 }
5984
5985 //Check whether the prepare thread was able to complete the current
5986 //stream. In case work is still pending emplace it along with the rest
5987 //of the streams in the pending list.
5988 if (currentStream != nullptr) {
5989 if (!mCurrentPrepareComplete) {
5990 pendingStreams.emplace(currentMaxCount, currentStream);
5991 }
5992 }
5993
5994 mPendingStreams.insert(pendingStreams.begin(), pendingStreams.end());
5995 for (const auto& it : mPendingStreams) {
5996 it.second->cancelPrepare();
5997 }
5998}
5999
6000status_t Camera3Device::PreparerThread::resume() {
6001 ATRACE_CALL();
6002 status_t res;
6003
6004 Mutex::Autolock l(mLock);
6005 sp<NotificationListener> listener = mListener.promote();
6006
6007 if (mActive) {
6008 ALOGE("%s: Trying to resume an already active prepare thread!", __FUNCTION__);
6009 return NO_INIT;
6010 }
6011
6012 auto it = mPendingStreams.begin();
6013 for (; it != mPendingStreams.end();) {
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -07006014 res = it->second->startPrepare(it->first, true /*blockRequest*/);
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006015 if (res == OK) {
6016 if (listener != NULL) {
6017 listener->notifyPrepared(it->second->getId());
6018 }
6019 it = mPendingStreams.erase(it);
6020 } else if (res != NOT_ENOUGH_DATA) {
6021 ALOGE("%s: Unable to start preparer stream: %d (%s)", __FUNCTION__,
6022 res, strerror(-res));
6023 it = mPendingStreams.erase(it);
6024 } else {
6025 it++;
6026 }
6027 }
6028
6029 if (mPendingStreams.empty()) {
6030 return OK;
6031 }
6032
6033 res = Thread::run("C3PrepThread", PRIORITY_BACKGROUND);
6034 if (res != OK) {
6035 ALOGE("%s: Unable to start preparer stream: %d (%s)",
6036 __FUNCTION__, res, strerror(-res));
6037 return res;
6038 }
6039 mCancelNow = false;
6040 mActive = true;
6041 ALOGV("%s: Preparer stream started", __FUNCTION__);
6042
6043 return OK;
6044}
6045
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006046status_t Camera3Device::PreparerThread::clear() {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07006047 ATRACE_CALL();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006048 Mutex::Autolock l(mLock);
6049
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006050 for (const auto& it : mPendingStreams) {
6051 it.second->cancelPrepare();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006052 }
6053 mPendingStreams.clear();
6054 mCancelNow = true;
6055
6056 return OK;
6057}
6058
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07006059void Camera3Device::PreparerThread::setNotificationListener(wp<NotificationListener> listener) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -07006060 ATRACE_CALL();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006061 Mutex::Autolock l(mLock);
6062 mListener = listener;
6063}
6064
6065bool Camera3Device::PreparerThread::threadLoop() {
6066 status_t res;
6067 {
6068 Mutex::Autolock l(mLock);
6069 if (mCurrentStream == nullptr) {
6070 // End thread if done with work
6071 if (mPendingStreams.empty()) {
6072 ALOGV("%s: Preparer stream out of work", __FUNCTION__);
6073 // threadLoop _must not_ re-acquire mLock after it sets mActive to false; would
6074 // cause deadlock with prepare()'s requestExitAndWait triggered by !mActive.
6075 mActive = false;
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006076 mThreadActiveSignal.signal();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006077 return false;
6078 }
6079
6080 // Get next stream to prepare
6081 auto it = mPendingStreams.begin();
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006082 mCurrentStream = it->second;
6083 mCurrentMaxCount = it->first;
6084 mCurrentPrepareComplete = false;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006085 mPendingStreams.erase(it);
6086 ATRACE_ASYNC_BEGIN("stream prepare", mCurrentStream->getId());
6087 ALOGV("%s: Preparing stream %d", __FUNCTION__, mCurrentStream->getId());
6088 } else if (mCancelNow) {
6089 mCurrentStream->cancelPrepare();
6090 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
6091 ALOGV("%s: Cancelling stream %d prepare", __FUNCTION__, mCurrentStream->getId());
6092 mCurrentStream.clear();
6093 mCancelNow = false;
6094 return true;
6095 }
6096 }
6097
6098 res = mCurrentStream->prepareNextBuffer();
6099 if (res == NOT_ENOUGH_DATA) return true;
6100 if (res != OK) {
6101 // Something bad happened; try to recover by cancelling prepare and
6102 // signalling listener anyway
6103 ALOGE("%s: Stream %d returned error %d (%s) during prepare", __FUNCTION__,
6104 mCurrentStream->getId(), res, strerror(-res));
6105 mCurrentStream->cancelPrepare();
6106 }
6107
6108 // This stream has finished, notify listener
6109 Mutex::Autolock l(mLock);
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07006110 sp<NotificationListener> listener = mListener.promote();
6111 if (listener != NULL) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006112 ALOGV("%s: Stream %d prepare done, signaling listener", __FUNCTION__,
6113 mCurrentStream->getId());
Yin-Chia Yehe1c80632016-08-08 14:48:05 -07006114 listener->notifyPrepared(mCurrentStream->getId());
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006115 }
6116
6117 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
6118 mCurrentStream.clear();
Emilian Peevac3ce6c2017-12-12 15:27:02 +00006119 mCurrentPrepareComplete = true;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07006120
6121 return true;
6122}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07006123
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006124status_t Camera3Device::RequestBufferStateMachine::initialize(
6125 sp<camera3::StatusTracker> statusTracker) {
6126 if (statusTracker == nullptr) {
6127 ALOGE("%s: statusTracker is null", __FUNCTION__);
6128 return BAD_VALUE;
6129 }
6130
6131 std::lock_guard<std::mutex> lock(mLock);
6132 mStatusTracker = statusTracker;
Yin-Chia Yeh87b3ec02019-06-03 10:44:39 -07006133 mRequestBufferStatusId = statusTracker->addComponent("BufferRequestSM");
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006134 return OK;
6135}
6136
6137bool Camera3Device::RequestBufferStateMachine::startRequestBuffer() {
6138 std::lock_guard<std::mutex> lock(mLock);
Yin-Chia Yeh8a4ccb02018-11-16 15:43:36 -08006139 if (mStatus == RB_STATUS_READY || mStatus == RB_STATUS_PENDING_STOP) {
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006140 mRequestBufferOngoing = true;
Yin-Chia Yeh8a4ccb02018-11-16 15:43:36 -08006141 notifyTrackerLocked(/*active*/true);
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006142 return true;
6143 }
6144 return false;
6145}
6146
6147void Camera3Device::RequestBufferStateMachine::endRequestBuffer() {
6148 std::lock_guard<std::mutex> lock(mLock);
6149 if (!mRequestBufferOngoing) {
6150 ALOGE("%s called without a successful startRequestBuffer call first!", __FUNCTION__);
6151 return;
6152 }
6153 mRequestBufferOngoing = false;
6154 if (mStatus == RB_STATUS_PENDING_STOP) {
6155 checkSwitchToStopLocked();
6156 }
Yin-Chia Yeh8a4ccb02018-11-16 15:43:36 -08006157 notifyTrackerLocked(/*active*/false);
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006158}
6159
6160void Camera3Device::RequestBufferStateMachine::onStreamsConfigured() {
6161 std::lock_guard<std::mutex> lock(mLock);
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006162 mSwitchedToOffline = false;
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006163 mStatus = RB_STATUS_READY;
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006164 return;
6165}
6166
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -08006167void Camera3Device::RequestBufferStateMachine::onSubmittingRequest() {
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006168 std::lock_guard<std::mutex> lock(mLock);
6169 mRequestThreadPaused = false;
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -08006170 // inflight map register actually happens in prepareHalRequest now, but it is close enough
6171 // approximation.
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006172 mInflightMapEmpty = false;
6173 if (mStatus == RB_STATUS_STOPPED) {
6174 mStatus = RB_STATUS_READY;
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006175 }
6176 return;
6177}
6178
6179void Camera3Device::RequestBufferStateMachine::onRequestThreadPaused() {
6180 std::lock_guard<std::mutex> lock(mLock);
6181 mRequestThreadPaused = true;
6182 if (mStatus == RB_STATUS_PENDING_STOP) {
6183 checkSwitchToStopLocked();
6184 }
6185 return;
6186}
6187
6188void Camera3Device::RequestBufferStateMachine::onInflightMapEmpty() {
6189 std::lock_guard<std::mutex> lock(mLock);
6190 mInflightMapEmpty = true;
6191 if (mStatus == RB_STATUS_PENDING_STOP) {
6192 checkSwitchToStopLocked();
6193 }
6194 return;
6195}
6196
6197void Camera3Device::RequestBufferStateMachine::onWaitUntilIdle() {
6198 std::lock_guard<std::mutex> lock(mLock);
6199 if (!checkSwitchToStopLocked()) {
6200 mStatus = RB_STATUS_PENDING_STOP;
6201 }
6202 return;
6203}
6204
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006205bool Camera3Device::RequestBufferStateMachine::onSwitchToOfflineSuccess() {
6206 std::lock_guard<std::mutex> lock(mLock);
6207 if (mRequestBufferOngoing) {
6208 ALOGE("%s: HAL must not be requesting buffer after HAL returns switchToOffline!",
6209 __FUNCTION__);
6210 return false;
6211 }
6212 mSwitchedToOffline = true;
6213 mInflightMapEmpty = true;
6214 mRequestThreadPaused = true;
6215 mStatus = RB_STATUS_STOPPED;
6216 return true;
6217}
6218
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006219void Camera3Device::RequestBufferStateMachine::notifyTrackerLocked(bool active) {
6220 sp<StatusTracker> statusTracker = mStatusTracker.promote();
6221 if (statusTracker != nullptr) {
6222 if (active) {
6223 statusTracker->markComponentActive(mRequestBufferStatusId);
6224 } else {
6225 statusTracker->markComponentIdle(mRequestBufferStatusId, Fence::NO_FENCE);
6226 }
6227 }
6228}
6229
6230bool Camera3Device::RequestBufferStateMachine::checkSwitchToStopLocked() {
6231 if (mInflightMapEmpty && mRequestThreadPaused && !mRequestBufferOngoing) {
6232 mStatus = RB_STATUS_STOPPED;
Yin-Chia Yeh30ab5ed2018-10-12 15:57:04 -07006233 return true;
6234 }
6235 return false;
6236}
6237
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006238bool Camera3Device::startRequestBuffer() {
6239 return mRequestBufferSM.startRequestBuffer();
6240}
Shuzhen Wang268a1362018-10-16 16:32:59 -07006241
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006242void Camera3Device::endRequestBuffer() {
6243 mRequestBufferSM.endRequestBuffer();
6244}
Shuzhen Wang268a1362018-10-16 16:32:59 -07006245
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006246nsecs_t Camera3Device::getWaitDuration() {
6247 return kBaseGetBufferWait + getExpectedInFlightDuration();
6248}
Shuzhen Wang268a1362018-10-16 16:32:59 -07006249
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006250void Camera3Device::getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out) {
6251 mInterface->getInflightBufferKeys(out);
6252}
Shuzhen Wang268a1362018-10-16 16:32:59 -07006253
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006254void Camera3Device::getInflightRequestBufferKeys(std::vector<uint64_t>* out) {
6255 mInterface->getInflightRequestBufferKeys(out);
6256}
Shuzhen Wang268a1362018-10-16 16:32:59 -07006257
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006258std::vector<sp<Camera3StreamInterface>> Camera3Device::getAllStreams() {
6259 std::vector<sp<Camera3StreamInterface>> ret;
6260 bool hasInputStream = mInputStream != nullptr;
6261 ret.reserve(mOutputStreams.size() + mDeletedStreams.size() + ((hasInputStream) ? 1 : 0));
6262 if (hasInputStream) {
6263 ret.push_back(mInputStream);
Shuzhen Wang268a1362018-10-16 16:32:59 -07006264 }
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006265 for (size_t i = 0; i < mOutputStreams.size(); i++) {
6266 ret.push_back(mOutputStreams[i]);
6267 }
6268 for (size_t i = 0; i < mDeletedStreams.size(); i++) {
6269 ret.push_back(mDeletedStreams[i]);
6270 }
6271 return ret;
Shuzhen Wang268a1362018-10-16 16:32:59 -07006272}
6273
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006274status_t Camera3Device::switchToOffline(
6275 const std::vector<int32_t>& streamsToKeep,
6276 /*out*/ sp<CameraOfflineSessionBase>* session) {
6277 ATRACE_CALL();
6278 if (session == nullptr) {
6279 ALOGE("%s: session must not be null", __FUNCTION__);
6280 return BAD_VALUE;
6281 }
6282
6283 Mutex::Autolock il(mInterfaceLock);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006284
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006285 bool hasInputStream = mInputStream != nullptr;
6286 int32_t inputStreamId = hasInputStream ? mInputStream->getId() : -1;
6287 bool inputStreamSupportsOffline = hasInputStream ?
6288 mInputStream->getOfflineProcessingSupport() : false;
6289 auto outputStreamIds = mOutputStreams.getStreamIds();
6290 auto streamIds = outputStreamIds;
6291 if (hasInputStream) {
6292 streamIds.push_back(mInputStream->getId());
6293 }
6294
6295 // Check all streams in streamsToKeep supports offline mode
6296 for (auto id : streamsToKeep) {
6297 if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
6298 ALOGE("%s: Unknown stream ID %d", __FUNCTION__, id);
6299 return BAD_VALUE;
6300 } else if (id == inputStreamId) {
6301 if (!inputStreamSupportsOffline) {
6302 ALOGE("%s: input stream %d cannot be switched to offline",
6303 __FUNCTION__, id);
6304 return BAD_VALUE;
6305 }
6306 } else {
6307 sp<camera3::Camera3OutputStreamInterface> stream = mOutputStreams.get(id);
6308 if (!stream->getOfflineProcessingSupport()) {
6309 ALOGE("%s: output stream %d cannot be switched to offline",
6310 __FUNCTION__, id);
6311 return BAD_VALUE;
6312 }
6313 }
6314 }
6315
6316 // TODO: block surface sharing and surface group streams until we can support them
6317
6318 // Stop repeating request, wait until all remaining requests are submitted, then call into
6319 // HAL switchToOffline
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006320 hardware::camera::device::V3_6::CameraOfflineSessionInfo offlineSessionInfo;
6321 sp<hardware::camera::device::V3_6::ICameraOfflineSession> offlineSession;
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006322 camera3::BufferRecords bufferRecords;
6323 status_t ret = mRequestThread->switchToOffline(
6324 streamsToKeep, &offlineSessionInfo, &offlineSession, &bufferRecords);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006325
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006326 if (ret != OK) {
6327 SET_ERR("Switch to offline failed: %s (%d)", strerror(-ret), ret);
6328 return ret;
6329 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006330
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006331 bool succ = mRequestBufferSM.onSwitchToOfflineSuccess();
6332 if (!succ) {
6333 SET_ERR("HAL must not be calling requestStreamBuffers call");
6334 // TODO: block ALL callbacks from HAL till app configured new streams?
6335 return UNKNOWN_ERROR;
6336 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006337
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006338 // Verify offlineSessionInfo
6339 std::vector<int32_t> offlineStreamIds;
6340 offlineStreamIds.reserve(offlineSessionInfo.offlineStreams.size());
6341 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
6342 // verify stream IDs
6343 int32_t id = offlineStream.id;
6344 if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
6345 SET_ERR("stream ID %d not found!", id);
6346 return UNKNOWN_ERROR;
6347 }
6348
6349 // When not using HAL buf manager, only allow streams requested by app to be preserved
6350 if (!mUseHalBufManager) {
6351 if (std::find(streamsToKeep.begin(), streamsToKeep.end(), id) == streamsToKeep.end()) {
6352 SET_ERR("stream ID %d must not be switched to offline!", id);
6353 return UNKNOWN_ERROR;
6354 }
6355 }
6356
6357 offlineStreamIds.push_back(id);
6358 sp<Camera3StreamInterface> stream = (id == inputStreamId) ?
6359 static_cast<sp<Camera3StreamInterface>>(mInputStream) :
6360 static_cast<sp<Camera3StreamInterface>>(mOutputStreams.get(id));
6361 // Verify number of outstanding buffers
6362 if (stream->getOutstandingBuffersCount() != offlineStream.numOutstandingBuffers) {
6363 SET_ERR("Offline stream %d # of remaining buffer mismatch: (%zu,%d) (service/HAL)",
6364 id, stream->getOutstandingBuffersCount(), offlineStream.numOutstandingBuffers);
6365 return UNKNOWN_ERROR;
6366 }
6367 }
6368
6369 // Verify all streams to be deleted don't have any outstanding buffers
6370 if (hasInputStream && std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
6371 inputStreamId) == offlineStreamIds.end()) {
6372 if (mInputStream->hasOutstandingBuffers()) {
6373 SET_ERR("Input stream %d still has %zu outstanding buffer!",
6374 inputStreamId, mInputStream->getOutstandingBuffersCount());
6375 return UNKNOWN_ERROR;
6376 }
6377 }
6378
6379 for (const auto& outStreamId : outputStreamIds) {
6380 if (std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
6381 outStreamId) == offlineStreamIds.end()) {
6382 auto outStream = mOutputStreams.get(outStreamId);
6383 if (outStream->hasOutstandingBuffers()) {
6384 SET_ERR("Output stream %d still has %zu outstanding buffer!",
6385 outStreamId, outStream->getOutstandingBuffersCount());
6386 return UNKNOWN_ERROR;
6387 }
6388 }
6389 }
6390
6391 InFlightRequestMap offlineReqs;
6392 // Verify inflight requests and their pending buffers
6393 {
6394 std::lock_guard<std::mutex> l(mInFlightLock);
6395 for (auto offlineReq : offlineSessionInfo.offlineRequests) {
6396 int idx = mInFlightMap.indexOfKey(offlineReq.frameNumber);
6397 if (idx == NAME_NOT_FOUND) {
6398 SET_ERR("Offline request frame number %d not found!", offlineReq.frameNumber);
6399 return UNKNOWN_ERROR;
6400 }
6401
6402 const auto& inflightReq = mInFlightMap.valueAt(idx);
6403 // TODO: check specific stream IDs
6404 size_t numBuffersLeft = static_cast<size_t>(inflightReq.numBuffersLeft);
6405 if (numBuffersLeft != offlineReq.pendingStreams.size()) {
6406 SET_ERR("Offline request # of remaining buffer mismatch: (%d,%d) (service/HAL)",
6407 inflightReq.numBuffersLeft, offlineReq.pendingStreams.size());
6408 return UNKNOWN_ERROR;
6409 }
6410 offlineReqs.add(offlineReq.frameNumber, inflightReq);
6411 }
6412 }
6413
6414 // Create Camera3OfflineSession and transfer object ownership
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006415 // (streams, inflight requests, buffer caches)
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006416 camera3::StreamSet offlineStreamSet;
6417 sp<camera3::Camera3Stream> inputStream;
6418 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
6419 int32_t id = offlineStream.id;
6420 if (mInputStream != nullptr && id == mInputStream->getId()) {
6421 inputStream = mInputStream;
6422 } else {
6423 offlineStreamSet.add(id, mOutputStreams.get(id));
6424 }
6425 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006426
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006427 // TODO: check if we need to lock before copying states
6428 // though technically no other thread should be talking to Camera3Device at this point
6429 Camera3OfflineStates offlineStates(
6430 mTagMonitor, mVendorTagId, mUseHalBufManager, mNeedFixupMonochromeTags,
Shuzhen Wangb7b42652020-05-07 11:59:02 -07006431 mUsePartialResult, mNumPartialResults, mLastCompletedRegularFrameNumber,
6432 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
6433 mNextResultFrameNumber, mNextReprocessResultFrameNumber,
6434 mNextZslStillResultFrameNumber, mNextShutterFrameNumber,
6435 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
6436 mDeviceInfo, mPhysicalDeviceInfoMap, mDistortionMappers,
6437 mZoomRatioMappers, mRotateAndCropMappers);
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006438
6439 *session = new Camera3OfflineSession(mId, inputStream, offlineStreamSet,
6440 std::move(bufferRecords), offlineReqs, offlineStates, offlineSession);
6441
6442 // Delete all streams that has been transferred to offline session
6443 Mutex::Autolock l(mLock);
6444 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
6445 int32_t id = offlineStream.id;
6446 if (mInputStream != nullptr && id == mInputStream->getId()) {
6447 mInputStream.clear();
6448 } else {
6449 mOutputStreams.remove(id);
6450 }
6451 }
6452
6453 // disconnect all other streams and switch to UNCONFIGURED state
6454 if (mInputStream != nullptr) {
6455 ret = mInputStream->disconnect();
6456 if (ret != OK) {
6457 SET_ERR_L("disconnect input stream failed!");
6458 return UNKNOWN_ERROR;
6459 }
6460 }
6461
6462 for (auto streamId : mOutputStreams.getStreamIds()) {
6463 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
6464 ret = stream->disconnect();
6465 if (ret != OK) {
6466 SET_ERR_L("disconnect output stream %d failed!", streamId);
6467 return UNKNOWN_ERROR;
6468 }
6469 }
6470
6471 mInputStream.clear();
6472 mOutputStreams.clear();
6473 mNeedConfig = true;
6474 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
6475 mOperatingMode = NO_MODE;
6476 mIsConstrainedHighSpeedConfiguration = false;
Emilian Peevc0fe54c2020-03-11 14:05:07 -07006477 mRequestThread->clearPreviousRequest();
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006478
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006479 return OK;
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -08006480 // TO be done by CameraDeviceClient/Camera3OfflineSession
6481 // register the offline client to camera service
6482 // Setup result passthing threads etc
6483 // Initialize offline session so HAL can start sending callback to it (result Fmq)
6484 // TODO: check how many onIdle callback will be sent
6485 // Java side to make sure the CameraCaptureSession is properly closed
Yin-Chia Yehb978c382019-10-30 00:22:37 -07006486}
6487
Emilian Peevcc0b7952020-01-07 13:54:47 -08006488void Camera3Device::getOfflineStreamIds(std::vector<int> *offlineStreamIds) {
6489 ATRACE_CALL();
6490
6491 if (offlineStreamIds == nullptr) {
6492 return;
6493 }
6494
6495 Mutex::Autolock il(mInterfaceLock);
6496
6497 auto streamIds = mOutputStreams.getStreamIds();
6498 bool hasInputStream = mInputStream != nullptr;
6499 if (hasInputStream && mInputStream->getOfflineProcessingSupport()) {
6500 offlineStreamIds->push_back(mInputStream->getId());
6501 }
6502
6503 for (const auto & streamId : streamIds) {
6504 sp<camera3::Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
6505 // Streams that use the camera buffer manager are currently not supported in
6506 // offline mode
6507 if (stream->getOfflineProcessingSupport() &&
6508 (stream->getStreamSetId() == CAMERA3_STREAM_SET_ID_INVALID)) {
6509 offlineStreamIds->push_back(streamId);
6510 }
6511 }
6512}
6513
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08006514status_t Camera3Device::setRotateAndCropAutoBehavior(
6515 camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue) {
6516 ATRACE_CALL();
6517 Mutex::Autolock il(mInterfaceLock);
6518 Mutex::Autolock l(mLock);
6519 if (mRequestThread == nullptr) {
6520 return INVALID_OPERATION;
6521 }
6522 return mRequestThread->setRotateAndCropAutoBehavior(rotateAndCropValue);
6523}
6524
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08006525bool Camera3Device::supportsCameraMute() {
6526 Mutex::Autolock il(mInterfaceLock);
6527 Mutex::Autolock l(mLock);
6528
6529 return mSupportCameraMute;
6530}
6531
6532status_t Camera3Device::setCameraMute(bool enabled) {
6533 ATRACE_CALL();
6534 Mutex::Autolock il(mInterfaceLock);
6535 Mutex::Autolock l(mLock);
6536
6537 if (mRequestThread == nullptr || !mSupportCameraMute) {
6538 return INVALID_OPERATION;
6539 }
6540 return mRequestThread->setCameraMute(enabled);
6541}
6542
Cliff Wuc2ad9c82021-04-21 00:58:58 +08006543status_t Camera3Device::injectCamera(const String8& injectedCamId,
6544 sp<CameraProviderManager> manager) {
6545 ALOGI("%s Injection camera: injectedCamId = %s", __FUNCTION__, injectedCamId.string());
6546 ATRACE_CALL();
6547 Mutex::Autolock il(mInterfaceLock);
6548
6549 status_t res = NO_ERROR;
6550 if (mInjectionMethods->isInjecting()) {
6551 if (injectedCamId == mInjectionMethods->getInjectedCamId()) {
6552 return OK;
6553 } else {
6554 res = mInjectionMethods->stopInjection();
6555 if (res != OK) {
6556 ALOGE("%s: Failed to stop the injection camera! ret != NO_ERROR: %d",
6557 __FUNCTION__, res);
6558 return res;
6559 }
6560 }
6561 }
6562
6563 res = mInjectionMethods->injectionInitialize(injectedCamId, manager, this);
6564 if (res != OK) {
6565 ALOGE("%s: Failed to initialize the injection camera! ret != NO_ERROR: %d",
6566 __FUNCTION__, res);
6567 return res;
6568 }
6569
6570 camera3::camera_stream_configuration injectionConfig;
6571 std::vector<uint32_t> injectionBufferSizes;
6572 mInjectionMethods->getInjectionConfig(&injectionConfig, &injectionBufferSizes);
6573 // When the second display of android is cast to the remote device, and the opened camera is
6574 // also cast to the second display, in this case, because the camera has configured the streams
6575 // at this time, we can directly call injectCamera() to replace the internal camera with
6576 // injection camera.
6577 if (mOperatingMode >= 0 && injectionConfig.num_streams > 0
6578 && injectionBufferSizes.size() > 0) {
6579 ALOGV("%s: The opened camera is directly cast to the remote device.", __FUNCTION__);
6580 res = mInjectionMethods->injectCamera(
6581 injectionConfig, injectionBufferSizes);
6582 if (res != OK) {
6583 ALOGE("Can't finish inject camera process!");
6584 return res;
6585 }
6586 }
6587
6588 return OK;
6589}
6590
6591status_t Camera3Device::stopInjection() {
6592 ALOGI("%s: Injection camera: stopInjection", __FUNCTION__);
6593 Mutex::Autolock il(mInterfaceLock);
6594 return mInjectionMethods->stopInjection();
6595}
6596
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08006597}; // namespace android