blob: ec3591f5b7c8d180f4eb8a98dec29609a4f3216f [file] [log] [blame]
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera3-Device"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20//#define LOG_NNDEBUG 0 // Per-frame verbose logging
21
22#ifdef LOG_NNDEBUG
23#define ALOGVV(...) ALOGV(__VA_ARGS__)
24#else
25#define ALOGVV(...) ((void)0)
26#endif
27
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -070028// Convenience macro for transient errors
29#define CLOGE(fmt, ...) ALOGE("Camera %d: %s: " fmt, mId, __FUNCTION__, \
30 ##__VA_ARGS__)
31
32// Convenience macros for transitioning to the error state
33#define SET_ERR(fmt, ...) setErrorState( \
34 "%s: " fmt, __FUNCTION__, \
35 ##__VA_ARGS__)
36#define SET_ERR_L(fmt, ...) setErrorStateLocked( \
37 "%s: " fmt, __FUNCTION__, \
38 ##__VA_ARGS__)
39
Colin Crosse5729fa2014-03-21 15:04:25 -070040#include <inttypes.h>
41
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080042#include <utils/Log.h>
43#include <utils/Trace.h>
44#include <utils/Timers.h>
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070045
Igor Murashkinff3e31d2013-10-23 16:40:06 -070046#include "utils/CameraTraces.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070047#include "device3/Camera3Device.h"
48#include "device3/Camera3OutputStream.h"
49#include "device3/Camera3InputStream.h"
50#include "device3/Camera3ZslStream.h"
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -070051#include "device3/Camera3DummyStream.h"
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -070052#include "CameraService.h"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080053
54using namespace android::camera3;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080055
56namespace android {
57
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080058Camera3Device::Camera3Device(int id):
59 mId(id),
Eino-Ville Talvala9a179412015-06-09 13:15:16 -070060 mIsConstrainedHighSpeedConfiguration(false),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080061 mHal3Device(NULL),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070062 mStatus(STATUS_UNINITIALIZED),
Ruben Brunk183f0562015-08-12 12:55:02 -070063 mStatusWaiters(0),
Zhijun He204e3292014-07-14 17:09:23 -070064 mUsePartialResult(false),
65 mNumPartialResults(1),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -070066 mNextResultFrameNumber(0),
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -070067 mNextReprocessResultFrameNumber(0),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -070068 mNextShutterFrameNumber(0),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070069 mListener(NULL)
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080070{
71 ATRACE_CALL();
72 camera3_callback_ops::notify = &sNotify;
73 camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
74 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
75}
76
77Camera3Device::~Camera3Device()
78{
79 ATRACE_CALL();
80 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
81 disconnect();
82}
83
Igor Murashkin71381052013-03-04 14:53:08 -080084int Camera3Device::getId() const {
85 return mId;
86}
87
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080088/**
89 * CameraDeviceBase interface
90 */
91
Yin-Chia Yehe074a932015-01-30 10:29:02 -080092status_t Camera3Device::initialize(CameraModule *module)
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080093{
94 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -070095 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080096 Mutex::Autolock l(mLock);
97
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080098 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080099 if (mStatus != STATUS_UNINITIALIZED) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700100 CLOGE("Already initialized!");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800101 return INVALID_OPERATION;
102 }
103
104 /** Open HAL device */
105
106 status_t res;
107 String8 deviceName = String8::format("%d", mId);
108
109 camera3_device_t *device;
110
Zhijun He213ce792013-11-19 08:45:15 -0800111 ATRACE_BEGIN("camera3->open");
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800112 res = module->open(deviceName.string(),
113 reinterpret_cast<hw_device_t**>(&device));
Zhijun He213ce792013-11-19 08:45:15 -0800114 ATRACE_END();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800115
116 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700117 SET_ERR_L("Could not open camera: %s (%d)", strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800118 return res;
119 }
120
121 /** Cross-check device version */
Zhijun He95dd5ba2014-03-26 18:18:00 -0700122 if (device->common.version < CAMERA_DEVICE_API_VERSION_3_0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700123 SET_ERR_L("Could not open camera: "
Zhijun He95dd5ba2014-03-26 18:18:00 -0700124 "Camera device should be at least %x, reports %x instead",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700125 CAMERA_DEVICE_API_VERSION_3_0,
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800126 device->common.version);
127 device->common.close(&device->common);
128 return BAD_VALUE;
129 }
130
131 camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800132 res = CameraService::filterGetInfoErrorCode(module->getCameraInfo(
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700133 mId, &info));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800134 if (res != OK) return res;
135
136 if (info.device_version != device->common.version) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700137 SET_ERR_L("HAL reporting mismatched camera_info version (%x)"
138 " and device version (%x).",
Zhijun He95dd5ba2014-03-26 18:18:00 -0700139 info.device_version, device->common.version);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800140 device->common.close(&device->common);
141 return BAD_VALUE;
142 }
143
144 /** Initialize device with callback functions */
145
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700146 ATRACE_BEGIN("camera3->initialize");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800147 res = device->ops->initialize(device, this);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700148 ATRACE_END();
149
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800150 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700151 SET_ERR_L("Unable to initialize HAL device: %s (%d)",
152 strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800153 device->common.close(&device->common);
154 return BAD_VALUE;
155 }
156
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700157 /** Start up status tracker thread */
158 mStatusTracker = new StatusTracker(this);
159 res = mStatusTracker->run(String8::format("C3Dev-%d-Status", mId).string());
160 if (res != OK) {
161 SET_ERR_L("Unable to start status tracking thread: %s (%d)",
162 strerror(-res), res);
163 device->common.close(&device->common);
164 mStatusTracker.clear();
165 return res;
166 }
167
Chien-Yu Chenab5135b2015-06-30 11:20:58 -0700168 bool aeLockAvailable = false;
169 camera_metadata_ro_entry aeLockAvailableEntry;
170 res = find_camera_metadata_ro_entry(info.static_camera_characteristics,
171 ANDROID_CONTROL_AE_LOCK_AVAILABLE, &aeLockAvailableEntry);
172 if (res == OK && aeLockAvailableEntry.count > 0) {
173 aeLockAvailable = (aeLockAvailableEntry.data.u8[0] ==
174 ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE);
175 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800176
Chien-Yu Chenab5135b2015-06-30 11:20:58 -0700177 /** Start up request queue thread */
178 mRequestThread = new RequestThread(this, mStatusTracker, device, aeLockAvailable);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800179 res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800180 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700181 SET_ERR_L("Unable to start request queue thread: %s (%d)",
182 strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800183 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800184 mRequestThread.clear();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800185 return res;
186 }
187
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700188 mPreparerThread = new PreparerThread();
189
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800190 /** Everything is good to go */
191
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700192 mDeviceVersion = device->common.version;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800193 mDeviceInfo = info.static_camera_characteristics;
194 mHal3Device = device;
Ruben Brunk183f0562015-08-12 12:55:02 -0700195
196 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800197 mNextStreamId = 0;
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -0700198 mDummyStreamId = NO_STREAM;
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -0700199 mNeedConfig = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700200 mPauseStateNotify = false;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800201
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700202 // Will the HAL be sending in early partial result metadata?
Zhijun He204e3292014-07-14 17:09:23 -0700203 if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
204 camera_metadata_entry partialResultsCount =
205 mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
206 if (partialResultsCount.count > 0) {
207 mNumPartialResults = partialResultsCount.data.i32[0];
208 mUsePartialResult = (mNumPartialResults > 1);
209 }
210 } else {
211 camera_metadata_entry partialResultsQuirk =
212 mDeviceInfo.find(ANDROID_QUIRKS_USE_PARTIAL_RESULT);
213 if (partialResultsQuirk.count > 0 && partialResultsQuirk.data.u8[0] == 1) {
214 mUsePartialResult = true;
215 }
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700216 }
217
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700218 camera_metadata_entry configs =
219 mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
220 for (uint32_t i = 0; i < configs.count; i += 4) {
221 if (configs.data.i32[i] == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
222 configs.data.i32[i + 3] ==
223 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
224 mSupportedOpaqueInputSizes.add(Size(configs.data.i32[i + 1],
225 configs.data.i32[i + 2]));
226 }
227 }
228
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800229 return OK;
230}
231
232status_t Camera3Device::disconnect() {
233 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700234 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800235
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800236 ALOGV("%s: E", __FUNCTION__);
237
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700238 status_t res = OK;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800239
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700240 {
241 Mutex::Autolock l(mLock);
242 if (mStatus == STATUS_UNINITIALIZED) return res;
243
244 if (mStatus == STATUS_ACTIVE ||
245 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
246 res = mRequestThread->clearRepeatingRequests();
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700247 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700248 SET_ERR_L("Can't stop streaming");
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700249 // Continue to close device even in case of error
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700250 } else {
251 res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
252 if (res != OK) {
253 SET_ERR_L("Timeout waiting for HAL to drain");
254 // Continue to close device even in case of error
255 }
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700256 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800257 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800258
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700259 if (mStatus == STATUS_ERROR) {
260 CLOGE("Shutting down in an error state");
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700261 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700262
263 if (mStatusTracker != NULL) {
264 mStatusTracker->requestExit();
265 }
266
267 if (mRequestThread != NULL) {
268 mRequestThread->requestExit();
269 }
270
271 mOutputStreams.clear();
272 mInputStream.clear();
273 }
274
275 // Joining done without holding mLock, otherwise deadlocks may ensue
276 // as the threads try to access parent state
277 if (mRequestThread != NULL && mStatus != STATUS_ERROR) {
278 // HAL may be in a bad state, so waiting for request thread
279 // (which may be stuck in the HAL processCaptureRequest call)
280 // could be dangerous.
281 mRequestThread->join();
282 }
283
284 if (mStatusTracker != NULL) {
285 mStatusTracker->join();
286 }
287
Eino-Ville Talvalaefff1c42015-08-28 16:27:27 -0700288 camera3_device_t *hal3Device;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700289 {
290 Mutex::Autolock l(mLock);
291
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800292 mRequestThread.clear();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700293 mStatusTracker.clear();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800294
Eino-Ville Talvalaefff1c42015-08-28 16:27:27 -0700295 hal3Device = mHal3Device;
296 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800297
Eino-Ville Talvalaefff1c42015-08-28 16:27:27 -0700298 // Call close without internal mutex held, as the HAL close may need to
299 // wait on assorted callbacks,etc, to complete before it can return.
300 if (hal3Device != NULL) {
301 ATRACE_BEGIN("camera3->close");
302 hal3Device->common.close(&hal3Device->common);
303 ATRACE_END();
304 }
305
306 {
307 Mutex::Autolock l(mLock);
308 mHal3Device = NULL;
Ruben Brunk183f0562015-08-12 12:55:02 -0700309 internalUpdateStatusLocked(STATUS_UNINITIALIZED);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700310 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800311
312 ALOGV("%s: X", __FUNCTION__);
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700313 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800314}
315
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700316// For dumping/debugging only -
317// try to acquire a lock a few times, eventually give up to proceed with
318// debug/dump operations
319bool Camera3Device::tryLockSpinRightRound(Mutex& lock) {
320 bool gotLock = false;
321 for (size_t i = 0; i < kDumpLockAttempts; ++i) {
322 if (lock.tryLock() == NO_ERROR) {
323 gotLock = true;
324 break;
325 } else {
326 usleep(kDumpSleepDuration);
327 }
328 }
329 return gotLock;
330}
331
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700332Camera3Device::Size Camera3Device::getMaxJpegResolution() const {
333 int32_t maxJpegWidth = 0, maxJpegHeight = 0;
334 if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
335 const int STREAM_CONFIGURATION_SIZE = 4;
336 const int STREAM_FORMAT_OFFSET = 0;
337 const int STREAM_WIDTH_OFFSET = 1;
338 const int STREAM_HEIGHT_OFFSET = 2;
339 const int STREAM_IS_INPUT_OFFSET = 3;
340 camera_metadata_ro_entry_t availableStreamConfigs =
341 mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
342 if (availableStreamConfigs.count == 0 ||
343 availableStreamConfigs.count % STREAM_CONFIGURATION_SIZE != 0) {
344 return Size(0, 0);
345 }
346
347 // Get max jpeg size (area-wise).
348 for (size_t i=0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) {
349 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
350 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
351 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
352 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
353 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
354 && format == HAL_PIXEL_FORMAT_BLOB &&
355 (width * height > maxJpegWidth * maxJpegHeight)) {
356 maxJpegWidth = width;
357 maxJpegHeight = height;
358 }
359 }
360 } else {
361 camera_metadata_ro_entry availableJpegSizes =
362 mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
363 if (availableJpegSizes.count == 0 || availableJpegSizes.count % 2 != 0) {
364 return Size(0, 0);
365 }
366
367 // Get max jpeg size (area-wise).
368 for (size_t i = 0; i < availableJpegSizes.count; i += 2) {
369 if ((availableJpegSizes.data.i32[i] * availableJpegSizes.data.i32[i + 1])
370 > (maxJpegWidth * maxJpegHeight)) {
371 maxJpegWidth = availableJpegSizes.data.i32[i];
372 maxJpegHeight = availableJpegSizes.data.i32[i + 1];
373 }
374 }
375 }
376 return Size(maxJpegWidth, maxJpegHeight);
377}
378
Zhijun Hef7da0962014-04-24 13:27:56 -0700379ssize_t Camera3Device::getJpegBufferSize(uint32_t width, uint32_t height) const {
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700380 // Get max jpeg size (area-wise).
381 Size maxJpegResolution = getMaxJpegResolution();
382 if (maxJpegResolution.width == 0) {
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700383 ALOGE("%s: Camera %d: Can't find valid available jpeg sizes in static metadata!",
Zhijun Hef7da0962014-04-24 13:27:56 -0700384 __FUNCTION__, mId);
385 return BAD_VALUE;
386 }
387
Zhijun Hef7da0962014-04-24 13:27:56 -0700388 // Get max jpeg buffer size
389 ssize_t maxJpegBufferSize = 0;
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700390 camera_metadata_ro_entry jpegBufMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE);
391 if (jpegBufMaxSize.count == 0) {
Zhijun Hef7da0962014-04-24 13:27:56 -0700392 ALOGE("%s: Camera %d: Can't find maximum JPEG size in static metadata!", __FUNCTION__, mId);
393 return BAD_VALUE;
394 }
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700395 maxJpegBufferSize = jpegBufMaxSize.data.i32[0];
Yin-Chia Yeh0c4e56d2015-01-09 15:21:27 -0800396 assert(kMinJpegBufferSize < maxJpegBufferSize);
Zhijun Hef7da0962014-04-24 13:27:56 -0700397
398 // Calculate final jpeg buffer size for the given resolution.
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700399 float scaleFactor = ((float) (width * height)) /
400 (maxJpegResolution.width * maxJpegResolution.height);
Yin-Chia Yeh0c4e56d2015-01-09 15:21:27 -0800401 ssize_t jpegBufferSize = scaleFactor * (maxJpegBufferSize - kMinJpegBufferSize) +
402 kMinJpegBufferSize;
Zhijun Hef7da0962014-04-24 13:27:56 -0700403 if (jpegBufferSize > maxJpegBufferSize) {
404 jpegBufferSize = maxJpegBufferSize;
Zhijun Hef7da0962014-04-24 13:27:56 -0700405 }
406
407 return jpegBufferSize;
408}
409
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700410ssize_t Camera3Device::getPointCloudBufferSize() const {
411 const int FLOATS_PER_POINT=4;
412 camera_metadata_ro_entry maxPointCount = mDeviceInfo.find(ANDROID_DEPTH_MAX_DEPTH_SAMPLES);
413 if (maxPointCount.count == 0) {
414 ALOGE("%s: Camera %d: Can't find maximum depth point cloud size in static metadata!",
415 __FUNCTION__, mId);
416 return BAD_VALUE;
417 }
418 ssize_t maxBytesForPointCloud = sizeof(android_depth_points) +
419 maxPointCount.data.i32[0] * sizeof(float) * FLOATS_PER_POINT;
420 return maxBytesForPointCloud;
421}
422
423
424
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800425status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
426 ATRACE_CALL();
427 (void)args;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700428
429 // Try to lock, but continue in case of failure (to avoid blocking in
430 // deadlocks)
431 bool gotInterfaceLock = tryLockSpinRightRound(mInterfaceLock);
432 bool gotLock = tryLockSpinRightRound(mLock);
433
434 ALOGW_IF(!gotInterfaceLock,
435 "Camera %d: %s: Unable to lock interface lock, proceeding anyway",
436 mId, __FUNCTION__);
437 ALOGW_IF(!gotLock,
438 "Camera %d: %s: Unable to lock main lock, proceeding anyway",
439 mId, __FUNCTION__);
440
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800441 String8 lines;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800442
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800443 const char *status =
444 mStatus == STATUS_ERROR ? "ERROR" :
445 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700446 mStatus == STATUS_UNCONFIGURED ? "UNCONFIGURED" :
447 mStatus == STATUS_CONFIGURED ? "CONFIGURED" :
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800448 mStatus == STATUS_ACTIVE ? "ACTIVE" :
449 "Unknown";
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700450
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800451 lines.appendFormat(" Device status: %s\n", status);
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700452 if (mStatus == STATUS_ERROR) {
453 lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
454 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800455 lines.appendFormat(" Stream configuration:\n");
Zhijun He1fa89992015-06-01 15:44:31 -0700456 lines.appendFormat(" Operation mode: %s \n", mIsConstrainedHighSpeedConfiguration ?
Eino-Ville Talvala9a179412015-06-09 13:15:16 -0700457 "CONSTRAINED HIGH SPEED VIDEO" : "NORMAL");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800458
459 if (mInputStream != NULL) {
460 write(fd, lines.string(), lines.size());
461 mInputStream->dump(fd, args);
462 } else {
463 lines.appendFormat(" No input stream.\n");
464 write(fd, lines.string(), lines.size());
465 }
466 for (size_t i = 0; i < mOutputStreams.size(); i++) {
467 mOutputStreams[i]->dump(fd,args);
468 }
469
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700470 lines = String8(" In-flight requests:\n");
471 if (mInFlightMap.size() == 0) {
472 lines.append(" None\n");
473 } else {
474 for (size_t i = 0; i < mInFlightMap.size(); i++) {
475 InFlightRequest r = mInFlightMap.valueAt(i);
Colin Crosse5729fa2014-03-21 15:04:25 -0700476 lines.appendFormat(" Frame %d | Timestamp: %" PRId64 ", metadata"
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700477 " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
Chien-Yu Chen43e69a62014-11-25 16:38:33 -0800478 r.shutterTimestamp, r.haveResultMetadata ? "true" : "false",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700479 r.numBuffersLeft);
480 }
481 }
482 write(fd, lines.string(), lines.size());
483
Igor Murashkin1e479c02013-09-06 16:55:14 -0700484 {
485 lines = String8(" Last request sent:\n");
486 write(fd, lines.string(), lines.size());
487
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700488 CameraMetadata lastRequest = getLatestRequestLocked();
Igor Murashkin1e479c02013-09-06 16:55:14 -0700489 lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
490 }
491
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800492 if (mHal3Device != NULL) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700493 lines = String8(" HAL device dump:\n");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800494 write(fd, lines.string(), lines.size());
495 mHal3Device->ops->dump(mHal3Device, fd);
496 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800497
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700498 if (gotLock) mLock.unlock();
499 if (gotInterfaceLock) mInterfaceLock.unlock();
500
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800501 return OK;
502}
503
504const CameraMetadata& Camera3Device::info() const {
505 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800506 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
507 mStatus == STATUS_ERROR)) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700508 ALOGW("%s: Access to static info %s!", __FUNCTION__,
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800509 mStatus == STATUS_ERROR ?
510 "when in error state" : "before init");
511 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800512 return mDeviceInfo;
513}
514
Jianing Wei90e59c92014-03-12 18:29:36 -0700515status_t Camera3Device::checkStatusOkToCaptureLocked() {
516 switch (mStatus) {
517 case STATUS_ERROR:
518 CLOGE("Device has encountered a serious error");
519 return INVALID_OPERATION;
520 case STATUS_UNINITIALIZED:
521 CLOGE("Device not initialized");
522 return INVALID_OPERATION;
523 case STATUS_UNCONFIGURED:
524 case STATUS_CONFIGURED:
525 case STATUS_ACTIVE:
526 // OK
527 break;
528 default:
529 SET_ERR_L("Unexpected status: %d", mStatus);
530 return INVALID_OPERATION;
531 }
532 return OK;
533}
534
535status_t Camera3Device::convertMetadataListToRequestListLocked(
536 const List<const CameraMetadata> &metadataList, RequestList *requestList) {
537 if (requestList == NULL) {
538 CLOGE("requestList cannot be NULL.");
539 return BAD_VALUE;
540 }
541
Jianing Weicb0652e2014-03-12 18:29:36 -0700542 int32_t burstId = 0;
Jianing Wei90e59c92014-03-12 18:29:36 -0700543 for (List<const CameraMetadata>::const_iterator it = metadataList.begin();
544 it != metadataList.end(); ++it) {
545 sp<CaptureRequest> newRequest = setUpRequestLocked(*it);
546 if (newRequest == 0) {
547 CLOGE("Can't create capture request");
548 return BAD_VALUE;
549 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700550
551 // Setup burst Id and request Id
552 newRequest->mResultExtras.burstId = burstId++;
553 if (it->exists(ANDROID_REQUEST_ID)) {
554 if (it->find(ANDROID_REQUEST_ID).count == 0) {
555 CLOGE("RequestID entry exists; but must not be empty in metadata");
556 return BAD_VALUE;
557 }
558 newRequest->mResultExtras.requestId = it->find(ANDROID_REQUEST_ID).data.i32[0];
559 } else {
560 CLOGE("RequestID does not exist in metadata");
561 return BAD_VALUE;
562 }
563
Jianing Wei90e59c92014-03-12 18:29:36 -0700564 requestList->push_back(newRequest);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700565
566 ALOGV("%s: requestId = %" PRId32, __FUNCTION__, newRequest->mResultExtras.requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700567 }
568 return OK;
569}
570
Jianing Weicb0652e2014-03-12 18:29:36 -0700571status_t Camera3Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800572 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800573
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700574 List<const CameraMetadata> requests;
575 requests.push_back(request);
576 return captureList(requests, /*lastFrameNumber*/NULL);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800577}
578
Jianing Wei90e59c92014-03-12 18:29:36 -0700579status_t Camera3Device::submitRequestsHelper(
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700580 const List<const CameraMetadata> &requests, bool repeating,
581 /*out*/
582 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700583 ATRACE_CALL();
584 Mutex::Autolock il(mInterfaceLock);
585 Mutex::Autolock l(mLock);
586
587 status_t res = checkStatusOkToCaptureLocked();
588 if (res != OK) {
589 // error logged by previous call
590 return res;
591 }
592
593 RequestList requestList;
594
595 res = convertMetadataListToRequestListLocked(requests, /*out*/&requestList);
596 if (res != OK) {
597 // error logged by previous call
598 return res;
599 }
600
601 if (repeating) {
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700602 res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700603 } else {
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700604 res = mRequestThread->queueRequestList(requestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700605 }
606
607 if (res == OK) {
608 waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
609 if (res != OK) {
610 SET_ERR_L("Can't transition to active in %f seconds!",
611 kActiveTimeout/1e9);
612 }
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700613 ALOGV("Camera %d: Capture request %" PRId32 " enqueued", mId,
614 (*(requestList.begin()))->mResultExtras.requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700615 } else {
616 CLOGE("Cannot queue request. Impossible.");
617 return BAD_VALUE;
618 }
619
620 return res;
621}
622
Jianing Weicb0652e2014-03-12 18:29:36 -0700623status_t Camera3Device::captureList(const List<const CameraMetadata> &requests,
624 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700625 ATRACE_CALL();
626
Jianing Weicb0652e2014-03-12 18:29:36 -0700627 return submitRequestsHelper(requests, /*repeating*/false, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700628}
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800629
Jianing Weicb0652e2014-03-12 18:29:36 -0700630status_t Camera3Device::setStreamingRequest(const CameraMetadata &request,
631 int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800632 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800633
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700634 List<const CameraMetadata> requests;
635 requests.push_back(request);
636 return setStreamingRequestList(requests, /*lastFrameNumber*/NULL);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800637}
638
Jianing Weicb0652e2014-03-12 18:29:36 -0700639status_t Camera3Device::setStreamingRequestList(const List<const CameraMetadata> &requests,
640 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700641 ATRACE_CALL();
642
Jianing Weicb0652e2014-03-12 18:29:36 -0700643 return submitRequestsHelper(requests, /*repeating*/true, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700644}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800645
646sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
647 const CameraMetadata &request) {
648 status_t res;
649
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700650 if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800651 res = configureStreamsLocked();
Yin-Chia Yeh3ea3fcd2014-09-05 14:14:44 -0700652 // Stream configuration failed due to unsupported configuration.
653 // Device back to unconfigured state. Client might try other configuraitons
654 if (res == BAD_VALUE && mStatus == STATUS_UNCONFIGURED) {
655 CLOGE("No streams configured");
656 return NULL;
657 }
658 // Stream configuration failed for other reason. Fatal.
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800659 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700660 SET_ERR_L("Can't set up streams: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800661 return NULL;
662 }
Yin-Chia Yeh3ea3fcd2014-09-05 14:14:44 -0700663 // Stream configuration successfully configure to empty stream configuration.
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700664 if (mStatus == STATUS_UNCONFIGURED) {
665 CLOGE("No streams configured");
666 return NULL;
667 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800668 }
669
670 sp<CaptureRequest> newRequest = createCaptureRequest(request);
671 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800672}
673
Jianing Weicb0652e2014-03-12 18:29:36 -0700674status_t Camera3Device::clearStreamingRequest(int64_t *lastFrameNumber) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800675 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700676 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800677 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800678
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800679 switch (mStatus) {
680 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700681 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800682 return INVALID_OPERATION;
683 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700684 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800685 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700686 case STATUS_UNCONFIGURED:
687 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800688 case STATUS_ACTIVE:
689 // OK
690 break;
691 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700692 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800693 return INVALID_OPERATION;
694 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700695 ALOGV("Camera %d: Clearing repeating request", mId);
Jianing Weicb0652e2014-03-12 18:29:36 -0700696
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700697 return mRequestThread->clearRepeatingRequests(lastFrameNumber);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800698}
699
700status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
701 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700702 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800703
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700704 return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800705}
706
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700707status_t Camera3Device::createInputStream(
708 uint32_t width, uint32_t height, int format, int *id) {
709 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700710 Mutex::Autolock il(mInterfaceLock);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700711 Mutex::Autolock l(mLock);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700712 ALOGV("Camera %d: Creating new input stream %d: %d x %d, format %d",
713 mId, mNextStreamId, width, height, format);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700714
715 status_t res;
716 bool wasActive = false;
717
718 switch (mStatus) {
719 case STATUS_ERROR:
720 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
721 return INVALID_OPERATION;
722 case STATUS_UNINITIALIZED:
723 ALOGE("%s: Device not initialized", __FUNCTION__);
724 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700725 case STATUS_UNCONFIGURED:
726 case STATUS_CONFIGURED:
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700727 // OK
728 break;
729 case STATUS_ACTIVE:
730 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700731 res = internalPauseAndWaitLocked();
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700732 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700733 SET_ERR_L("Can't pause captures to reconfigure streams!");
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700734 return res;
735 }
736 wasActive = true;
737 break;
738 default:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700739 SET_ERR_L("%s: Unexpected status: %d", mStatus);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700740 return INVALID_OPERATION;
741 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700742 assert(mStatus != STATUS_ACTIVE);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700743
744 if (mInputStream != 0) {
745 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
746 return INVALID_OPERATION;
747 }
748
749 sp<Camera3InputStream> newStream = new Camera3InputStream(mNextStreamId,
750 width, height, format);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700751 newStream->setStatusTracker(mStatusTracker);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700752
753 mInputStream = newStream;
754
755 *id = mNextStreamId++;
756
757 // Continue captures if active at start
758 if (wasActive) {
759 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
760 res = configureStreamsLocked();
761 if (res != OK) {
762 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
763 __FUNCTION__, mNextStreamId, strerror(-res), res);
764 return res;
765 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700766 internalResumeLocked();
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700767 }
768
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700769 ALOGV("Camera %d: Created input stream", mId);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700770 return OK;
771}
772
Igor Murashkin2fba5842013-04-22 14:03:54 -0700773
774status_t Camera3Device::createZslStream(
775 uint32_t width, uint32_t height,
776 int depth,
777 /*out*/
778 int *id,
779 sp<Camera3ZslStream>* zslStream) {
780 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700781 Mutex::Autolock il(mInterfaceLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700782 Mutex::Autolock l(mLock);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700783 ALOGV("Camera %d: Creating ZSL stream %d: %d x %d, depth %d",
784 mId, mNextStreamId, width, height, depth);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700785
786 status_t res;
787 bool wasActive = false;
788
789 switch (mStatus) {
790 case STATUS_ERROR:
791 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
792 return INVALID_OPERATION;
793 case STATUS_UNINITIALIZED:
794 ALOGE("%s: Device not initialized", __FUNCTION__);
795 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700796 case STATUS_UNCONFIGURED:
797 case STATUS_CONFIGURED:
Igor Murashkin2fba5842013-04-22 14:03:54 -0700798 // OK
799 break;
800 case STATUS_ACTIVE:
801 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700802 res = internalPauseAndWaitLocked();
Igor Murashkin2fba5842013-04-22 14:03:54 -0700803 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700804 SET_ERR_L("Can't pause captures to reconfigure streams!");
Igor Murashkin2fba5842013-04-22 14:03:54 -0700805 return res;
806 }
807 wasActive = true;
808 break;
809 default:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700810 SET_ERR_L("Unexpected status: %d", mStatus);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700811 return INVALID_OPERATION;
812 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700813 assert(mStatus != STATUS_ACTIVE);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700814
815 if (mInputStream != 0) {
816 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
817 return INVALID_OPERATION;
818 }
819
820 sp<Camera3ZslStream> newStream = new Camera3ZslStream(mNextStreamId,
821 width, height, depth);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700822 newStream->setStatusTracker(mStatusTracker);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700823
824 res = mOutputStreams.add(mNextStreamId, newStream);
825 if (res < 0) {
826 ALOGE("%s: Can't add new stream to set: %s (%d)",
827 __FUNCTION__, strerror(-res), res);
828 return res;
829 }
830 mInputStream = newStream;
831
Yuvraj Pasie5e3d082014-04-15 18:37:45 +0530832 mNeedConfig = true;
833
Igor Murashkin2fba5842013-04-22 14:03:54 -0700834 *id = mNextStreamId++;
835 *zslStream = newStream;
836
837 // Continue captures if active at start
838 if (wasActive) {
839 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
840 res = configureStreamsLocked();
841 if (res != OK) {
842 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
843 __FUNCTION__, mNextStreamId, strerror(-res), res);
844 return res;
845 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700846 internalResumeLocked();
Igor Murashkin2fba5842013-04-22 14:03:54 -0700847 }
848
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700849 ALOGV("Camera %d: Created ZSL stream", mId);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700850 return OK;
851}
852
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700853status_t Camera3Device::createStream(sp<Surface> consumer,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800854 uint32_t width, uint32_t height, int format, android_dataspace dataSpace,
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700855 camera3_stream_rotation_t rotation, int *id) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800856 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700857 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800858 Mutex::Autolock l(mLock);
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700859 ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d",
860 mId, mNextStreamId, width, height, format, dataSpace, rotation);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800861
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800862 status_t res;
863 bool wasActive = false;
864
865 switch (mStatus) {
866 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700867 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800868 return INVALID_OPERATION;
869 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700870 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800871 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700872 case STATUS_UNCONFIGURED:
873 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800874 // OK
875 break;
876 case STATUS_ACTIVE:
877 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700878 res = internalPauseAndWaitLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800879 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700880 SET_ERR_L("Can't pause captures to reconfigure streams!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800881 return res;
882 }
883 wasActive = true;
884 break;
885 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700886 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800887 return INVALID_OPERATION;
888 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700889 assert(mStatus != STATUS_ACTIVE);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800890
891 sp<Camera3OutputStream> newStream;
892 if (format == HAL_PIXEL_FORMAT_BLOB) {
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700893 ssize_t blobBufferSize;
894 if (dataSpace != HAL_DATASPACE_DEPTH) {
895 blobBufferSize = getJpegBufferSize(width, height);
896 if (blobBufferSize <= 0) {
897 SET_ERR_L("Invalid jpeg buffer size %zd", blobBufferSize);
898 return BAD_VALUE;
899 }
900 } else {
901 blobBufferSize = getPointCloudBufferSize();
902 if (blobBufferSize <= 0) {
903 SET_ERR_L("Invalid point cloud buffer size %zd", blobBufferSize);
904 return BAD_VALUE;
905 }
Zhijun Hef7da0962014-04-24 13:27:56 -0700906 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800907 newStream = new Camera3OutputStream(mNextStreamId, consumer,
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700908 width, height, blobBufferSize, format, dataSpace, rotation);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800909 } else {
910 newStream = new Camera3OutputStream(mNextStreamId, consumer,
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700911 width, height, format, dataSpace, rotation);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800912 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700913 newStream->setStatusTracker(mStatusTracker);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800914
915 res = mOutputStreams.add(mNextStreamId, newStream);
916 if (res < 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700917 SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800918 return res;
919 }
920
921 *id = mNextStreamId++;
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -0700922 mNeedConfig = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800923
924 // Continue captures if active at start
925 if (wasActive) {
926 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
927 res = configureStreamsLocked();
928 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700929 CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
930 mNextStreamId, strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800931 return res;
932 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700933 internalResumeLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800934 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700935 ALOGV("Camera %d: Created new stream", mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800936 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800937}
938
939status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
940 ATRACE_CALL();
941 (void)outputId; (void)id;
942
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700943 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800944 return INVALID_OPERATION;
945}
946
947
948status_t Camera3Device::getStreamInfo(int id,
Eino-Ville Talvalad46a6b92015-05-14 17:26:24 -0700949 uint32_t *width, uint32_t *height,
950 uint32_t *format, android_dataspace *dataSpace) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800951 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700952 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800953 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800954
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800955 switch (mStatus) {
956 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700957 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800958 return INVALID_OPERATION;
959 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700960 CLOGE("Device not initialized!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800961 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700962 case STATUS_UNCONFIGURED:
963 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800964 case STATUS_ACTIVE:
965 // OK
966 break;
967 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700968 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800969 return INVALID_OPERATION;
970 }
971
972 ssize_t idx = mOutputStreams.indexOfKey(id);
973 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700974 CLOGE("Stream %d is unknown", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800975 return idx;
976 }
977
978 if (width) *width = mOutputStreams[idx]->getWidth();
979 if (height) *height = mOutputStreams[idx]->getHeight();
980 if (format) *format = mOutputStreams[idx]->getFormat();
Eino-Ville Talvalad46a6b92015-05-14 17:26:24 -0700981 if (dataSpace) *dataSpace = mOutputStreams[idx]->getDataSpace();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800982 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800983}
984
985status_t Camera3Device::setStreamTransform(int id,
986 int transform) {
987 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700988 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800989 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800990
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800991 switch (mStatus) {
992 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700993 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800994 return INVALID_OPERATION;
995 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700996 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800997 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700998 case STATUS_UNCONFIGURED:
999 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001000 case STATUS_ACTIVE:
1001 // OK
1002 break;
1003 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001004 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001005 return INVALID_OPERATION;
1006 }
1007
1008 ssize_t idx = mOutputStreams.indexOfKey(id);
1009 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001010 CLOGE("Stream %d does not exist",
1011 id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001012 return BAD_VALUE;
1013 }
1014
1015 return mOutputStreams.editValueAt(idx)->setTransform(transform);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001016}
1017
1018status_t Camera3Device::deleteStream(int id) {
1019 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001020 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001021 Mutex::Autolock l(mLock);
1022 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001023
Igor Murashkine2172be2013-05-28 15:31:39 -07001024 ALOGV("%s: Camera %d: Deleting stream %d", __FUNCTION__, mId, id);
1025
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001026 // CameraDevice semantics require device to already be idle before
1027 // deleteStream is called, unlike for createStream.
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001028 if (mStatus == STATUS_ACTIVE) {
Igor Murashkin52827132013-05-13 14:53:44 -07001029 ALOGV("%s: Camera %d: Device not idle", __FUNCTION__, mId);
1030 return -EBUSY;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001031 }
1032
Igor Murashkin2fba5842013-04-22 14:03:54 -07001033 sp<Camera3StreamInterface> deletedStream;
Zhijun He5f446352014-01-22 09:49:33 -08001034 ssize_t outputStreamIdx = mOutputStreams.indexOfKey(id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001035 if (mInputStream != NULL && id == mInputStream->getId()) {
1036 deletedStream = mInputStream;
1037 mInputStream.clear();
1038 } else {
Zhijun He5f446352014-01-22 09:49:33 -08001039 if (outputStreamIdx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001040 CLOGE("Stream %d does not exist", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001041 return BAD_VALUE;
1042 }
Zhijun He5f446352014-01-22 09:49:33 -08001043 }
1044
1045 // Delete output stream or the output part of a bi-directional stream.
1046 if (outputStreamIdx != NAME_NOT_FOUND) {
1047 deletedStream = mOutputStreams.editValueAt(outputStreamIdx);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001048 mOutputStreams.removeItem(id);
1049 }
1050
1051 // Free up the stream endpoint so that it can be used by some other stream
1052 res = deletedStream->disconnect();
1053 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001054 SET_ERR_L("Can't disconnect deleted stream %d", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001055 // fall through since we want to still list the stream as deleted.
1056 }
1057 mDeletedStreams.add(deletedStream);
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001058 mNeedConfig = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001059
1060 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001061}
1062
1063status_t Camera3Device::deleteReprocessStream(int id) {
1064 ATRACE_CALL();
1065 (void)id;
1066
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001067 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001068 return INVALID_OPERATION;
1069}
1070
Zhijun He1fa89992015-06-01 15:44:31 -07001071status_t Camera3Device::configureStreams(bool isConstrainedHighSpeed) {
Igor Murashkine2d167e2014-08-19 16:19:59 -07001072 ATRACE_CALL();
1073 ALOGV("%s: E", __FUNCTION__);
1074
1075 Mutex::Autolock il(mInterfaceLock);
1076 Mutex::Autolock l(mLock);
Chien-Yu Chen17338fc2015-06-18 16:30:12 -07001077
1078 if (mIsConstrainedHighSpeedConfiguration != isConstrainedHighSpeed) {
1079 mNeedConfig = true;
1080 mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
1081 }
Igor Murashkine2d167e2014-08-19 16:19:59 -07001082
1083 return configureStreamsLocked();
1084}
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001085
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001086status_t Camera3Device::getInputBufferProducer(
1087 sp<IGraphicBufferProducer> *producer) {
1088 Mutex::Autolock il(mInterfaceLock);
1089 Mutex::Autolock l(mLock);
1090
1091 if (producer == NULL) {
1092 return BAD_VALUE;
1093 } else if (mInputStream == NULL) {
1094 return INVALID_OPERATION;
1095 }
1096
1097 return mInputStream->getInputBufferProducer(producer);
1098}
1099
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001100status_t Camera3Device::createDefaultRequest(int templateId,
1101 CameraMetadata *request) {
1102 ATRACE_CALL();
Alex Rayfe7e0c62013-05-30 00:12:13 -07001103 ALOGV("%s: for template %d", __FUNCTION__, templateId);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001104 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001105 Mutex::Autolock l(mLock);
1106
1107 switch (mStatus) {
1108 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001109 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001110 return INVALID_OPERATION;
1111 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001112 CLOGE("Device is not initialized!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001113 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001114 case STATUS_UNCONFIGURED:
1115 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001116 case STATUS_ACTIVE:
1117 // OK
1118 break;
1119 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001120 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001121 return INVALID_OPERATION;
1122 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001123
Zhijun Hea1530f12014-09-14 12:44:20 -07001124 if (!mRequestTemplateCache[templateId].isEmpty()) {
1125 *request = mRequestTemplateCache[templateId];
1126 return OK;
1127 }
1128
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001129 const camera_metadata_t *rawRequest;
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001130 ATRACE_BEGIN("camera3->construct_default_request_settings");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001131 rawRequest = mHal3Device->ops->construct_default_request_settings(
1132 mHal3Device, templateId);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001133 ATRACE_END();
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001134 if (rawRequest == NULL) {
Yin-Chia Yeh0336d362015-04-14 12:34:22 -07001135 ALOGI("%s: template %d is not supported on this camera device",
1136 __FUNCTION__, templateId);
1137 return BAD_VALUE;
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001138 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001139 *request = rawRequest;
Zhijun Hea1530f12014-09-14 12:44:20 -07001140 mRequestTemplateCache[templateId] = rawRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001141
1142 return OK;
1143}
1144
1145status_t Camera3Device::waitUntilDrained() {
1146 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001147 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001148 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001149
Zhijun He69a37482014-03-23 18:44:49 -07001150 return waitUntilDrainedLocked();
1151}
1152
1153status_t Camera3Device::waitUntilDrainedLocked() {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001154 switch (mStatus) {
1155 case STATUS_UNINITIALIZED:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001156 case STATUS_UNCONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001157 ALOGV("%s: Already idle", __FUNCTION__);
1158 return OK;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001159 case STATUS_CONFIGURED:
1160 // To avoid race conditions, check with tracker to be sure
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001161 case STATUS_ERROR:
1162 case STATUS_ACTIVE:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001163 // Need to verify shut down
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001164 break;
1165 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001166 SET_ERR_L("Unexpected status: %d",mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001167 return INVALID_OPERATION;
1168 }
1169
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001170 ALOGV("%s: Camera %d: Waiting until idle", __FUNCTION__, mId);
1171 status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
Eino-Ville Talvala9c8a0912014-09-14 14:52:19 -07001172 if (res != OK) {
1173 SET_ERR_L("Error waiting for HAL to drain: %s (%d)", strerror(-res),
1174 res);
1175 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001176 return res;
1177}
1178
Ruben Brunk183f0562015-08-12 12:55:02 -07001179
1180void Camera3Device::internalUpdateStatusLocked(Status status) {
1181 mStatus = status;
1182 mRecentStatusUpdates.add(mStatus);
1183 mStatusChanged.broadcast();
1184}
1185
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001186// Pause to reconfigure
1187status_t Camera3Device::internalPauseAndWaitLocked() {
1188 mRequestThread->setPaused(true);
1189 mPauseStateNotify = true;
1190
1191 ALOGV("%s: Camera %d: Internal wait until idle", __FUNCTION__, mId);
1192 status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
1193 if (res != OK) {
1194 SET_ERR_L("Can't idle device in %f seconds!",
1195 kShutdownTimeout/1e9);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001196 }
1197
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001198 return res;
1199}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001200
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001201// Resume after internalPauseAndWaitLocked
1202status_t Camera3Device::internalResumeLocked() {
1203 status_t res;
1204
1205 mRequestThread->setPaused(false);
1206
1207 res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
1208 if (res != OK) {
1209 SET_ERR_L("Can't transition to active in %f seconds!",
1210 kActiveTimeout/1e9);
1211 }
1212 mPauseStateNotify = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001213 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001214}
1215
Ruben Brunk183f0562015-08-12 12:55:02 -07001216status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001217 status_t res = OK;
Ruben Brunk183f0562015-08-12 12:55:02 -07001218
1219 size_t startIndex = 0;
1220 if (mStatusWaiters == 0) {
1221 // Clear the list of recent statuses if there are no existing threads waiting on updates to
1222 // this status list
1223 mRecentStatusUpdates.clear();
1224 } else {
1225 // If other threads are waiting on updates to this status list, set the position of the
1226 // first element that this list will check rather than clearing the list.
1227 startIndex = mRecentStatusUpdates.size();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001228 }
1229
Ruben Brunk183f0562015-08-12 12:55:02 -07001230 mStatusWaiters++;
1231
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001232 bool stateSeen = false;
1233 do {
Ruben Brunk183f0562015-08-12 12:55:02 -07001234 if (active == (mStatus == STATUS_ACTIVE)) {
1235 // Desired state is current
1236 break;
1237 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001238
1239 res = mStatusChanged.waitRelative(mLock, timeout);
1240 if (res != OK) break;
1241
Ruben Brunk183f0562015-08-12 12:55:02 -07001242 // This is impossible, but if not, could result in subtle deadlocks and invalid state
1243 // transitions.
1244 LOG_ALWAYS_FATAL_IF(startIndex > mRecentStatusUpdates.size(),
1245 "%s: Skipping status updates in Camera3Device, may result in deadlock.",
1246 __FUNCTION__);
1247
1248 // Encountered desired state since we began waiting
1249 for (size_t i = startIndex; i < mRecentStatusUpdates.size(); i++) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001250 if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
1251 stateSeen = true;
1252 break;
1253 }
1254 }
1255 } while (!stateSeen);
1256
Ruben Brunk183f0562015-08-12 12:55:02 -07001257 mStatusWaiters--;
1258
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001259 return res;
1260}
1261
1262
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001263status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
1264 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001265 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001266
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001267 if (listener != NULL && mListener != NULL) {
1268 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
1269 }
1270 mListener = listener;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001271 mRequestThread->setNotificationListener(listener);
1272 mPreparerThread->setNotificationListener(listener);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001273
1274 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001275}
1276
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -07001277bool Camera3Device::willNotify3A() {
1278 return false;
1279}
1280
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001281status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001282 status_t res;
1283 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001284
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001285 while (mResultQueue.empty()) {
1286 res = mResultSignal.waitRelative(mOutputLock, timeout);
1287 if (res == TIMED_OUT) {
1288 return res;
1289 } else if (res != OK) {
Colin Crosse5729fa2014-03-21 15:04:25 -07001290 ALOGW("%s: Camera %d: No frame in %" PRId64 " ns: %s (%d)",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001291 __FUNCTION__, mId, timeout, strerror(-res), res);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001292 return res;
1293 }
1294 }
1295 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001296}
1297
Jianing Weicb0652e2014-03-12 18:29:36 -07001298status_t Camera3Device::getNextResult(CaptureResult *frame) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001299 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001300 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001301
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001302 if (mResultQueue.empty()) {
1303 return NOT_ENOUGH_DATA;
1304 }
1305
Jianing Weicb0652e2014-03-12 18:29:36 -07001306 if (frame == NULL) {
1307 ALOGE("%s: argument cannot be NULL", __FUNCTION__);
1308 return BAD_VALUE;
1309 }
1310
1311 CaptureResult &result = *(mResultQueue.begin());
1312 frame->mResultExtras = result.mResultExtras;
1313 frame->mMetadata.acquire(result.mMetadata);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001314 mResultQueue.erase(mResultQueue.begin());
1315
1316 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001317}
1318
1319status_t Camera3Device::triggerAutofocus(uint32_t id) {
1320 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001321 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001322
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001323 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
1324 // Mix-in this trigger into the next request and only the next request.
1325 RequestTrigger trigger[] = {
1326 {
1327 ANDROID_CONTROL_AF_TRIGGER,
1328 ANDROID_CONTROL_AF_TRIGGER_START
1329 },
1330 {
1331 ANDROID_CONTROL_AF_TRIGGER_ID,
1332 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07001333 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001334 };
1335
1336 return mRequestThread->queueTrigger(trigger,
1337 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001338}
1339
1340status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
1341 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001342 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001343
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001344 ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
1345 // Mix-in this trigger into the next request and only the next request.
1346 RequestTrigger trigger[] = {
1347 {
1348 ANDROID_CONTROL_AF_TRIGGER,
1349 ANDROID_CONTROL_AF_TRIGGER_CANCEL
1350 },
1351 {
1352 ANDROID_CONTROL_AF_TRIGGER_ID,
1353 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07001354 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001355 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001356
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001357 return mRequestThread->queueTrigger(trigger,
1358 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001359}
1360
1361status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
1362 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001363 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001364
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001365 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
1366 // Mix-in this trigger into the next request and only the next request.
1367 RequestTrigger trigger[] = {
1368 {
1369 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1370 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
1371 },
1372 {
1373 ANDROID_CONTROL_AE_PRECAPTURE_ID,
1374 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07001375 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001376 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001377
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001378 return mRequestThread->queueTrigger(trigger,
1379 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001380}
1381
1382status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
1383 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
1384 ATRACE_CALL();
1385 (void)reprocessStreamId; (void)buffer; (void)listener;
1386
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001387 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001388 return INVALID_OPERATION;
1389}
1390
Jianing Weicb0652e2014-03-12 18:29:36 -07001391status_t Camera3Device::flush(int64_t *frameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001392 ATRACE_CALL();
1393 ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001394 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001395
Eino-Ville Talvala17543512014-08-06 14:32:02 -07001396 NotificationListener* listener;
1397 {
1398 Mutex::Autolock l(mOutputLock);
1399 listener = mListener;
1400 }
1401
Zhijun He7ef20392014-04-21 16:04:17 -07001402 {
1403 Mutex::Autolock l(mLock);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07001404 mRequestThread->clear(listener, /*out*/frameNumber);
Zhijun He7ef20392014-04-21 16:04:17 -07001405 }
1406
Zhijun He491e3412013-12-27 10:57:44 -08001407 status_t res;
1408 if (mHal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_1) {
1409 res = mHal3Device->ops->flush(mHal3Device);
1410 } else {
Zhijun He7ef20392014-04-21 16:04:17 -07001411 Mutex::Autolock l(mLock);
Zhijun He69a37482014-03-23 18:44:49 -07001412 res = waitUntilDrainedLocked();
Zhijun He491e3412013-12-27 10:57:44 -08001413 }
1414
1415 return res;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001416}
1417
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001418status_t Camera3Device::prepare(int streamId) {
Ruben Brunkc78ac262015-08-13 17:58:46 -07001419 return prepare(camera3::Camera3StreamInterface::ALLOCATE_PIPELINE_MAX, streamId);
1420}
1421
1422status_t Camera3Device::prepare(int maxCount, int streamId) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001423 ATRACE_CALL();
1424 ALOGV("%s: Camera %d: Preparing stream %d", __FUNCTION__, mId, streamId);
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07001425 Mutex::Autolock il(mInterfaceLock);
1426 Mutex::Autolock l(mLock);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001427
1428 sp<Camera3StreamInterface> stream;
1429 ssize_t outputStreamIdx = mOutputStreams.indexOfKey(streamId);
1430 if (outputStreamIdx == NAME_NOT_FOUND) {
1431 CLOGE("Stream %d does not exist", streamId);
1432 return BAD_VALUE;
1433 }
1434
1435 stream = mOutputStreams.editValueAt(outputStreamIdx);
1436
1437 if (stream->isUnpreparable() || stream->hasOutstandingBuffers() ) {
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07001438 CLOGE("Stream %d has already been a request target", streamId);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001439 return BAD_VALUE;
1440 }
1441
1442 if (mRequestThread->isStreamPending(stream)) {
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07001443 CLOGE("Stream %d is already a target in a pending request", streamId);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001444 return BAD_VALUE;
1445 }
1446
Ruben Brunkc78ac262015-08-13 17:58:46 -07001447 return mPreparerThread->prepare(maxCount, stream);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001448}
1449
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001450status_t Camera3Device::tearDown(int streamId) {
1451 ATRACE_CALL();
1452 ALOGV("%s: Camera %d: Tearing down stream %d", __FUNCTION__, mId, streamId);
1453 Mutex::Autolock il(mInterfaceLock);
1454 Mutex::Autolock l(mLock);
1455
1456 // Teardown can only be accomplished on devices that don't require register_stream_buffers,
1457 // since we cannot call register_stream_buffers except right after configure_streams.
1458 if (mHal3Device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
1459 ALOGE("%s: Unable to tear down streams on device HAL v%x",
1460 __FUNCTION__, mHal3Device->common.version);
1461 return NO_INIT;
1462 }
1463
1464 sp<Camera3StreamInterface> stream;
1465 ssize_t outputStreamIdx = mOutputStreams.indexOfKey(streamId);
1466 if (outputStreamIdx == NAME_NOT_FOUND) {
1467 CLOGE("Stream %d does not exist", streamId);
1468 return BAD_VALUE;
1469 }
1470
1471 stream = mOutputStreams.editValueAt(outputStreamIdx);
1472
1473 if (stream->hasOutstandingBuffers() || mRequestThread->isStreamPending(stream)) {
1474 CLOGE("Stream %d is a target of a in-progress request", streamId);
1475 return BAD_VALUE;
1476 }
1477
1478 return stream->tearDown();
1479}
1480
Zhijun He204e3292014-07-14 17:09:23 -07001481uint32_t Camera3Device::getDeviceVersion() {
1482 ATRACE_CALL();
1483 Mutex::Autolock il(mInterfaceLock);
1484 return mDeviceVersion;
1485}
1486
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001487/**
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001488 * Methods called by subclasses
1489 */
1490
1491void Camera3Device::notifyStatus(bool idle) {
1492 {
1493 // Need mLock to safely update state and synchronize to current
1494 // state of methods in flight.
1495 Mutex::Autolock l(mLock);
1496 // We can get various system-idle notices from the status tracker
1497 // while starting up. Only care about them if we've actually sent
1498 // in some requests recently.
1499 if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
1500 return;
1501 }
1502 ALOGV("%s: Camera %d: Now %s", __FUNCTION__, mId,
1503 idle ? "idle" : "active");
Ruben Brunk183f0562015-08-12 12:55:02 -07001504 internalUpdateStatusLocked(idle ? STATUS_CONFIGURED : STATUS_ACTIVE);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001505
1506 // Skip notifying listener if we're doing some user-transparent
1507 // state changes
1508 if (mPauseStateNotify) return;
1509 }
1510 NotificationListener *listener;
1511 {
1512 Mutex::Autolock l(mOutputLock);
1513 listener = mListener;
1514 }
1515 if (idle && listener != NULL) {
1516 listener->notifyIdle();
1517 }
1518}
1519
1520/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001521 * Camera3Device private methods
1522 */
1523
1524sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
1525 const CameraMetadata &request) {
1526 ATRACE_CALL();
1527 status_t res;
1528
1529 sp<CaptureRequest> newRequest = new CaptureRequest;
1530 newRequest->mSettings = request;
1531
1532 camera_metadata_entry_t inputStreams =
1533 newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
1534 if (inputStreams.count > 0) {
1535 if (mInputStream == NULL ||
Zhijun Hed1d64672013-09-06 15:00:01 -07001536 mInputStream->getId() != inputStreams.data.i32[0]) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001537 CLOGE("Request references unknown input stream %d",
1538 inputStreams.data.u8[0]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001539 return NULL;
1540 }
1541 // Lazy completion of stream configuration (allocation/registration)
1542 // on first use
1543 if (mInputStream->isConfiguring()) {
1544 res = mInputStream->finishConfiguration(mHal3Device);
1545 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001546 SET_ERR_L("Unable to finish configuring input stream %d:"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001547 " %s (%d)",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001548 mInputStream->getId(), strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001549 return NULL;
1550 }
1551 }
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001552 // Check if stream is being prepared
1553 if (mInputStream->isPreparing()) {
1554 CLOGE("Request references an input stream that's being prepared!");
1555 return NULL;
1556 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001557
1558 newRequest->mInputStream = mInputStream;
1559 newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
1560 }
1561
1562 camera_metadata_entry_t streams =
1563 newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
1564 if (streams.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001565 CLOGE("Zero output streams specified!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001566 return NULL;
1567 }
1568
1569 for (size_t i = 0; i < streams.count; i++) {
Zhijun Hed1d64672013-09-06 15:00:01 -07001570 int idx = mOutputStreams.indexOfKey(streams.data.i32[i]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001571 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001572 CLOGE("Request references unknown stream %d",
1573 streams.data.u8[i]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001574 return NULL;
1575 }
Igor Murashkin2fba5842013-04-22 14:03:54 -07001576 sp<Camera3OutputStreamInterface> stream =
1577 mOutputStreams.editValueAt(idx);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001578
1579 // Lazy completion of stream configuration (allocation/registration)
1580 // on first use
1581 if (stream->isConfiguring()) {
1582 res = stream->finishConfiguration(mHal3Device);
1583 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001584 SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
1585 stream->getId(), strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001586 return NULL;
1587 }
1588 }
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001589 // Check if stream is being prepared
1590 if (stream->isPreparing()) {
1591 CLOGE("Request references an output stream that's being prepared!");
1592 return NULL;
1593 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001594
1595 newRequest->mOutputStreams.push(stream);
1596 }
1597 newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
1598
1599 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001600}
1601
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001602bool Camera3Device::isOpaqueInputSizeSupported(uint32_t width, uint32_t height) {
1603 for (uint32_t i = 0; i < mSupportedOpaqueInputSizes.size(); i++) {
1604 Size size = mSupportedOpaqueInputSizes[i];
1605 if (size.width == width && size.height == height) {
1606 return true;
1607 }
1608 }
1609
1610 return false;
1611}
1612
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001613status_t Camera3Device::configureStreamsLocked() {
1614 ATRACE_CALL();
1615 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001616
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001617 if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001618 CLOGE("Not idle");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001619 return INVALID_OPERATION;
1620 }
1621
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001622 if (!mNeedConfig) {
1623 ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
1624 return OK;
1625 }
1626
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07001627 // Workaround for device HALv3.2 or older spec bug - zero streams requires
1628 // adding a dummy stream instead.
1629 // TODO: Bug: 17321404 for fixing the HAL spec and removing this workaround.
1630 if (mOutputStreams.size() == 0) {
1631 addDummyStreamLocked();
1632 } else {
1633 tryRemoveDummyStreamLocked();
1634 }
1635
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001636 // Start configuring the streams
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001637 ALOGV("%s: Camera %d: Starting stream configuration", __FUNCTION__, mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001638
1639 camera3_stream_configuration config;
Zhijun He1fa89992015-06-01 15:44:31 -07001640 config.operation_mode = mIsConstrainedHighSpeedConfiguration ?
1641 CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE :
1642 CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001643 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
1644
1645 Vector<camera3_stream_t*> streams;
1646 streams.setCapacity(config.num_streams);
1647
1648 if (mInputStream != NULL) {
1649 camera3_stream_t *inputStream;
1650 inputStream = mInputStream->startConfiguration();
1651 if (inputStream == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001652 SET_ERR_L("Can't start input stream configuration");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001653 return INVALID_OPERATION;
1654 }
1655 streams.add(inputStream);
1656 }
1657
1658 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Igor Murashkin2fba5842013-04-22 14:03:54 -07001659
1660 // Don't configure bidi streams twice, nor add them twice to the list
1661 if (mOutputStreams[i].get() ==
1662 static_cast<Camera3StreamInterface*>(mInputStream.get())) {
1663
1664 config.num_streams--;
1665 continue;
1666 }
1667
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001668 camera3_stream_t *outputStream;
1669 outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
1670 if (outputStream == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001671 SET_ERR_L("Can't start output stream configuration");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001672 return INVALID_OPERATION;
1673 }
1674 streams.add(outputStream);
1675 }
1676
1677 config.streams = streams.editArray();
1678
1679 // Do the HAL configuration; will potentially touch stream
1680 // max_buffers, usage, priv fields.
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001681 ATRACE_BEGIN("camera3->configure_streams");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001682 res = mHal3Device->ops->configure_streams(mHal3Device, &config);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001683 ATRACE_END();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001684
Eino-Ville Talvala17543512014-08-06 14:32:02 -07001685 if (res == BAD_VALUE) {
1686 // HAL rejected this set of streams as unsupported, clean up config
1687 // attempt and return to unconfigured state
1688 if (mInputStream != NULL && mInputStream->isConfiguring()) {
1689 res = mInputStream->cancelConfiguration();
1690 if (res != OK) {
1691 SET_ERR_L("Can't cancel configuring input stream %d: %s (%d)",
1692 mInputStream->getId(), strerror(-res), res);
1693 return res;
1694 }
1695 }
1696
1697 for (size_t i = 0; i < mOutputStreams.size(); i++) {
1698 sp<Camera3OutputStreamInterface> outputStream =
1699 mOutputStreams.editValueAt(i);
1700 if (outputStream->isConfiguring()) {
1701 res = outputStream->cancelConfiguration();
1702 if (res != OK) {
1703 SET_ERR_L(
1704 "Can't cancel configuring output stream %d: %s (%d)",
1705 outputStream->getId(), strerror(-res), res);
1706 return res;
1707 }
1708 }
1709 }
1710
1711 // Return state to that at start of call, so that future configures
1712 // properly clean things up
Ruben Brunk183f0562015-08-12 12:55:02 -07001713 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07001714 mNeedConfig = true;
1715
1716 ALOGV("%s: Camera %d: Stream configuration failed", __FUNCTION__, mId);
1717 return BAD_VALUE;
1718 } else if (res != OK) {
1719 // Some other kind of error from configure_streams - this is not
1720 // expected
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001721 SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
1722 strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001723 return res;
1724 }
1725
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07001726 // Finish all stream configuration immediately.
1727 // TODO: Try to relax this later back to lazy completion, which should be
1728 // faster
1729
Igor Murashkin073f8572013-05-02 14:59:28 -07001730 if (mInputStream != NULL && mInputStream->isConfiguring()) {
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07001731 res = mInputStream->finishConfiguration(mHal3Device);
1732 if (res != OK) {
1733 SET_ERR_L("Can't finish configuring input stream %d: %s (%d)",
1734 mInputStream->getId(), strerror(-res), res);
1735 return res;
1736 }
1737 }
1738
1739 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Igor Murashkin073f8572013-05-02 14:59:28 -07001740 sp<Camera3OutputStreamInterface> outputStream =
1741 mOutputStreams.editValueAt(i);
1742 if (outputStream->isConfiguring()) {
1743 res = outputStream->finishConfiguration(mHal3Device);
1744 if (res != OK) {
1745 SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
1746 outputStream->getId(), strerror(-res), res);
1747 return res;
1748 }
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07001749 }
1750 }
1751
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001752 // Request thread needs to know to avoid using repeat-last-settings protocol
1753 // across configure_streams() calls
1754 mRequestThread->configurationComplete();
1755
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001756 // Update device state
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001757
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001758 mNeedConfig = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001759
Ruben Brunk183f0562015-08-12 12:55:02 -07001760 internalUpdateStatusLocked((mDummyStreamId == NO_STREAM) ?
1761 STATUS_CONFIGURED : STATUS_UNCONFIGURED);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001762
1763 ALOGV("%s: Camera %d: Stream configuration complete", __FUNCTION__, mId);
1764
Zhijun He0a210512014-07-24 13:45:15 -07001765 // tear down the deleted streams after configure streams.
1766 mDeletedStreams.clear();
1767
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001768 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001769}
1770
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07001771status_t Camera3Device::addDummyStreamLocked() {
1772 ATRACE_CALL();
1773 status_t res;
1774
1775 if (mDummyStreamId != NO_STREAM) {
1776 // Should never be adding a second dummy stream when one is already
1777 // active
1778 SET_ERR_L("%s: Camera %d: A dummy stream already exists!",
1779 __FUNCTION__, mId);
1780 return INVALID_OPERATION;
1781 }
1782
1783 ALOGV("%s: Camera %d: Adding a dummy stream", __FUNCTION__, mId);
1784
1785 sp<Camera3OutputStreamInterface> dummyStream =
1786 new Camera3DummyStream(mNextStreamId);
1787
1788 res = mOutputStreams.add(mNextStreamId, dummyStream);
1789 if (res < 0) {
1790 SET_ERR_L("Can't add dummy stream to set: %s (%d)", strerror(-res), res);
1791 return res;
1792 }
1793
1794 mDummyStreamId = mNextStreamId;
1795 mNextStreamId++;
1796
1797 return OK;
1798}
1799
1800status_t Camera3Device::tryRemoveDummyStreamLocked() {
1801 ATRACE_CALL();
1802 status_t res;
1803
1804 if (mDummyStreamId == NO_STREAM) return OK;
1805 if (mOutputStreams.size() == 1) return OK;
1806
1807 ALOGV("%s: Camera %d: Removing the dummy stream", __FUNCTION__, mId);
1808
1809 // Ok, have a dummy stream and there's at least one other output stream,
1810 // so remove the dummy
1811
1812 sp<Camera3StreamInterface> deletedStream;
1813 ssize_t outputStreamIdx = mOutputStreams.indexOfKey(mDummyStreamId);
1814 if (outputStreamIdx == NAME_NOT_FOUND) {
1815 SET_ERR_L("Dummy stream %d does not appear to exist", mDummyStreamId);
1816 return INVALID_OPERATION;
1817 }
1818
1819 deletedStream = mOutputStreams.editValueAt(outputStreamIdx);
1820 mOutputStreams.removeItemsAt(outputStreamIdx);
1821
1822 // Free up the stream endpoint so that it can be used by some other stream
1823 res = deletedStream->disconnect();
1824 if (res != OK) {
1825 SET_ERR_L("Can't disconnect deleted dummy stream %d", mDummyStreamId);
1826 // fall through since we want to still list the stream as deleted.
1827 }
1828 mDeletedStreams.add(deletedStream);
1829 mDummyStreamId = NO_STREAM;
1830
1831 return res;
1832}
1833
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001834void Camera3Device::setErrorState(const char *fmt, ...) {
1835 Mutex::Autolock l(mLock);
1836 va_list args;
1837 va_start(args, fmt);
1838
1839 setErrorStateLockedV(fmt, args);
1840
1841 va_end(args);
1842}
1843
1844void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
1845 Mutex::Autolock l(mLock);
1846 setErrorStateLockedV(fmt, args);
1847}
1848
1849void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
1850 va_list args;
1851 va_start(args, fmt);
1852
1853 setErrorStateLockedV(fmt, args);
1854
1855 va_end(args);
1856}
1857
1858void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001859 // Print out all error messages to log
1860 String8 errorCause = String8::formatV(fmt, args);
1861 ALOGE("Camera %d: %s", mId, errorCause.string());
1862
1863 // But only do error state transition steps for the first error
Zhijun Heb05eeae2013-06-06 13:51:22 -07001864 if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001865
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001866 mErrorCause = errorCause;
1867
1868 mRequestThread->setPaused(true);
Ruben Brunk183f0562015-08-12 12:55:02 -07001869 internalUpdateStatusLocked(STATUS_ERROR);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07001870
1871 // Notify upstream about a device error
1872 if (mListener != NULL) {
1873 mListener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
1874 CaptureResultExtras());
1875 }
1876
1877 // Save stack trace. View by dumping it later.
1878 CameraTraces::saveTrace();
1879 // TODO: consider adding errorCause and client pid/procname
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001880}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001881
1882/**
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001883 * In-flight request management
1884 */
1885
Jianing Weicb0652e2014-03-12 18:29:36 -07001886status_t Camera3Device::registerInFlight(uint32_t frameNumber,
Chien-Yu Chend196d612015-06-22 19:49:01 -07001887 int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
1888 const AeTriggerCancelOverride_t &aeTriggerCancelOverride) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001889 ATRACE_CALL();
1890 Mutex::Autolock l(mInFlightLock);
1891
1892 ssize_t res;
Chien-Yu Chend196d612015-06-22 19:49:01 -07001893 res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
1894 aeTriggerCancelOverride));
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001895 if (res < 0) return res;
1896
1897 return OK;
1898}
1899
1900/**
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001901 * Check if all 3A fields are ready, and send off a partial 3A-only result
1902 * to the output frame queue
1903 */
Zhijun He204e3292014-07-14 17:09:23 -07001904bool Camera3Device::processPartial3AResult(
Jianing Weicb0652e2014-03-12 18:29:36 -07001905 uint32_t frameNumber,
1906 const CameraMetadata& partial, const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001907
1908 // Check if all 3A states are present
1909 // The full list of fields is
1910 // android.control.afMode
1911 // android.control.awbMode
1912 // android.control.aeState
1913 // android.control.awbState
1914 // android.control.afState
1915 // android.control.afTriggerID
1916 // android.control.aePrecaptureID
1917 // TODO: Add android.control.aeMode
1918
1919 bool gotAllStates = true;
1920
1921 uint8_t afMode;
1922 uint8_t awbMode;
1923 uint8_t aeState;
1924 uint8_t afState;
1925 uint8_t awbState;
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001926
1927 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE,
1928 &afMode, frameNumber);
1929
1930 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE,
1931 &awbMode, frameNumber);
1932
1933 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE,
1934 &aeState, frameNumber);
1935
1936 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE,
1937 &afState, frameNumber);
1938
1939 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE,
1940 &awbState, frameNumber);
1941
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001942 if (!gotAllStates) return false;
1943
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001944 ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, "
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001945 "AF state %d, AE state %d, AWB state %d, "
1946 "AF trigger %d, AE precapture trigger %d",
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07001947 __FUNCTION__, mId, frameNumber, resultExtras.requestId,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001948 afMode, awbMode,
1949 afState, aeState, awbState,
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07001950 resultExtras.afTriggerId, resultExtras.precaptureTriggerId);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001951
1952 // Got all states, so construct a minimal result to send
1953 // In addition to the above fields, this means adding in
1954 // android.request.frameCount
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001955 // android.request.requestId
Zhijun He204e3292014-07-14 17:09:23 -07001956 // android.quirks.partialResult (for HAL version below HAL3.2)
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001957
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001958 const size_t kMinimal3AResultEntries = 10;
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001959
1960 Mutex::Autolock l(mOutputLock);
1961
Jianing Weicb0652e2014-03-12 18:29:36 -07001962 CaptureResult captureResult;
1963 captureResult.mResultExtras = resultExtras;
1964 captureResult.mMetadata = CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0);
1965 // TODO: change this to sp<CaptureResult>. This will need other changes, including,
1966 // but not limited to CameraDeviceBase::getNextResult
1967 CaptureResult& min3AResult =
1968 *mResultQueue.insert(mResultQueue.end(), captureResult);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001969
Jianing Weicb0652e2014-03-12 18:29:36 -07001970 if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_FRAME_COUNT,
1971 // TODO: This is problematic casting. Need to fix CameraMetadata.
1972 reinterpret_cast<int32_t*>(&frameNumber), frameNumber)) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001973 return false;
1974 }
1975
Jianing Weicb0652e2014-03-12 18:29:36 -07001976 int32_t requestId = resultExtras.requestId;
1977 if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_ID,
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001978 &requestId, frameNumber)) {
1979 return false;
1980 }
1981
Zhijun He204e3292014-07-14 17:09:23 -07001982 if (mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_2) {
1983 static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL;
1984 if (!insert3AResult(min3AResult.mMetadata, ANDROID_QUIRKS_PARTIAL_RESULT,
1985 &partialResult, frameNumber)) {
1986 return false;
1987 }
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001988 }
1989
Jianing Weicb0652e2014-03-12 18:29:36 -07001990 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_MODE,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001991 &afMode, frameNumber)) {
1992 return false;
1993 }
1994
Jianing Weicb0652e2014-03-12 18:29:36 -07001995 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_MODE,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001996 &awbMode, frameNumber)) {
1997 return false;
1998 }
1999
Jianing Weicb0652e2014-03-12 18:29:36 -07002000 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_STATE,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002001 &aeState, frameNumber)) {
2002 return false;
2003 }
2004
Jianing Weicb0652e2014-03-12 18:29:36 -07002005 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_STATE,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002006 &afState, frameNumber)) {
2007 return false;
2008 }
2009
Jianing Weicb0652e2014-03-12 18:29:36 -07002010 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_STATE,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002011 &awbState, frameNumber)) {
2012 return false;
2013 }
2014
Jianing Weicb0652e2014-03-12 18:29:36 -07002015 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_TRIGGER_ID,
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07002016 &resultExtras.afTriggerId, frameNumber)) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002017 return false;
2018 }
2019
Jianing Weicb0652e2014-03-12 18:29:36 -07002020 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_PRECAPTURE_ID,
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07002021 &resultExtras.precaptureTriggerId, frameNumber)) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002022 return false;
2023 }
2024
Zhijun He204e3292014-07-14 17:09:23 -07002025 // We only send the aggregated partial when all 3A related metadata are available
2026 // For both API1 and API2.
2027 // TODO: we probably should pass through all partials to API2 unconditionally.
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002028 mResultSignal.signal();
2029
2030 return true;
2031}
2032
2033template<typename T>
2034bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag,
Jianing Weicb0652e2014-03-12 18:29:36 -07002035 T* value, uint32_t frameNumber) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002036 (void) frameNumber;
2037
2038 camera_metadata_ro_entry_t entry;
2039
2040 entry = result.find(tag);
2041 if (entry.count == 0) {
2042 ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__,
2043 mId, frameNumber, get_camera_metadata_tag_name(tag));
2044 return false;
2045 }
2046
2047 if (sizeof(T) == sizeof(uint8_t)) {
2048 *value = entry.data.u8[0];
2049 } else if (sizeof(T) == sizeof(int32_t)) {
2050 *value = entry.data.i32[0];
2051 } else {
2052 ALOGE("%s: Unexpected type", __FUNCTION__);
2053 return false;
2054 }
2055 return true;
2056}
2057
2058template<typename T>
2059bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag,
Jianing Weicb0652e2014-03-12 18:29:36 -07002060 const T* value, uint32_t frameNumber) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002061 if (result.update(tag, value, 1) != NO_ERROR) {
2062 mResultQueue.erase(--mResultQueue.end(), mResultQueue.end());
2063 SET_ERR("Frame %d: Failed to set %s in partial metadata",
2064 frameNumber, get_camera_metadata_tag_name(tag));
2065 return false;
2066 }
2067 return true;
2068}
2069
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002070void Camera3Device::returnOutputBuffers(
2071 const camera3_stream_buffer_t *outputBuffers, size_t numBuffers,
2072 nsecs_t timestamp) {
2073 for (size_t i = 0; i < numBuffers; i++)
2074 {
2075 Camera3Stream *stream = Camera3Stream::cast(outputBuffers[i].stream);
2076 status_t res = stream->returnBuffer(outputBuffers[i], timestamp);
2077 // Note: stream may be deallocated at this point, if this buffer was
2078 // the last reference to it.
2079 if (res != OK) {
2080 ALOGE("Can't return buffer to its stream: %s (%d)",
2081 strerror(-res), res);
2082 }
2083 }
2084}
2085
2086
2087void Camera3Device::removeInFlightRequestIfReadyLocked(int idx) {
2088
2089 const InFlightRequest &request = mInFlightMap.valueAt(idx);
2090 const uint32_t frameNumber = mInFlightMap.keyAt(idx);
2091
2092 nsecs_t sensorTimestamp = request.sensorTimestamp;
2093 nsecs_t shutterTimestamp = request.shutterTimestamp;
2094
2095 // Check if it's okay to remove the request from InFlightMap:
2096 // In the case of a successful request:
2097 // all input and output buffers, all result metadata, shutter callback
2098 // arrived.
2099 // In the case of a unsuccessful request:
2100 // all input and output buffers arrived.
2101 if (request.numBuffersLeft == 0 &&
2102 (request.requestStatus != OK ||
2103 (request.haveResultMetadata && shutterTimestamp != 0))) {
2104 ATRACE_ASYNC_END("frame capture", frameNumber);
2105
2106 // Sanity check - if sensor timestamp matches shutter timestamp
2107 if (request.requestStatus == OK &&
2108 sensorTimestamp != shutterTimestamp) {
2109 SET_ERR("sensor timestamp (%" PRId64
2110 ") for frame %d doesn't match shutter timestamp (%" PRId64 ")",
2111 sensorTimestamp, frameNumber, shutterTimestamp);
2112 }
2113
2114 // for an unsuccessful request, it may have pending output buffers to
2115 // return.
2116 assert(request.requestStatus != OK ||
2117 request.pendingOutputBuffers.size() == 0);
2118 returnOutputBuffers(request.pendingOutputBuffers.array(),
2119 request.pendingOutputBuffers.size(), 0);
2120
2121 mInFlightMap.removeItemsAt(idx, 1);
2122
2123 ALOGVV("%s: removed frame %d from InFlightMap", __FUNCTION__, frameNumber);
2124 }
2125
2126 // Sanity check - if we have too many in-flight frames, something has
2127 // likely gone wrong
Chien-Yu Chenc96ac8d2015-08-12 16:46:24 -07002128 if (!mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() > kInFlightWarnLimit) {
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002129 CLOGE("In-flight list too large: %zu", mInFlightMap.size());
Chien-Yu Chenc96ac8d2015-08-12 16:46:24 -07002130 } else if (mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() >
2131 kInFlightWarnLimitHighSpeed) {
2132 CLOGE("In-flight list too large for high speed configuration: %zu",
2133 mInFlightMap.size());
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002134 }
2135}
2136
2137
2138void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata,
2139 CaptureResultExtras &resultExtras,
2140 CameraMetadata &collectedPartialResult,
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07002141 uint32_t frameNumber,
Chien-Yu Chend196d612015-06-22 19:49:01 -07002142 bool reprocess,
2143 const AeTriggerCancelOverride_t &aeTriggerCancelOverride) {
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002144 if (pendingMetadata.isEmpty())
2145 return;
2146
2147 Mutex::Autolock l(mOutputLock);
2148
2149 // TODO: need to track errors for tighter bounds on expected frame number
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07002150 if (reprocess) {
2151 if (frameNumber < mNextReprocessResultFrameNumber) {
2152 SET_ERR("Out-of-order reprocess capture result metadata submitted! "
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002153 "(got frame number %d, expecting %d)",
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07002154 frameNumber, mNextReprocessResultFrameNumber);
2155 return;
2156 }
2157 mNextReprocessResultFrameNumber = frameNumber + 1;
2158 } else {
2159 if (frameNumber < mNextResultFrameNumber) {
2160 SET_ERR("Out-of-order capture result metadata submitted! "
2161 "(got frame number %d, expecting %d)",
2162 frameNumber, mNextResultFrameNumber);
2163 return;
2164 }
2165 mNextResultFrameNumber = frameNumber + 1;
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002166 }
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002167
2168 CaptureResult captureResult;
2169 captureResult.mResultExtras = resultExtras;
2170 captureResult.mMetadata = pendingMetadata;
2171
2172 if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT,
2173 (int32_t*)&frameNumber, 1) != OK) {
2174 SET_ERR("Failed to set frame# in metadata (%d)",
2175 frameNumber);
2176 return;
2177 } else {
2178 ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
2179 __FUNCTION__, mId, frameNumber);
2180 }
2181
2182 // Append any previous partials to form a complete result
2183 if (mUsePartialResult && !collectedPartialResult.isEmpty()) {
2184 captureResult.mMetadata.append(collectedPartialResult);
2185 }
2186
2187 captureResult.mMetadata.sort();
2188
2189 // Check that there's a timestamp in the result metadata
2190 camera_metadata_entry entry =
2191 captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
2192 if (entry.count == 0) {
2193 SET_ERR("No timestamp provided by HAL for frame %d!",
2194 frameNumber);
2195 return;
2196 }
2197
Chien-Yu Chend196d612015-06-22 19:49:01 -07002198 overrideResultForPrecaptureCancel(&captureResult.mMetadata, aeTriggerCancelOverride);
2199
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002200 // Valid result, insert into queue
2201 List<CaptureResult>::iterator queuedResult =
2202 mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult));
2203 ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64
2204 ", burstId = %" PRId32, __FUNCTION__,
2205 queuedResult->mResultExtras.requestId,
2206 queuedResult->mResultExtras.frameNumber,
2207 queuedResult->mResultExtras.burstId);
2208
2209 mResultSignal.signal();
2210}
2211
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002212/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002213 * Camera HAL device callback methods
2214 */
2215
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002216void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002217 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002218
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002219 status_t res;
2220
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002221 uint32_t frameNumber = result->frame_number;
Zhijun Hef0d962a2014-06-30 10:24:11 -07002222 if (result->result == NULL && result->num_output_buffers == 0 &&
2223 result->input_buffer == NULL) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002224 SET_ERR("No result data provided by HAL for frame %d",
2225 frameNumber);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002226 return;
2227 }
Zhijun He204e3292014-07-14 17:09:23 -07002228
2229 // For HAL3.2 or above, If HAL doesn't support partial, it must always set
2230 // partial_result to 1 when metadata is included in this result.
2231 if (!mUsePartialResult &&
2232 mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
2233 result->result != NULL &&
2234 result->partial_result != 1) {
2235 SET_ERR("Result is malformed for frame %d: partial_result %u must be 1"
2236 " if partial result is not supported",
2237 frameNumber, result->partial_result);
2238 return;
2239 }
2240
2241 bool isPartialResult = false;
2242 CameraMetadata collectedPartialResult;
Jianing Weicb0652e2014-03-12 18:29:36 -07002243 CaptureResultExtras resultExtras;
Zhijun Hec98bd8d2014-07-07 12:44:10 -07002244 bool hasInputBufferInRequest = false;
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002245
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002246 // Get shutter timestamp and resultExtras from list of in-flight requests,
2247 // where it was added by the shutter notification for this frame. If the
2248 // shutter timestamp isn't received yet, append the output buffers to the
2249 // in-flight request and they will be returned when the shutter timestamp
2250 // arrives. Update the in-flight status and remove the in-flight entry if
2251 // all result data and shutter timestamp have been received.
2252 nsecs_t shutterTimestamp = 0;
2253
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002254 {
2255 Mutex::Autolock l(mInFlightLock);
2256 ssize_t idx = mInFlightMap.indexOfKey(frameNumber);
2257 if (idx == NAME_NOT_FOUND) {
2258 SET_ERR("Unknown frame number for capture result: %d",
2259 frameNumber);
2260 return;
2261 }
2262 InFlightRequest &request = mInFlightMap.editValueAt(idx);
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002263 ALOGVV("%s: got InFlightRequest requestId = %" PRId32
2264 ", frameNumber = %" PRId64 ", burstId = %" PRId32
2265 ", partialResultCount = %d",
2266 __FUNCTION__, request.resultExtras.requestId,
2267 request.resultExtras.frameNumber, request.resultExtras.burstId,
2268 result->partial_result);
2269 // Always update the partial count to the latest one if it's not 0
2270 // (buffers only). When framework aggregates adjacent partial results
2271 // into one, the latest partial count will be used.
2272 if (result->partial_result != 0)
2273 request.resultExtras.partialResultCount = result->partial_result;
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002274
2275 // Check if this result carries only partial metadata
Zhijun He204e3292014-07-14 17:09:23 -07002276 if (mUsePartialResult && result->result != NULL) {
2277 if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
2278 if (result->partial_result > mNumPartialResults || result->partial_result < 1) {
2279 SET_ERR("Result is malformed for frame %d: partial_result %u must be in"
2280 " the range of [1, %d] when metadata is included in the result",
2281 frameNumber, result->partial_result, mNumPartialResults);
2282 return;
2283 }
2284 isPartialResult = (result->partial_result < mNumPartialResults);
Zhijun He5d76e1a2014-07-22 16:08:13 -07002285 if (isPartialResult) {
2286 request.partialResult.collectedResult.append(result->result);
2287 }
Zhijun He204e3292014-07-14 17:09:23 -07002288 } else {
2289 camera_metadata_ro_entry_t partialResultEntry;
2290 res = find_camera_metadata_ro_entry(result->result,
2291 ANDROID_QUIRKS_PARTIAL_RESULT, &partialResultEntry);
2292 if (res != NAME_NOT_FOUND &&
2293 partialResultEntry.count > 0 &&
2294 partialResultEntry.data.u8[0] ==
2295 ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
2296 // A partial result. Flag this as such, and collect this
2297 // set of metadata into the in-flight entry.
2298 isPartialResult = true;
2299 request.partialResult.collectedResult.append(
2300 result->result);
2301 request.partialResult.collectedResult.erase(
2302 ANDROID_QUIRKS_PARTIAL_RESULT);
2303 }
2304 }
2305
2306 if (isPartialResult) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002307 // Fire off a 3A-only result if possible
Zhijun He204e3292014-07-14 17:09:23 -07002308 if (!request.partialResult.haveSent3A) {
2309 request.partialResult.haveSent3A =
2310 processPartial3AResult(frameNumber,
2311 request.partialResult.collectedResult,
Jianing Weicb0652e2014-03-12 18:29:36 -07002312 request.resultExtras);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002313 }
2314 }
2315 }
2316
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002317 shutterTimestamp = request.shutterTimestamp;
Zhijun Hec98bd8d2014-07-07 12:44:10 -07002318 hasInputBufferInRequest = request.hasInputBuffer;
Jianing Weicb0652e2014-03-12 18:29:36 -07002319
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002320 // Did we get the (final) result metadata for this capture?
Zhijun He204e3292014-07-14 17:09:23 -07002321 if (result->result != NULL && !isPartialResult) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002322 if (request.haveResultMetadata) {
2323 SET_ERR("Called multiple times with metadata for frame %d",
2324 frameNumber);
2325 return;
2326 }
Zhijun He204e3292014-07-14 17:09:23 -07002327 if (mUsePartialResult &&
2328 !request.partialResult.collectedResult.isEmpty()) {
2329 collectedPartialResult.acquire(
2330 request.partialResult.collectedResult);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002331 }
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002332 request.haveResultMetadata = true;
2333 }
2334
Zhijun Hec98bd8d2014-07-07 12:44:10 -07002335 uint32_t numBuffersReturned = result->num_output_buffers;
2336 if (result->input_buffer != NULL) {
2337 if (hasInputBufferInRequest) {
2338 numBuffersReturned += 1;
2339 } else {
2340 ALOGW("%s: Input buffer should be NULL if there is no input"
2341 " buffer sent in the request",
2342 __FUNCTION__);
2343 }
2344 }
2345 request.numBuffersLeft -= numBuffersReturned;
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002346 if (request.numBuffersLeft < 0) {
2347 SET_ERR("Too many buffers returned for frame %d",
2348 frameNumber);
2349 return;
2350 }
2351
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002352 camera_metadata_ro_entry_t entry;
2353 res = find_camera_metadata_ro_entry(result->result,
2354 ANDROID_SENSOR_TIMESTAMP, &entry);
2355 if (res == OK && entry.count == 1) {
2356 request.sensorTimestamp = entry.data.i64[0];
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002357 }
2358
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002359 // If shutter event isn't received yet, append the output buffers to
2360 // the in-flight request. Otherwise, return the output buffers to
2361 // streams.
2362 if (shutterTimestamp == 0) {
2363 request.pendingOutputBuffers.appendArray(result->output_buffers,
2364 result->num_output_buffers);
Igor Murashkind2c90692013-04-02 12:32:32 -07002365 } else {
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002366 returnOutputBuffers(result->output_buffers,
2367 result->num_output_buffers, shutterTimestamp);
Igor Murashkind2c90692013-04-02 12:32:32 -07002368 }
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002369
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002370 if (result->result != NULL && !isPartialResult) {
2371 if (shutterTimestamp == 0) {
2372 request.pendingMetadata = result->result;
2373 request.partialResult.collectedResult = collectedPartialResult;
2374 } else {
2375 CameraMetadata metadata;
2376 metadata = result->result;
2377 sendCaptureResult(metadata, request.resultExtras,
Chien-Yu Chend196d612015-06-22 19:49:01 -07002378 collectedPartialResult, frameNumber, hasInputBufferInRequest,
2379 request.aeTriggerCancelOverride);
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002380 }
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002381 }
2382
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002383 removeInFlightRequestIfReadyLocked(idx);
2384 } // scope for mInFlightLock
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002385
Zhijun Hef0d962a2014-06-30 10:24:11 -07002386 if (result->input_buffer != NULL) {
Zhijun Hec98bd8d2014-07-07 12:44:10 -07002387 if (hasInputBufferInRequest) {
2388 Camera3Stream *stream =
2389 Camera3Stream::cast(result->input_buffer->stream);
2390 res = stream->returnInputBuffer(*(result->input_buffer));
2391 // Note: stream may be deallocated at this point, if this buffer was the
2392 // last reference to it.
2393 if (res != OK) {
2394 ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
2395 " its stream:%s (%d)", __FUNCTION__,
2396 frameNumber, strerror(-res), res);
Zhijun He0ea8fa42014-07-07 17:05:38 -07002397 }
2398 } else {
2399 ALOGW("%s: Input buffer should be NULL if there is no input"
2400 " buffer sent in the request, skipping input buffer return.",
2401 __FUNCTION__);
Zhijun Hef0d962a2014-06-30 10:24:11 -07002402 }
2403 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002404}
2405
2406void Camera3Device::notify(const camera3_notify_msg *msg) {
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07002407 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002408 NotificationListener *listener;
2409 {
2410 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002411 listener = mListener;
2412 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002413
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002414 if (msg == NULL) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002415 SET_ERR("HAL sent NULL notify message!");
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002416 return;
2417 }
2418
2419 switch (msg->type) {
2420 case CAMERA3_MSG_ERROR: {
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002421 notifyError(msg->message.error, listener);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002422 break;
2423 }
2424 case CAMERA3_MSG_SHUTTER: {
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002425 notifyShutter(msg->message.shutter, listener);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002426 break;
2427 }
2428 default:
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002429 SET_ERR("Unknown notify message from HAL: %d",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002430 msg->type);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002431 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002432}
2433
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002434void Camera3Device::notifyError(const camera3_error_msg_t &msg,
2435 NotificationListener *listener) {
2436
2437 // Map camera HAL error codes to ICameraDeviceCallback error codes
2438 // Index into this with the HAL error code
2439 static const ICameraDeviceCallbacks::CameraErrorCode
2440 halErrorMap[CAMERA3_MSG_NUM_ERRORS] = {
2441 // 0 = Unused error code
2442 ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR,
2443 // 1 = CAMERA3_MSG_ERROR_DEVICE
2444 ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
2445 // 2 = CAMERA3_MSG_ERROR_REQUEST
2446 ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
2447 // 3 = CAMERA3_MSG_ERROR_RESULT
2448 ICameraDeviceCallbacks::ERROR_CAMERA_RESULT,
2449 // 4 = CAMERA3_MSG_ERROR_BUFFER
2450 ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER
2451 };
2452
2453 ICameraDeviceCallbacks::CameraErrorCode errorCode =
2454 ((msg.error_code >= 0) &&
2455 (msg.error_code < CAMERA3_MSG_NUM_ERRORS)) ?
2456 halErrorMap[msg.error_code] :
2457 ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR;
2458
2459 int streamId = 0;
2460 if (msg.error_stream != NULL) {
2461 Camera3Stream *stream =
2462 Camera3Stream::cast(msg.error_stream);
2463 streamId = stream->getId();
2464 }
2465 ALOGV("Camera %d: %s: HAL error, frame %d, stream %d: %d",
2466 mId, __FUNCTION__, msg.frame_number,
2467 streamId, msg.error_code);
2468
2469 CaptureResultExtras resultExtras;
2470 switch (errorCode) {
2471 case ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE:
2472 // SET_ERR calls notifyError
2473 SET_ERR("Camera HAL reported serious device error");
2474 break;
2475 case ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
2476 case ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
2477 case ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
2478 {
2479 Mutex::Autolock l(mInFlightLock);
2480 ssize_t idx = mInFlightMap.indexOfKey(msg.frame_number);
2481 if (idx >= 0) {
2482 InFlightRequest &r = mInFlightMap.editValueAt(idx);
2483 r.requestStatus = msg.error_code;
2484 resultExtras = r.resultExtras;
2485 } else {
2486 resultExtras.frameNumber = msg.frame_number;
2487 ALOGE("Camera %d: %s: cannot find in-flight request on "
2488 "frame %" PRId64 " error", mId, __FUNCTION__,
2489 resultExtras.frameNumber);
2490 }
2491 }
2492 if (listener != NULL) {
2493 listener->notifyError(errorCode, resultExtras);
2494 } else {
2495 ALOGE("Camera %d: %s: no listener available", mId, __FUNCTION__);
2496 }
2497 break;
2498 default:
2499 // SET_ERR calls notifyError
2500 SET_ERR("Unknown error message from HAL: %d", msg.error_code);
2501 break;
2502 }
2503}
2504
2505void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg,
2506 NotificationListener *listener) {
2507 ssize_t idx;
2508 // Verify ordering of shutter notifications
2509 {
2510 Mutex::Autolock l(mOutputLock);
2511 // TODO: need to track errors for tighter bounds on expected frame number.
2512 if (msg.frame_number < mNextShutterFrameNumber) {
2513 SET_ERR("Shutter notification out-of-order. Expected "
2514 "notification for frame %d, got frame %d",
2515 mNextShutterFrameNumber, msg.frame_number);
2516 return;
2517 }
2518 mNextShutterFrameNumber = msg.frame_number + 1;
2519 }
2520
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002521 // Set timestamp for the request in the in-flight tracking
2522 // and get the request ID to send upstream
2523 {
2524 Mutex::Autolock l(mInFlightLock);
2525 idx = mInFlightMap.indexOfKey(msg.frame_number);
2526 if (idx >= 0) {
2527 InFlightRequest &r = mInFlightMap.editValueAt(idx);
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002528
2529 ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
2530 mId, __FUNCTION__,
2531 msg.frame_number, r.resultExtras.requestId, msg.timestamp);
2532 // Call listener, if any
2533 if (listener != NULL) {
2534 listener->notifyShutter(r.resultExtras, msg.timestamp);
2535 }
2536
2537 r.shutterTimestamp = msg.timestamp;
2538
2539 // send pending result and buffers
2540 sendCaptureResult(r.pendingMetadata, r.resultExtras,
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07002541 r.partialResult.collectedResult, msg.frame_number,
Chien-Yu Chend196d612015-06-22 19:49:01 -07002542 r.hasInputBuffer, r.aeTriggerCancelOverride);
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002543 returnOutputBuffers(r.pendingOutputBuffers.array(),
2544 r.pendingOutputBuffers.size(), r.shutterTimestamp);
2545 r.pendingOutputBuffers.clear();
2546
2547 removeInFlightRequestIfReadyLocked(idx);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002548 }
2549 }
2550 if (idx < 0) {
2551 SET_ERR("Shutter notification for non-existent frame number %d",
2552 msg.frame_number);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002553 }
2554}
2555
2556
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002557CameraMetadata Camera3Device::getLatestRequestLocked() {
Igor Murashkin1e479c02013-09-06 16:55:14 -07002558 ALOGV("%s", __FUNCTION__);
2559
Igor Murashkin1e479c02013-09-06 16:55:14 -07002560 CameraMetadata retVal;
2561
2562 if (mRequestThread != NULL) {
2563 retVal = mRequestThread->getLatestRequest();
2564 }
2565
Igor Murashkin1e479c02013-09-06 16:55:14 -07002566 return retVal;
2567}
2568
Jianing Weicb0652e2014-03-12 18:29:36 -07002569
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002570/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002571 * RequestThread inner class methods
2572 */
2573
2574Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002575 sp<StatusTracker> statusTracker,
Chien-Yu Chenab5135b2015-06-30 11:20:58 -07002576 camera3_device_t *hal3Device,
2577 bool aeLockAvailable) :
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002578 Thread(/*canCallJava*/false),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002579 mParent(parent),
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002580 mStatusTracker(statusTracker),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002581 mHal3Device(hal3Device),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002582 mId(getId(parent)),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002583 mReconfigured(false),
2584 mDoPause(false),
2585 mPaused(true),
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002586 mFrameNumber(0),
Jianing Weicb0652e2014-03-12 18:29:36 -07002587 mLatestRequestId(NAME_NOT_FOUND),
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07002588 mCurrentAfTriggerId(0),
2589 mCurrentPreCaptureTriggerId(0),
Chien-Yu Chenab5135b2015-06-30 11:20:58 -07002590 mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES),
2591 mAeLockAvailable(aeLockAvailable) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002592 mStatusId = statusTracker->addComponent();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002593}
2594
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002595void Camera3Device::RequestThread::setNotificationListener(
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002596 NotificationListener *listener) {
2597 Mutex::Autolock l(mRequestLock);
2598 mListener = listener;
2599}
2600
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002601void Camera3Device::RequestThread::configurationComplete() {
2602 Mutex::Autolock l(mRequestLock);
2603 mReconfigured = true;
2604}
2605
Jianing Wei90e59c92014-03-12 18:29:36 -07002606status_t Camera3Device::RequestThread::queueRequestList(
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002607 List<sp<CaptureRequest> > &requests,
2608 /*out*/
2609 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -07002610 Mutex::Autolock l(mRequestLock);
2611 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
2612 ++it) {
2613 mRequestQueue.push_back(*it);
2614 }
2615
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002616 if (lastFrameNumber != NULL) {
2617 *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
2618 ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
2619 __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
2620 *lastFrameNumber);
2621 }
Jianing Weicb0652e2014-03-12 18:29:36 -07002622
Jianing Wei90e59c92014-03-12 18:29:36 -07002623 unpauseForNewRequests();
2624
2625 return OK;
2626}
2627
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002628
2629status_t Camera3Device::RequestThread::queueTrigger(
2630 RequestTrigger trigger[],
2631 size_t count) {
2632
2633 Mutex::Autolock l(mTriggerMutex);
2634 status_t ret;
2635
2636 for (size_t i = 0; i < count; ++i) {
2637 ret = queueTriggerLocked(trigger[i]);
2638
2639 if (ret != OK) {
2640 return ret;
2641 }
2642 }
2643
2644 return OK;
2645}
2646
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002647int Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
2648 sp<Camera3Device> d = device.promote();
2649 if (d != NULL) return d->mId;
2650 return 0;
2651}
2652
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002653status_t Camera3Device::RequestThread::queueTriggerLocked(
2654 RequestTrigger trigger) {
2655
2656 uint32_t tag = trigger.metadataTag;
2657 ssize_t index = mTriggerMap.indexOfKey(tag);
2658
2659 switch (trigger.getTagType()) {
2660 case TYPE_BYTE:
2661 // fall-through
2662 case TYPE_INT32:
2663 break;
2664 default:
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002665 ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
2666 trigger.getTagType());
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002667 return INVALID_OPERATION;
2668 }
2669
2670 /**
2671 * Collect only the latest trigger, since we only have 1 field
2672 * in the request settings per trigger tag, and can't send more than 1
2673 * trigger per request.
2674 */
2675 if (index != NAME_NOT_FOUND) {
2676 mTriggerMap.editValueAt(index) = trigger;
2677 } else {
2678 mTriggerMap.add(tag, trigger);
2679 }
2680
2681 return OK;
2682}
2683
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002684status_t Camera3Device::RequestThread::setRepeatingRequests(
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002685 const RequestList &requests,
2686 /*out*/
2687 int64_t *lastFrameNumber) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002688 Mutex::Autolock l(mRequestLock);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002689 if (lastFrameNumber != NULL) {
2690 *lastFrameNumber = mRepeatingLastFrameNumber;
2691 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002692 mRepeatingRequests.clear();
2693 mRepeatingRequests.insert(mRepeatingRequests.begin(),
2694 requests.begin(), requests.end());
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07002695
2696 unpauseForNewRequests();
2697
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002698 mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002699 return OK;
2700}
2701
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07002702bool Camera3Device::RequestThread::isRepeatingRequestLocked(const sp<CaptureRequest> requestIn) {
2703 if (mRepeatingRequests.empty()) {
2704 return false;
2705 }
2706 int32_t requestId = requestIn->mResultExtras.requestId;
2707 const RequestList &repeatRequests = mRepeatingRequests;
2708 // All repeating requests are guaranteed to have same id so only check first quest
2709 const sp<CaptureRequest> firstRequest = *repeatRequests.begin();
2710 return (firstRequest->mResultExtras.requestId == requestId);
2711}
2712
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002713status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002714 Mutex::Autolock l(mRequestLock);
2715 mRepeatingRequests.clear();
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002716 if (lastFrameNumber != NULL) {
2717 *lastFrameNumber = mRepeatingLastFrameNumber;
2718 }
2719 mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002720 return OK;
2721}
2722
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002723status_t Camera3Device::RequestThread::clear(
2724 NotificationListener *listener,
2725 /*out*/int64_t *lastFrameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002726 Mutex::Autolock l(mRequestLock);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002727 ALOGV("RequestThread::%s:", __FUNCTION__);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002728
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002729 mRepeatingRequests.clear();
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07002730
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002731 // Send errors for all requests pending in the request queue, including
2732 // pending repeating requests
2733 if (listener != NULL) {
2734 for (RequestList::iterator it = mRequestQueue.begin();
2735 it != mRequestQueue.end(); ++it) {
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07002736 // Abort the input buffers for reprocess requests.
2737 if ((*it)->mInputStream != NULL) {
2738 camera3_stream_buffer_t inputBuffer;
2739 status_t res = (*it)->mInputStream->getInputBuffer(&inputBuffer);
2740 if (res != OK) {
2741 ALOGW("%s: %d: couldn't get input buffer while clearing the request "
2742 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
2743 } else {
2744 res = (*it)->mInputStream->returnInputBuffer(inputBuffer);
2745 if (res != OK) {
2746 ALOGE("%s: %d: couldn't return input buffer while clearing the request "
2747 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
2748 }
2749 }
2750 }
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002751 // Set the frame number this request would have had, if it
2752 // had been submitted; this frame number will not be reused.
2753 // The requestId and burstId fields were set when the request was
2754 // submitted originally (in convertMetadataListToRequestListLocked)
2755 (*it)->mResultExtras.frameNumber = mFrameNumber++;
2756 listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
2757 (*it)->mResultExtras);
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07002758 }
2759 }
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002760 mRequestQueue.clear();
2761 mTriggerMap.clear();
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002762 if (lastFrameNumber != NULL) {
2763 *lastFrameNumber = mRepeatingLastFrameNumber;
2764 }
2765 mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002766 return OK;
2767}
2768
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002769void Camera3Device::RequestThread::setPaused(bool paused) {
2770 Mutex::Autolock l(mPauseLock);
2771 mDoPause = paused;
2772 mDoPauseSignal.signal();
2773}
2774
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002775status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
2776 int32_t requestId, nsecs_t timeout) {
2777 Mutex::Autolock l(mLatestRequestMutex);
2778 status_t res;
2779 while (mLatestRequestId != requestId) {
2780 nsecs_t startTime = systemTime();
2781
2782 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
2783 if (res != OK) return res;
2784
2785 timeout -= (systemTime() - startTime);
2786 }
2787
2788 return OK;
2789}
2790
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002791void Camera3Device::RequestThread::requestExit() {
2792 // Call parent to set up shutdown
2793 Thread::requestExit();
2794 // The exit from any possible waits
2795 mDoPauseSignal.signal();
2796 mRequestSignal.signal();
2797}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002798
Chien-Yu Chend196d612015-06-22 19:49:01 -07002799
2800/**
2801 * For devices <= CAMERA_DEVICE_API_VERSION_3_2, AE_PRECAPTURE_TRIGGER_CANCEL is not supported so
2802 * we need to override AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE and AE_LOCK_OFF
2803 * to AE_LOCK_ON to start cancelling AE precapture. If AE lock is not available, it still overrides
2804 * AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE but doesn't add AE_LOCK_ON to the
2805 * request.
2806 */
2807void Camera3Device::RequestThread::handleAePrecaptureCancelRequest(sp<CaptureRequest> request) {
2808 request->mAeTriggerCancelOverride.applyAeLock = false;
2809 request->mAeTriggerCancelOverride.applyAePrecaptureTrigger = false;
2810
2811 if (mHal3Device->common.version > CAMERA_DEVICE_API_VERSION_3_2) {
2812 return;
2813 }
2814
2815 camera_metadata_entry_t aePrecaptureTrigger =
2816 request->mSettings.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
2817 if (aePrecaptureTrigger.count > 0 &&
2818 aePrecaptureTrigger.data.u8[0] == ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL) {
2819 // Always override CANCEL to IDLE
2820 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
2821 request->mSettings.update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &aePrecaptureTrigger, 1);
2822 request->mAeTriggerCancelOverride.applyAePrecaptureTrigger = true;
2823 request->mAeTriggerCancelOverride.aePrecaptureTrigger =
2824 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL;
2825
2826 if (mAeLockAvailable == true) {
2827 camera_metadata_entry_t aeLock = request->mSettings.find(ANDROID_CONTROL_AE_LOCK);
2828 if (aeLock.count == 0 || aeLock.data.u8[0] == ANDROID_CONTROL_AE_LOCK_OFF) {
2829 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_ON;
2830 request->mSettings.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
2831 request->mAeTriggerCancelOverride.applyAeLock = true;
2832 request->mAeTriggerCancelOverride.aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
2833 }
2834 }
2835 }
2836}
2837
2838/**
2839 * Override result metadata for cancelling AE precapture trigger applied in
2840 * handleAePrecaptureCancelRequest().
2841 */
2842void Camera3Device::overrideResultForPrecaptureCancel(
2843 CameraMetadata *result, const AeTriggerCancelOverride_t &aeTriggerCancelOverride) {
2844 if (aeTriggerCancelOverride.applyAeLock) {
2845 // Only devices <= v3.2 should have this override
2846 assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2);
2847 result->update(ANDROID_CONTROL_AE_LOCK, &aeTriggerCancelOverride.aeLock, 1);
2848 }
2849
2850 if (aeTriggerCancelOverride.applyAePrecaptureTrigger) {
2851 // Only devices <= v3.2 should have this override
2852 assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2);
2853 result->update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
2854 &aeTriggerCancelOverride.aePrecaptureTrigger, 1);
2855 }
2856}
2857
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002858bool Camera3Device::RequestThread::threadLoop() {
2859
2860 status_t res;
2861
2862 // Handle paused state.
2863 if (waitIfPaused()) {
2864 return true;
2865 }
2866
2867 // Get work to do
2868
2869 sp<CaptureRequest> nextRequest = waitForNextRequest();
2870 if (nextRequest == NULL) {
2871 return true;
2872 }
2873
2874 // Create request to HAL
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002875 camera3_capture_request_t request = camera3_capture_request_t();
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002876 request.frame_number = nextRequest->mResultExtras.frameNumber;
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002877 Vector<camera3_stream_buffer_t> outputBuffers;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002878
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002879 // Get the request ID, if any
2880 int requestId;
2881 camera_metadata_entry_t requestIdEntry =
2882 nextRequest->mSettings.find(ANDROID_REQUEST_ID);
2883 if (requestIdEntry.count > 0) {
2884 requestId = requestIdEntry.data.i32[0];
2885 } else {
2886 ALOGW("%s: Did not have android.request.id set in the request",
2887 __FUNCTION__);
2888 requestId = NAME_NOT_FOUND;
2889 }
2890
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002891 // Insert any queued triggers (before metadata is locked)
2892 int32_t triggerCount;
2893 res = insertTriggers(nextRequest);
2894 if (res < 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002895 SET_ERR("RequestThread: Unable to insert triggers "
2896 "(capture request %d, HAL device: %s (%d)",
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002897 request.frame_number, strerror(-res), res);
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002898 cleanUpFailedRequest(request, nextRequest, outputBuffers);
2899 return false;
2900 }
2901 triggerCount = res;
2902
2903 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
2904
2905 // If the request is the same as last, or we had triggers last time
2906 if (mPrevRequest != nextRequest || triggersMixedIn) {
2907 /**
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07002908 * HAL workaround:
2909 * Insert a dummy trigger ID if a trigger is set but no trigger ID is
2910 */
2911 res = addDummyTriggerIds(nextRequest);
2912 if (res != OK) {
2913 SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
2914 "(capture request %d, HAL device: %s (%d)",
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002915 request.frame_number, strerror(-res), res);
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07002916 cleanUpFailedRequest(request, nextRequest, outputBuffers);
2917 return false;
2918 }
2919
2920 /**
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002921 * The request should be presorted so accesses in HAL
2922 * are O(logn). Sidenote, sorting a sorted metadata is nop.
2923 */
2924 nextRequest->mSettings.sort();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002925 request.settings = nextRequest->mSettings.getAndLock();
2926 mPrevRequest = nextRequest;
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002927 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
2928
2929 IF_ALOGV() {
2930 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
2931 find_camera_metadata_ro_entry(
2932 request.settings,
2933 ANDROID_CONTROL_AF_TRIGGER,
2934 &e
2935 );
2936 if (e.count > 0) {
2937 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
2938 __FUNCTION__,
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002939 request.frame_number,
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002940 e.data.u8[0]);
2941 }
2942 }
2943 } else {
2944 // leave request.settings NULL to indicate 'reuse latest given'
2945 ALOGVV("%s: Request settings are REUSED",
2946 __FUNCTION__);
2947 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002948
Zhijun Hef0d962a2014-06-30 10:24:11 -07002949 uint32_t totalNumBuffers = 0;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002950
2951 // Fill in buffers
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002952 if (nextRequest->mInputStream != NULL) {
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07002953 request.input_buffer = &nextRequest->mInputBuffer;
Zhijun Hef0d962a2014-06-30 10:24:11 -07002954 totalNumBuffers += 1;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002955 } else {
2956 request.input_buffer = NULL;
2957 }
2958
2959 outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
2960 nextRequest->mOutputStreams.size());
2961 request.output_buffers = outputBuffers.array();
2962 for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
2963 res = nextRequest->mOutputStreams.editItemAt(i)->
2964 getBuffer(&outputBuffers.editItemAt(i));
2965 if (res != OK) {
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002966 // Can't get output buffer from gralloc queue - this could be due to
2967 // abandoned queue or other consumer misbehavior, so not a fatal
2968 // error
Eino-Ville Talvala07d21692013-09-24 18:04:19 -07002969 ALOGE("RequestThread: Can't get output buffer, skipping request:"
2970 " %s (%d)", strerror(-res), res);
Eino-Ville Talvala0ec23d32015-05-28 15:15:54 -07002971 {
2972 Mutex::Autolock l(mRequestLock);
2973 if (mListener != NULL) {
2974 mListener->notifyError(
2975 ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
2976 nextRequest->mResultExtras);
2977 }
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002978 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002979 cleanUpFailedRequest(request, nextRequest, outputBuffers);
2980 return true;
2981 }
2982 request.num_output_buffers++;
2983 }
Zhijun Hef0d962a2014-06-30 10:24:11 -07002984 totalNumBuffers += request.num_output_buffers;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002985
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002986 // Log request in the in-flight queue
2987 sp<Camera3Device> parent = mParent.promote();
2988 if (parent == NULL) {
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002989 // Should not happen, and nowhere to send errors to, so just log it
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002990 CLOGE("RequestThread: Parent is gone");
2991 cleanUpFailedRequest(request, nextRequest, outputBuffers);
2992 return false;
2993 }
2994
Jianing Weicb0652e2014-03-12 18:29:36 -07002995 res = parent->registerInFlight(request.frame_number,
Zhijun Hec98bd8d2014-07-07 12:44:10 -07002996 totalNumBuffers, nextRequest->mResultExtras,
Chien-Yu Chend196d612015-06-22 19:49:01 -07002997 /*hasInput*/request.input_buffer != NULL,
2998 nextRequest->mAeTriggerCancelOverride);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002999 ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
3000 ", burstId = %" PRId32 ".",
Jianing Weicb0652e2014-03-12 18:29:36 -07003001 __FUNCTION__,
3002 nextRequest->mResultExtras.requestId, nextRequest->mResultExtras.frameNumber,
3003 nextRequest->mResultExtras.burstId);
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07003004 if (res != OK) {
3005 SET_ERR("RequestThread: Unable to register new in-flight request:"
3006 " %s (%d)", strerror(-res), res);
3007 cleanUpFailedRequest(request, nextRequest, outputBuffers);
3008 return false;
3009 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003010
Zhijun Hecc27e112013-10-03 16:12:43 -07003011 // Inform waitUntilRequestProcessed thread of a new request ID
3012 {
3013 Mutex::Autolock al(mLatestRequestMutex);
3014
3015 mLatestRequestId = requestId;
3016 mLatestRequestSignal.signal();
3017 }
3018
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003019 // Submit request and block until ready for next one
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07003020 ATRACE_ASYNC_BEGIN("frame capture", request.frame_number);
3021 ATRACE_BEGIN("camera3->process_capture_request");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003022 res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07003023 ATRACE_END();
3024
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003025 if (res != OK) {
Eino-Ville Talvala17543512014-08-06 14:32:02 -07003026 // Should only get a failure here for malformed requests or device-level
3027 // errors, so consider all errors fatal. Bad metadata failures should
3028 // come through notify.
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07003029 SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003030 " device: %s (%d)", request.frame_number, strerror(-res), res);
3031 cleanUpFailedRequest(request, nextRequest, outputBuffers);
3032 return false;
3033 }
3034
Igor Murashkin1e479c02013-09-06 16:55:14 -07003035 // Update the latest request sent to HAL
3036 if (request.settings != NULL) { // Don't update them if they were unchanged
3037 Mutex::Autolock al(mLatestRequestMutex);
3038
3039 camera_metadata_t* cloned = clone_camera_metadata(request.settings);
3040 mLatestRequest.acquire(cloned);
3041 }
3042
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003043 if (request.settings != NULL) {
3044 nextRequest->mSettings.unlock(request.settings);
3045 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003046
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07003047 // Unset as current request
3048 {
3049 Mutex::Autolock l(mRequestLock);
3050 mNextRequest.clear();
3051 }
3052
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003053 // Remove any previously queued triggers (after unlock)
3054 res = removeTriggers(mPrevRequest);
3055 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07003056 SET_ERR("RequestThread: Unable to remove triggers "
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003057 "(capture request %d, HAL device: %s (%d)",
3058 request.frame_number, strerror(-res), res);
3059 return false;
3060 }
3061 mPrevTriggers = triggerCount;
3062
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003063 return true;
3064}
3065
Igor Murashkin1e479c02013-09-06 16:55:14 -07003066CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
3067 Mutex::Autolock al(mLatestRequestMutex);
3068
3069 ALOGV("RequestThread::%s", __FUNCTION__);
3070
3071 return mLatestRequest;
3072}
3073
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07003074bool Camera3Device::RequestThread::isStreamPending(
3075 sp<Camera3StreamInterface>& stream) {
3076 Mutex::Autolock l(mRequestLock);
3077
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07003078 if (mNextRequest != nullptr) {
3079 for (const auto& s : mNextRequest->mOutputStreams) {
3080 if (stream == s) return true;
3081 }
3082 if (stream == mNextRequest->mInputStream) return true;
3083 }
3084
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07003085 for (const auto& request : mRequestQueue) {
3086 for (const auto& s : request->mOutputStreams) {
3087 if (stream == s) return true;
3088 }
3089 if (stream == request->mInputStream) return true;
3090 }
3091
3092 for (const auto& request : mRepeatingRequests) {
3093 for (const auto& s : request->mOutputStreams) {
3094 if (stream == s) return true;
3095 }
3096 if (stream == request->mInputStream) return true;
3097 }
3098
3099 return false;
3100}
Jianing Weicb0652e2014-03-12 18:29:36 -07003101
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003102void Camera3Device::RequestThread::cleanUpFailedRequest(
3103 camera3_capture_request_t &request,
3104 sp<CaptureRequest> &nextRequest,
3105 Vector<camera3_stream_buffer_t> &outputBuffers) {
3106
3107 if (request.settings != NULL) {
3108 nextRequest->mSettings.unlock(request.settings);
3109 }
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07003110 if (nextRequest->mInputStream != NULL) {
3111 nextRequest->mInputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
3112 nextRequest->mInputStream->returnInputBuffer(nextRequest->mInputBuffer);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003113 }
3114 for (size_t i = 0; i < request.num_output_buffers; i++) {
3115 outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
3116 nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
3117 outputBuffers[i], 0);
3118 }
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07003119
3120 Mutex::Autolock l(mRequestLock);
3121 mNextRequest.clear();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003122}
3123
3124sp<Camera3Device::CaptureRequest>
3125 Camera3Device::RequestThread::waitForNextRequest() {
3126 status_t res;
3127 sp<CaptureRequest> nextRequest;
3128
3129 // Optimized a bit for the simple steady-state case (single repeating
3130 // request), to avoid putting that request in the queue temporarily.
3131 Mutex::Autolock l(mRequestLock);
3132
3133 while (mRequestQueue.empty()) {
3134 if (!mRepeatingRequests.empty()) {
3135 // Always atomically enqueue all requests in a repeating request
3136 // list. Guarantees a complete in-sequence set of captures to
3137 // application.
3138 const RequestList &requests = mRepeatingRequests;
3139 RequestList::const_iterator firstRequest =
3140 requests.begin();
3141 nextRequest = *firstRequest;
3142 mRequestQueue.insert(mRequestQueue.end(),
3143 ++firstRequest,
3144 requests.end());
3145 // No need to wait any longer
Jianing Weicb0652e2014-03-12 18:29:36 -07003146
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07003147 mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
Jianing Weicb0652e2014-03-12 18:29:36 -07003148
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003149 break;
3150 }
3151
3152 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
3153
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003154 if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
3155 exitPending()) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003156 Mutex::Autolock pl(mPauseLock);
3157 if (mPaused == false) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003158 ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003159 mPaused = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003160 // Let the tracker know
3161 sp<StatusTracker> statusTracker = mStatusTracker.promote();
3162 if (statusTracker != 0) {
3163 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
3164 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003165 }
3166 // Stop waiting for now and let thread management happen
3167 return NULL;
3168 }
3169 }
3170
3171 if (nextRequest == NULL) {
3172 // Don't have a repeating request already in hand, so queue
3173 // must have an entry now.
3174 RequestList::iterator firstRequest =
3175 mRequestQueue.begin();
3176 nextRequest = *firstRequest;
3177 mRequestQueue.erase(firstRequest);
3178 }
3179
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07003180 // In case we've been unpaused by setPaused clearing mDoPause, need to
3181 // update internal pause state (capture/setRepeatingRequest unpause
3182 // directly).
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003183 Mutex::Autolock pl(mPauseLock);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003184 if (mPaused) {
3185 ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
3186 sp<StatusTracker> statusTracker = mStatusTracker.promote();
3187 if (statusTracker != 0) {
3188 statusTracker->markComponentActive(mStatusId);
3189 }
3190 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003191 mPaused = false;
3192
3193 // Check if we've reconfigured since last time, and reset the preview
3194 // request if so. Can't use 'NULL request == repeat' across configure calls.
3195 if (mReconfigured) {
3196 mPrevRequest.clear();
3197 mReconfigured = false;
3198 }
3199
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07003200 if (nextRequest != NULL) {
3201 nextRequest->mResultExtras.frameNumber = mFrameNumber++;
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07003202 nextRequest->mResultExtras.afTriggerId = mCurrentAfTriggerId;
3203 nextRequest->mResultExtras.precaptureTriggerId = mCurrentPreCaptureTriggerId;
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07003204
3205 // Since RequestThread::clear() removes buffers from the input stream,
3206 // get the right buffer here before unlocking mRequestLock
3207 if (nextRequest->mInputStream != NULL) {
3208 res = nextRequest->mInputStream->getInputBuffer(&nextRequest->mInputBuffer);
3209 if (res != OK) {
3210 // Can't get input buffer from gralloc queue - this could be due to
3211 // disconnected queue or other producer misbehavior, so not a fatal
3212 // error
3213 ALOGE("%s: Can't get input buffer, skipping request:"
3214 " %s (%d)", __FUNCTION__, strerror(-res), res);
3215 if (mListener != NULL) {
3216 mListener->notifyError(
3217 ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
3218 nextRequest->mResultExtras);
3219 }
3220 return NULL;
3221 }
3222 }
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07003223 }
Chien-Yu Chend196d612015-06-22 19:49:01 -07003224
3225 handleAePrecaptureCancelRequest(nextRequest);
3226
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07003227 mNextRequest = nextRequest;
3228
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003229 return nextRequest;
3230}
3231
3232bool Camera3Device::RequestThread::waitIfPaused() {
3233 status_t res;
3234 Mutex::Autolock l(mPauseLock);
3235 while (mDoPause) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003236 if (mPaused == false) {
3237 mPaused = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003238 ALOGV("%s: RequestThread: Paused", __FUNCTION__);
3239 // Let the tracker know
3240 sp<StatusTracker> statusTracker = mStatusTracker.promote();
3241 if (statusTracker != 0) {
3242 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
3243 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003244 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003245
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003246 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003247 if (res == TIMED_OUT || exitPending()) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003248 return true;
3249 }
3250 }
3251 // We don't set mPaused to false here, because waitForNextRequest needs
3252 // to further manage the paused state in case of starvation.
3253 return false;
3254}
3255
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07003256void Camera3Device::RequestThread::unpauseForNewRequests() {
3257 // With work to do, mark thread as unpaused.
3258 // If paused by request (setPaused), don't resume, to avoid
3259 // extra signaling/waiting overhead to waitUntilPaused
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003260 mRequestSignal.signal();
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07003261 Mutex::Autolock p(mPauseLock);
3262 if (!mDoPause) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003263 ALOGV("%s: RequestThread: Going active", __FUNCTION__);
3264 if (mPaused) {
3265 sp<StatusTracker> statusTracker = mStatusTracker.promote();
3266 if (statusTracker != 0) {
3267 statusTracker->markComponentActive(mStatusId);
3268 }
3269 }
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07003270 mPaused = false;
3271 }
3272}
3273
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07003274void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
3275 sp<Camera3Device> parent = mParent.promote();
3276 if (parent != NULL) {
3277 va_list args;
3278 va_start(args, fmt);
3279
3280 parent->setErrorStateV(fmt, args);
3281
3282 va_end(args);
3283 }
3284}
3285
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003286status_t Camera3Device::RequestThread::insertTriggers(
3287 const sp<CaptureRequest> &request) {
3288
3289 Mutex::Autolock al(mTriggerMutex);
3290
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07003291 sp<Camera3Device> parent = mParent.promote();
3292 if (parent == NULL) {
3293 CLOGE("RequestThread: Parent is gone");
3294 return DEAD_OBJECT;
3295 }
3296
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003297 CameraMetadata &metadata = request->mSettings;
3298 size_t count = mTriggerMap.size();
3299
3300 for (size_t i = 0; i < count; ++i) {
3301 RequestTrigger trigger = mTriggerMap.valueAt(i);
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003302 uint32_t tag = trigger.metadataTag;
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07003303
3304 if (tag == ANDROID_CONTROL_AF_TRIGGER_ID || tag == ANDROID_CONTROL_AE_PRECAPTURE_ID) {
3305 bool isAeTrigger = (trigger.metadataTag == ANDROID_CONTROL_AE_PRECAPTURE_ID);
3306 uint32_t triggerId = static_cast<uint32_t>(trigger.entryValue);
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07003307 if (isAeTrigger) {
3308 request->mResultExtras.precaptureTriggerId = triggerId;
3309 mCurrentPreCaptureTriggerId = triggerId;
3310 } else {
3311 request->mResultExtras.afTriggerId = triggerId;
3312 mCurrentAfTriggerId = triggerId;
3313 }
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07003314 if (parent->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
3315 continue; // Trigger ID tag is deprecated since device HAL 3.2
3316 }
3317 }
3318
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003319 camera_metadata_entry entry = metadata.find(tag);
3320
3321 if (entry.count > 0) {
3322 /**
3323 * Already has an entry for this trigger in the request.
3324 * Rewrite it with our requested trigger value.
3325 */
3326 RequestTrigger oldTrigger = trigger;
3327
3328 oldTrigger.entryValue = entry.data.u8[0];
3329
3330 mTriggerReplacedMap.add(tag, oldTrigger);
3331 } else {
3332 /**
3333 * More typical, no trigger entry, so we just add it
3334 */
3335 mTriggerRemovedMap.add(tag, trigger);
3336 }
3337
3338 status_t res;
3339
3340 switch (trigger.getTagType()) {
3341 case TYPE_BYTE: {
3342 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
3343 res = metadata.update(tag,
3344 &entryValue,
3345 /*count*/1);
3346 break;
3347 }
3348 case TYPE_INT32:
3349 res = metadata.update(tag,
3350 &trigger.entryValue,
3351 /*count*/1);
3352 break;
3353 default:
3354 ALOGE("%s: Type not supported: 0x%x",
3355 __FUNCTION__,
3356 trigger.getTagType());
3357 return INVALID_OPERATION;
3358 }
3359
3360 if (res != OK) {
3361 ALOGE("%s: Failed to update request metadata with trigger tag %s"
3362 ", value %d", __FUNCTION__, trigger.getTagName(),
3363 trigger.entryValue);
3364 return res;
3365 }
3366
3367 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
3368 trigger.getTagName(),
3369 trigger.entryValue);
3370 }
3371
3372 mTriggerMap.clear();
3373
3374 return count;
3375}
3376
3377status_t Camera3Device::RequestThread::removeTriggers(
3378 const sp<CaptureRequest> &request) {
3379 Mutex::Autolock al(mTriggerMutex);
3380
3381 CameraMetadata &metadata = request->mSettings;
3382
3383 /**
3384 * Replace all old entries with their old values.
3385 */
3386 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
3387 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
3388
3389 status_t res;
3390
3391 uint32_t tag = trigger.metadataTag;
3392 switch (trigger.getTagType()) {
3393 case TYPE_BYTE: {
3394 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
3395 res = metadata.update(tag,
3396 &entryValue,
3397 /*count*/1);
3398 break;
3399 }
3400 case TYPE_INT32:
3401 res = metadata.update(tag,
3402 &trigger.entryValue,
3403 /*count*/1);
3404 break;
3405 default:
3406 ALOGE("%s: Type not supported: 0x%x",
3407 __FUNCTION__,
3408 trigger.getTagType());
3409 return INVALID_OPERATION;
3410 }
3411
3412 if (res != OK) {
3413 ALOGE("%s: Failed to restore request metadata with trigger tag %s"
3414 ", trigger value %d", __FUNCTION__,
3415 trigger.getTagName(), trigger.entryValue);
3416 return res;
3417 }
3418 }
3419 mTriggerReplacedMap.clear();
3420
3421 /**
3422 * Remove all new entries.
3423 */
3424 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
3425 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
3426 status_t res = metadata.erase(trigger.metadataTag);
3427
3428 if (res != OK) {
3429 ALOGE("%s: Failed to erase metadata with trigger tag %s"
3430 ", trigger value %d", __FUNCTION__,
3431 trigger.getTagName(), trigger.entryValue);
3432 return res;
3433 }
3434 }
3435 mTriggerRemovedMap.clear();
3436
3437 return OK;
3438}
3439
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07003440status_t Camera3Device::RequestThread::addDummyTriggerIds(
3441 const sp<CaptureRequest> &request) {
3442 // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here
3443 static const int32_t dummyTriggerId = 1;
3444 status_t res;
3445
3446 CameraMetadata &metadata = request->mSettings;
3447
3448 // If AF trigger is active, insert a dummy AF trigger ID if none already
3449 // exists
3450 camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
3451 camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
3452 if (afTrigger.count > 0 &&
3453 afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
3454 afId.count == 0) {
3455 res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
3456 if (res != OK) return res;
3457 }
3458
3459 // If AE precapture trigger is active, insert a dummy precapture trigger ID
3460 // if none already exists
3461 camera_metadata_entry pcTrigger =
3462 metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
3463 camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
3464 if (pcTrigger.count > 0 &&
3465 pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
3466 pcId.count == 0) {
3467 res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
3468 &dummyTriggerId, 1);
3469 if (res != OK) return res;
3470 }
3471
3472 return OK;
3473}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003474
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07003475/**
3476 * PreparerThread inner class methods
3477 */
3478
3479Camera3Device::PreparerThread::PreparerThread() :
3480 Thread(/*canCallJava*/false), mActive(false), mCancelNow(false) {
3481}
3482
3483Camera3Device::PreparerThread::~PreparerThread() {
3484 Thread::requestExitAndWait();
3485 if (mCurrentStream != nullptr) {
3486 mCurrentStream->cancelPrepare();
3487 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
3488 mCurrentStream.clear();
3489 }
3490 clear();
3491}
3492
Ruben Brunkc78ac262015-08-13 17:58:46 -07003493status_t Camera3Device::PreparerThread::prepare(int maxCount, sp<Camera3StreamInterface>& stream) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07003494 status_t res;
3495
3496 Mutex::Autolock l(mLock);
3497
Ruben Brunkc78ac262015-08-13 17:58:46 -07003498 res = stream->startPrepare(maxCount);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07003499 if (res == OK) {
3500 // No preparation needed, fire listener right off
3501 ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId());
3502 if (mListener) {
3503 mListener->notifyPrepared(stream->getId());
3504 }
3505 return OK;
3506 } else if (res != NOT_ENOUGH_DATA) {
3507 return res;
3508 }
3509
3510 // Need to prepare, start up thread if necessary
3511 if (!mActive) {
3512 // mRunning will change to false before the thread fully shuts down, so wait to be sure it
3513 // isn't running
3514 Thread::requestExitAndWait();
3515 res = Thread::run("C3PrepThread", PRIORITY_BACKGROUND);
3516 if (res != OK) {
3517 ALOGE("%s: Unable to start preparer stream: %d (%s)", __FUNCTION__, res, strerror(-res));
3518 if (mListener) {
3519 mListener->notifyPrepared(stream->getId());
3520 }
3521 return res;
3522 }
3523 mCancelNow = false;
3524 mActive = true;
3525 ALOGV("%s: Preparer stream started", __FUNCTION__);
3526 }
3527
3528 // queue up the work
3529 mPendingStreams.push_back(stream);
3530 ALOGV("%s: Stream %d queued for preparing", __FUNCTION__, stream->getId());
3531
3532 return OK;
3533}
3534
3535status_t Camera3Device::PreparerThread::clear() {
3536 status_t res;
3537
3538 Mutex::Autolock l(mLock);
3539
3540 for (const auto& stream : mPendingStreams) {
3541 stream->cancelPrepare();
3542 }
3543 mPendingStreams.clear();
3544 mCancelNow = true;
3545
3546 return OK;
3547}
3548
3549void Camera3Device::PreparerThread::setNotificationListener(NotificationListener *listener) {
3550 Mutex::Autolock l(mLock);
3551 mListener = listener;
3552}
3553
3554bool Camera3Device::PreparerThread::threadLoop() {
3555 status_t res;
3556 {
3557 Mutex::Autolock l(mLock);
3558 if (mCurrentStream == nullptr) {
3559 // End thread if done with work
3560 if (mPendingStreams.empty()) {
3561 ALOGV("%s: Preparer stream out of work", __FUNCTION__);
3562 // threadLoop _must not_ re-acquire mLock after it sets mActive to false; would
3563 // cause deadlock with prepare()'s requestExitAndWait triggered by !mActive.
3564 mActive = false;
3565 return false;
3566 }
3567
3568 // Get next stream to prepare
3569 auto it = mPendingStreams.begin();
3570 mCurrentStream = *it;
3571 mPendingStreams.erase(it);
3572 ATRACE_ASYNC_BEGIN("stream prepare", mCurrentStream->getId());
3573 ALOGV("%s: Preparing stream %d", __FUNCTION__, mCurrentStream->getId());
3574 } else if (mCancelNow) {
3575 mCurrentStream->cancelPrepare();
3576 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
3577 ALOGV("%s: Cancelling stream %d prepare", __FUNCTION__, mCurrentStream->getId());
3578 mCurrentStream.clear();
3579 mCancelNow = false;
3580 return true;
3581 }
3582 }
3583
3584 res = mCurrentStream->prepareNextBuffer();
3585 if (res == NOT_ENOUGH_DATA) return true;
3586 if (res != OK) {
3587 // Something bad happened; try to recover by cancelling prepare and
3588 // signalling listener anyway
3589 ALOGE("%s: Stream %d returned error %d (%s) during prepare", __FUNCTION__,
3590 mCurrentStream->getId(), res, strerror(-res));
3591 mCurrentStream->cancelPrepare();
3592 }
3593
3594 // This stream has finished, notify listener
3595 Mutex::Autolock l(mLock);
3596 if (mListener) {
3597 ALOGV("%s: Stream %d prepare done, signaling listener", __FUNCTION__,
3598 mCurrentStream->getId());
3599 mListener->notifyPrepared(mCurrentStream->getId());
3600 }
3601
3602 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
3603 mCurrentStream.clear();
3604
3605 return true;
3606}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003607
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003608/**
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08003609 * Static callback forwarding methods from HAL to instance
3610 */
3611
3612void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
3613 const camera3_capture_result *result) {
3614 Camera3Device *d =
3615 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
Chien-Yu Chend196d612015-06-22 19:49:01 -07003616
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08003617 d->processCaptureResult(result);
3618}
3619
3620void Camera3Device::sNotify(const camera3_callback_ops *cb,
3621 const camera3_notify_msg *msg) {
3622 Camera3Device *d =
3623 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
3624 d->notify(msg);
3625}
3626
3627}; // namespace android