blob: 1a3a77022dd0b898e764a966c4ea2ea078690e3a [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 Talvalaf99498e2015-09-25 16:52:55 -070047#include "mediautils/SchedulingPolicyService.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070048#include "device3/Camera3Device.h"
49#include "device3/Camera3OutputStream.h"
50#include "device3/Camera3InputStream.h"
51#include "device3/Camera3ZslStream.h"
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -070052#include "device3/Camera3DummyStream.h"
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -070053#include "CameraService.h"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080054
55using namespace android::camera3;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080056
57namespace android {
58
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080059Camera3Device::Camera3Device(int id):
60 mId(id),
Eino-Ville Talvala9a179412015-06-09 13:15:16 -070061 mIsConstrainedHighSpeedConfiguration(false),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080062 mHal3Device(NULL),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070063 mStatus(STATUS_UNINITIALIZED),
Ruben Brunk183f0562015-08-12 12:55:02 -070064 mStatusWaiters(0),
Zhijun He204e3292014-07-14 17:09:23 -070065 mUsePartialResult(false),
66 mNumPartialResults(1),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -070067 mNextResultFrameNumber(0),
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -070068 mNextReprocessResultFrameNumber(0),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -070069 mNextShutterFrameNumber(0),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070070 mListener(NULL)
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080071{
72 ATRACE_CALL();
73 camera3_callback_ops::notify = &sNotify;
74 camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
75 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
76}
77
78Camera3Device::~Camera3Device()
79{
80 ATRACE_CALL();
81 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
82 disconnect();
83}
84
Igor Murashkin71381052013-03-04 14:53:08 -080085int Camera3Device::getId() const {
86 return mId;
87}
88
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080089/**
90 * CameraDeviceBase interface
91 */
92
Yin-Chia Yehe074a932015-01-30 10:29:02 -080093status_t Camera3Device::initialize(CameraModule *module)
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080094{
95 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -070096 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080097 Mutex::Autolock l(mLock);
98
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080099 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800100 if (mStatus != STATUS_UNINITIALIZED) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700101 CLOGE("Already initialized!");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800102 return INVALID_OPERATION;
103 }
104
105 /** Open HAL device */
106
107 status_t res;
108 String8 deviceName = String8::format("%d", mId);
109
110 camera3_device_t *device;
111
Zhijun He213ce792013-11-19 08:45:15 -0800112 ATRACE_BEGIN("camera3->open");
Chien-Yu Chend231fd62015-02-25 16:04:22 -0800113 res = module->open(deviceName.string(),
114 reinterpret_cast<hw_device_t**>(&device));
Zhijun He213ce792013-11-19 08:45:15 -0800115 ATRACE_END();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800116
117 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700118 SET_ERR_L("Could not open camera: %s (%d)", strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800119 return res;
120 }
121
122 /** Cross-check device version */
Zhijun He95dd5ba2014-03-26 18:18:00 -0700123 if (device->common.version < CAMERA_DEVICE_API_VERSION_3_0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700124 SET_ERR_L("Could not open camera: "
Zhijun He95dd5ba2014-03-26 18:18:00 -0700125 "Camera device should be at least %x, reports %x instead",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700126 CAMERA_DEVICE_API_VERSION_3_0,
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800127 device->common.version);
128 device->common.close(&device->common);
129 return BAD_VALUE;
130 }
131
132 camera_info info;
Yin-Chia Yehe074a932015-01-30 10:29:02 -0800133 res = CameraService::filterGetInfoErrorCode(module->getCameraInfo(
Eino-Ville Talvalaf67e23e2014-07-23 17:17:59 -0700134 mId, &info));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800135 if (res != OK) return res;
136
137 if (info.device_version != device->common.version) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700138 SET_ERR_L("HAL reporting mismatched camera_info version (%x)"
139 " and device version (%x).",
Zhijun He95dd5ba2014-03-26 18:18:00 -0700140 info.device_version, device->common.version);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800141 device->common.close(&device->common);
142 return BAD_VALUE;
143 }
144
145 /** Initialize device with callback functions */
146
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700147 ATRACE_BEGIN("camera3->initialize");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800148 res = device->ops->initialize(device, this);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700149 ATRACE_END();
150
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800151 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700152 SET_ERR_L("Unable to initialize HAL device: %s (%d)",
153 strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800154 device->common.close(&device->common);
155 return BAD_VALUE;
156 }
157
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700158 /** Start up status tracker thread */
159 mStatusTracker = new StatusTracker(this);
160 res = mStatusTracker->run(String8::format("C3Dev-%d-Status", mId).string());
161 if (res != OK) {
162 SET_ERR_L("Unable to start status tracking thread: %s (%d)",
163 strerror(-res), res);
164 device->common.close(&device->common);
165 mStatusTracker.clear();
166 return res;
167 }
168
Chien-Yu Chenab5135b2015-06-30 11:20:58 -0700169 bool aeLockAvailable = false;
170 camera_metadata_ro_entry aeLockAvailableEntry;
171 res = find_camera_metadata_ro_entry(info.static_camera_characteristics,
172 ANDROID_CONTROL_AE_LOCK_AVAILABLE, &aeLockAvailableEntry);
173 if (res == OK && aeLockAvailableEntry.count > 0) {
174 aeLockAvailable = (aeLockAvailableEntry.data.u8[0] ==
175 ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE);
176 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800177
Chien-Yu Chenab5135b2015-06-30 11:20:58 -0700178 /** Start up request queue thread */
179 mRequestThread = new RequestThread(this, mStatusTracker, device, aeLockAvailable);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800180 res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800181 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700182 SET_ERR_L("Unable to start request queue thread: %s (%d)",
183 strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800184 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800185 mRequestThread.clear();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800186 return res;
187 }
188
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700189 mPreparerThread = new PreparerThread();
190
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800191 /** Everything is good to go */
192
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700193 mDeviceVersion = device->common.version;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800194 mDeviceInfo = info.static_camera_characteristics;
195 mHal3Device = device;
Ruben Brunk183f0562015-08-12 12:55:02 -0700196
197 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800198 mNextStreamId = 0;
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -0700199 mDummyStreamId = NO_STREAM;
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -0700200 mNeedConfig = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700201 mPauseStateNotify = false;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800202
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700203 // Will the HAL be sending in early partial result metadata?
Zhijun He204e3292014-07-14 17:09:23 -0700204 if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
205 camera_metadata_entry partialResultsCount =
206 mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
207 if (partialResultsCount.count > 0) {
208 mNumPartialResults = partialResultsCount.data.i32[0];
209 mUsePartialResult = (mNumPartialResults > 1);
210 }
211 } else {
212 camera_metadata_entry partialResultsQuirk =
213 mDeviceInfo.find(ANDROID_QUIRKS_USE_PARTIAL_RESULT);
214 if (partialResultsQuirk.count > 0 && partialResultsQuirk.data.u8[0] == 1) {
215 mUsePartialResult = true;
216 }
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700217 }
218
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700219 camera_metadata_entry configs =
220 mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
221 for (uint32_t i = 0; i < configs.count; i += 4) {
222 if (configs.data.i32[i] == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
223 configs.data.i32[i + 3] ==
224 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
225 mSupportedOpaqueInputSizes.add(Size(configs.data.i32[i + 1],
226 configs.data.i32[i + 2]));
227 }
228 }
229
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800230 return OK;
231}
232
233status_t Camera3Device::disconnect() {
234 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700235 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800236
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800237 ALOGV("%s: E", __FUNCTION__);
238
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700239 status_t res = OK;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800240
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700241 {
242 Mutex::Autolock l(mLock);
243 if (mStatus == STATUS_UNINITIALIZED) return res;
244
245 if (mStatus == STATUS_ACTIVE ||
246 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
247 res = mRequestThread->clearRepeatingRequests();
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700248 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700249 SET_ERR_L("Can't stop streaming");
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700250 // Continue to close device even in case of error
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700251 } else {
252 res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
253 if (res != OK) {
254 SET_ERR_L("Timeout waiting for HAL to drain");
255 // Continue to close device even in case of error
256 }
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700257 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800258 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800259
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700260 if (mStatus == STATUS_ERROR) {
261 CLOGE("Shutting down in an error state");
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700262 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700263
264 if (mStatusTracker != NULL) {
265 mStatusTracker->requestExit();
266 }
267
268 if (mRequestThread != NULL) {
269 mRequestThread->requestExit();
270 }
271
272 mOutputStreams.clear();
273 mInputStream.clear();
274 }
275
276 // Joining done without holding mLock, otherwise deadlocks may ensue
277 // as the threads try to access parent state
278 if (mRequestThread != NULL && mStatus != STATUS_ERROR) {
279 // HAL may be in a bad state, so waiting for request thread
280 // (which may be stuck in the HAL processCaptureRequest call)
281 // could be dangerous.
282 mRequestThread->join();
283 }
284
285 if (mStatusTracker != NULL) {
286 mStatusTracker->join();
287 }
288
Eino-Ville Talvalaefff1c42015-08-28 16:27:27 -0700289 camera3_device_t *hal3Device;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700290 {
291 Mutex::Autolock l(mLock);
292
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800293 mRequestThread.clear();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700294 mStatusTracker.clear();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800295
Eino-Ville Talvalaefff1c42015-08-28 16:27:27 -0700296 hal3Device = mHal3Device;
297 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800298
Eino-Ville Talvalaefff1c42015-08-28 16:27:27 -0700299 // Call close without internal mutex held, as the HAL close may need to
300 // wait on assorted callbacks,etc, to complete before it can return.
301 if (hal3Device != NULL) {
302 ATRACE_BEGIN("camera3->close");
303 hal3Device->common.close(&hal3Device->common);
304 ATRACE_END();
305 }
306
307 {
308 Mutex::Autolock l(mLock);
309 mHal3Device = NULL;
Ruben Brunk183f0562015-08-12 12:55:02 -0700310 internalUpdateStatusLocked(STATUS_UNINITIALIZED);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700311 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800312
313 ALOGV("%s: X", __FUNCTION__);
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700314 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800315}
316
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700317// For dumping/debugging only -
318// try to acquire a lock a few times, eventually give up to proceed with
319// debug/dump operations
320bool Camera3Device::tryLockSpinRightRound(Mutex& lock) {
321 bool gotLock = false;
322 for (size_t i = 0; i < kDumpLockAttempts; ++i) {
323 if (lock.tryLock() == NO_ERROR) {
324 gotLock = true;
325 break;
326 } else {
327 usleep(kDumpSleepDuration);
328 }
329 }
330 return gotLock;
331}
332
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700333Camera3Device::Size Camera3Device::getMaxJpegResolution() const {
334 int32_t maxJpegWidth = 0, maxJpegHeight = 0;
335 if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
336 const int STREAM_CONFIGURATION_SIZE = 4;
337 const int STREAM_FORMAT_OFFSET = 0;
338 const int STREAM_WIDTH_OFFSET = 1;
339 const int STREAM_HEIGHT_OFFSET = 2;
340 const int STREAM_IS_INPUT_OFFSET = 3;
341 camera_metadata_ro_entry_t availableStreamConfigs =
342 mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
343 if (availableStreamConfigs.count == 0 ||
344 availableStreamConfigs.count % STREAM_CONFIGURATION_SIZE != 0) {
345 return Size(0, 0);
346 }
347
348 // Get max jpeg size (area-wise).
349 for (size_t i=0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) {
350 int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET];
351 int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET];
352 int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET];
353 int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET];
354 if (isInput == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
355 && format == HAL_PIXEL_FORMAT_BLOB &&
356 (width * height > maxJpegWidth * maxJpegHeight)) {
357 maxJpegWidth = width;
358 maxJpegHeight = height;
359 }
360 }
361 } else {
362 camera_metadata_ro_entry availableJpegSizes =
363 mDeviceInfo.find(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
364 if (availableJpegSizes.count == 0 || availableJpegSizes.count % 2 != 0) {
365 return Size(0, 0);
366 }
367
368 // Get max jpeg size (area-wise).
369 for (size_t i = 0; i < availableJpegSizes.count; i += 2) {
370 if ((availableJpegSizes.data.i32[i] * availableJpegSizes.data.i32[i + 1])
371 > (maxJpegWidth * maxJpegHeight)) {
372 maxJpegWidth = availableJpegSizes.data.i32[i];
373 maxJpegHeight = availableJpegSizes.data.i32[i + 1];
374 }
375 }
376 }
377 return Size(maxJpegWidth, maxJpegHeight);
378}
379
Zhijun Hef7da0962014-04-24 13:27:56 -0700380ssize_t Camera3Device::getJpegBufferSize(uint32_t width, uint32_t height) const {
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700381 // Get max jpeg size (area-wise).
382 Size maxJpegResolution = getMaxJpegResolution();
383 if (maxJpegResolution.width == 0) {
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700384 ALOGE("%s: Camera %d: Can't find valid available jpeg sizes in static metadata!",
Zhijun Hef7da0962014-04-24 13:27:56 -0700385 __FUNCTION__, mId);
386 return BAD_VALUE;
387 }
388
Zhijun Hef7da0962014-04-24 13:27:56 -0700389 // Get max jpeg buffer size
390 ssize_t maxJpegBufferSize = 0;
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700391 camera_metadata_ro_entry jpegBufMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE);
392 if (jpegBufMaxSize.count == 0) {
Zhijun Hef7da0962014-04-24 13:27:56 -0700393 ALOGE("%s: Camera %d: Can't find maximum JPEG size in static metadata!", __FUNCTION__, mId);
394 return BAD_VALUE;
395 }
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700396 maxJpegBufferSize = jpegBufMaxSize.data.i32[0];
Yin-Chia Yeh0c4e56d2015-01-09 15:21:27 -0800397 assert(kMinJpegBufferSize < maxJpegBufferSize);
Zhijun Hef7da0962014-04-24 13:27:56 -0700398
399 // Calculate final jpeg buffer size for the given resolution.
Yin-Chia Yehcd8fce82014-06-18 10:51:34 -0700400 float scaleFactor = ((float) (width * height)) /
401 (maxJpegResolution.width * maxJpegResolution.height);
Yin-Chia Yeh0c4e56d2015-01-09 15:21:27 -0800402 ssize_t jpegBufferSize = scaleFactor * (maxJpegBufferSize - kMinJpegBufferSize) +
403 kMinJpegBufferSize;
Zhijun Hef7da0962014-04-24 13:27:56 -0700404 if (jpegBufferSize > maxJpegBufferSize) {
405 jpegBufferSize = maxJpegBufferSize;
Zhijun Hef7da0962014-04-24 13:27:56 -0700406 }
407
408 return jpegBufferSize;
409}
410
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700411ssize_t Camera3Device::getPointCloudBufferSize() const {
412 const int FLOATS_PER_POINT=4;
413 camera_metadata_ro_entry maxPointCount = mDeviceInfo.find(ANDROID_DEPTH_MAX_DEPTH_SAMPLES);
414 if (maxPointCount.count == 0) {
415 ALOGE("%s: Camera %d: Can't find maximum depth point cloud size in static metadata!",
416 __FUNCTION__, mId);
417 return BAD_VALUE;
418 }
419 ssize_t maxBytesForPointCloud = sizeof(android_depth_points) +
420 maxPointCount.data.i32[0] * sizeof(float) * FLOATS_PER_POINT;
421 return maxBytesForPointCloud;
422}
423
424
425
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800426status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
427 ATRACE_CALL();
428 (void)args;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700429
430 // Try to lock, but continue in case of failure (to avoid blocking in
431 // deadlocks)
432 bool gotInterfaceLock = tryLockSpinRightRound(mInterfaceLock);
433 bool gotLock = tryLockSpinRightRound(mLock);
434
435 ALOGW_IF(!gotInterfaceLock,
436 "Camera %d: %s: Unable to lock interface lock, proceeding anyway",
437 mId, __FUNCTION__);
438 ALOGW_IF(!gotLock,
439 "Camera %d: %s: Unable to lock main lock, proceeding anyway",
440 mId, __FUNCTION__);
441
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800442 String8 lines;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800443
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800444 const char *status =
445 mStatus == STATUS_ERROR ? "ERROR" :
446 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700447 mStatus == STATUS_UNCONFIGURED ? "UNCONFIGURED" :
448 mStatus == STATUS_CONFIGURED ? "CONFIGURED" :
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800449 mStatus == STATUS_ACTIVE ? "ACTIVE" :
450 "Unknown";
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700451
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800452 lines.appendFormat(" Device status: %s\n", status);
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700453 if (mStatus == STATUS_ERROR) {
454 lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
455 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800456 lines.appendFormat(" Stream configuration:\n");
Zhijun He1fa89992015-06-01 15:44:31 -0700457 lines.appendFormat(" Operation mode: %s \n", mIsConstrainedHighSpeedConfiguration ?
Eino-Ville Talvala9a179412015-06-09 13:15:16 -0700458 "CONSTRAINED HIGH SPEED VIDEO" : "NORMAL");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800459
460 if (mInputStream != NULL) {
461 write(fd, lines.string(), lines.size());
462 mInputStream->dump(fd, args);
463 } else {
464 lines.appendFormat(" No input stream.\n");
465 write(fd, lines.string(), lines.size());
466 }
467 for (size_t i = 0; i < mOutputStreams.size(); i++) {
468 mOutputStreams[i]->dump(fd,args);
469 }
470
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700471 lines = String8(" In-flight requests:\n");
472 if (mInFlightMap.size() == 0) {
473 lines.append(" None\n");
474 } else {
475 for (size_t i = 0; i < mInFlightMap.size(); i++) {
476 InFlightRequest r = mInFlightMap.valueAt(i);
Colin Crosse5729fa2014-03-21 15:04:25 -0700477 lines.appendFormat(" Frame %d | Timestamp: %" PRId64 ", metadata"
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700478 " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
Chien-Yu Chen43e69a62014-11-25 16:38:33 -0800479 r.shutterTimestamp, r.haveResultMetadata ? "true" : "false",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700480 r.numBuffersLeft);
481 }
482 }
483 write(fd, lines.string(), lines.size());
484
Igor Murashkin1e479c02013-09-06 16:55:14 -0700485 {
486 lines = String8(" Last request sent:\n");
487 write(fd, lines.string(), lines.size());
488
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700489 CameraMetadata lastRequest = getLatestRequestLocked();
Igor Murashkin1e479c02013-09-06 16:55:14 -0700490 lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
491 }
492
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800493 if (mHal3Device != NULL) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700494 lines = String8(" HAL device dump:\n");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800495 write(fd, lines.string(), lines.size());
496 mHal3Device->ops->dump(mHal3Device, fd);
497 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800498
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700499 if (gotLock) mLock.unlock();
500 if (gotInterfaceLock) mInterfaceLock.unlock();
501
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800502 return OK;
503}
504
505const CameraMetadata& Camera3Device::info() const {
506 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800507 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
508 mStatus == STATUS_ERROR)) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700509 ALOGW("%s: Access to static info %s!", __FUNCTION__,
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800510 mStatus == STATUS_ERROR ?
511 "when in error state" : "before init");
512 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800513 return mDeviceInfo;
514}
515
Jianing Wei90e59c92014-03-12 18:29:36 -0700516status_t Camera3Device::checkStatusOkToCaptureLocked() {
517 switch (mStatus) {
518 case STATUS_ERROR:
519 CLOGE("Device has encountered a serious error");
520 return INVALID_OPERATION;
521 case STATUS_UNINITIALIZED:
522 CLOGE("Device not initialized");
523 return INVALID_OPERATION;
524 case STATUS_UNCONFIGURED:
525 case STATUS_CONFIGURED:
526 case STATUS_ACTIVE:
527 // OK
528 break;
529 default:
530 SET_ERR_L("Unexpected status: %d", mStatus);
531 return INVALID_OPERATION;
532 }
533 return OK;
534}
535
536status_t Camera3Device::convertMetadataListToRequestListLocked(
537 const List<const CameraMetadata> &metadataList, RequestList *requestList) {
538 if (requestList == NULL) {
539 CLOGE("requestList cannot be NULL.");
540 return BAD_VALUE;
541 }
542
Jianing Weicb0652e2014-03-12 18:29:36 -0700543 int32_t burstId = 0;
Jianing Wei90e59c92014-03-12 18:29:36 -0700544 for (List<const CameraMetadata>::const_iterator it = metadataList.begin();
545 it != metadataList.end(); ++it) {
546 sp<CaptureRequest> newRequest = setUpRequestLocked(*it);
547 if (newRequest == 0) {
548 CLOGE("Can't create capture request");
549 return BAD_VALUE;
550 }
Jianing Weicb0652e2014-03-12 18:29:36 -0700551
552 // Setup burst Id and request Id
553 newRequest->mResultExtras.burstId = burstId++;
554 if (it->exists(ANDROID_REQUEST_ID)) {
555 if (it->find(ANDROID_REQUEST_ID).count == 0) {
556 CLOGE("RequestID entry exists; but must not be empty in metadata");
557 return BAD_VALUE;
558 }
559 newRequest->mResultExtras.requestId = it->find(ANDROID_REQUEST_ID).data.i32[0];
560 } else {
561 CLOGE("RequestID does not exist in metadata");
562 return BAD_VALUE;
563 }
564
Jianing Wei90e59c92014-03-12 18:29:36 -0700565 requestList->push_back(newRequest);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700566
567 ALOGV("%s: requestId = %" PRId32, __FUNCTION__, newRequest->mResultExtras.requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700568 }
Chien-Yu Chen85a64552015-08-28 15:46:12 -0700569
570 // Setup batch size if this is a high speed video recording request.
571 if (mIsConstrainedHighSpeedConfiguration && requestList->size() > 0) {
572 auto firstRequest = requestList->begin();
573 for (auto& outputStream : (*firstRequest)->mOutputStreams) {
574 if (outputStream->isVideoStream()) {
575 (*firstRequest)->mBatchSize = requestList->size();
576 break;
577 }
578 }
579 }
580
Jianing Wei90e59c92014-03-12 18:29:36 -0700581 return OK;
582}
583
Jianing Weicb0652e2014-03-12 18:29:36 -0700584status_t Camera3Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800585 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800586
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700587 List<const CameraMetadata> requests;
588 requests.push_back(request);
589 return captureList(requests, /*lastFrameNumber*/NULL);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800590}
591
Jianing Wei90e59c92014-03-12 18:29:36 -0700592status_t Camera3Device::submitRequestsHelper(
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700593 const List<const CameraMetadata> &requests, bool repeating,
594 /*out*/
595 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700596 ATRACE_CALL();
597 Mutex::Autolock il(mInterfaceLock);
598 Mutex::Autolock l(mLock);
599
600 status_t res = checkStatusOkToCaptureLocked();
601 if (res != OK) {
602 // error logged by previous call
603 return res;
604 }
605
606 RequestList requestList;
607
608 res = convertMetadataListToRequestListLocked(requests, /*out*/&requestList);
609 if (res != OK) {
610 // error logged by previous call
611 return res;
612 }
613
614 if (repeating) {
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700615 res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700616 } else {
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700617 res = mRequestThread->queueRequestList(requestList, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700618 }
619
620 if (res == OK) {
621 waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
622 if (res != OK) {
623 SET_ERR_L("Can't transition to active in %f seconds!",
624 kActiveTimeout/1e9);
625 }
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700626 ALOGV("Camera %d: Capture request %" PRId32 " enqueued", mId,
627 (*(requestList.begin()))->mResultExtras.requestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700628 } else {
629 CLOGE("Cannot queue request. Impossible.");
630 return BAD_VALUE;
631 }
632
633 return res;
634}
635
Jianing Weicb0652e2014-03-12 18:29:36 -0700636status_t Camera3Device::captureList(const List<const CameraMetadata> &requests,
637 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700638 ATRACE_CALL();
639
Jianing Weicb0652e2014-03-12 18:29:36 -0700640 return submitRequestsHelper(requests, /*repeating*/false, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700641}
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800642
Jianing Weicb0652e2014-03-12 18:29:36 -0700643status_t Camera3Device::setStreamingRequest(const CameraMetadata &request,
644 int64_t* /*lastFrameNumber*/) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800645 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800646
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700647 List<const CameraMetadata> requests;
648 requests.push_back(request);
649 return setStreamingRequestList(requests, /*lastFrameNumber*/NULL);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800650}
651
Jianing Weicb0652e2014-03-12 18:29:36 -0700652status_t Camera3Device::setStreamingRequestList(const List<const CameraMetadata> &requests,
653 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700654 ATRACE_CALL();
655
Jianing Weicb0652e2014-03-12 18:29:36 -0700656 return submitRequestsHelper(requests, /*repeating*/true, lastFrameNumber);
Jianing Wei90e59c92014-03-12 18:29:36 -0700657}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800658
659sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
660 const CameraMetadata &request) {
661 status_t res;
662
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700663 if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800664 res = configureStreamsLocked();
Yin-Chia Yeh3ea3fcd2014-09-05 14:14:44 -0700665 // Stream configuration failed due to unsupported configuration.
666 // Device back to unconfigured state. Client might try other configuraitons
667 if (res == BAD_VALUE && mStatus == STATUS_UNCONFIGURED) {
668 CLOGE("No streams configured");
669 return NULL;
670 }
671 // Stream configuration failed for other reason. Fatal.
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800672 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700673 SET_ERR_L("Can't set up streams: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800674 return NULL;
675 }
Yin-Chia Yeh3ea3fcd2014-09-05 14:14:44 -0700676 // Stream configuration successfully configure to empty stream configuration.
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700677 if (mStatus == STATUS_UNCONFIGURED) {
678 CLOGE("No streams configured");
679 return NULL;
680 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800681 }
682
683 sp<CaptureRequest> newRequest = createCaptureRequest(request);
684 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800685}
686
Jianing Weicb0652e2014-03-12 18:29:36 -0700687status_t Camera3Device::clearStreamingRequest(int64_t *lastFrameNumber) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800688 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700689 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800690 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800691
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800692 switch (mStatus) {
693 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700694 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800695 return INVALID_OPERATION;
696 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700697 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800698 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700699 case STATUS_UNCONFIGURED:
700 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800701 case STATUS_ACTIVE:
702 // OK
703 break;
704 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700705 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800706 return INVALID_OPERATION;
707 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700708 ALOGV("Camera %d: Clearing repeating request", mId);
Jianing Weicb0652e2014-03-12 18:29:36 -0700709
Jianing Wei2d6bb3f2014-04-11 10:00:31 -0700710 return mRequestThread->clearRepeatingRequests(lastFrameNumber);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800711}
712
713status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
714 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700715 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800716
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700717 return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800718}
719
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700720status_t Camera3Device::createInputStream(
721 uint32_t width, uint32_t height, int format, int *id) {
722 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700723 Mutex::Autolock il(mInterfaceLock);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700724 Mutex::Autolock l(mLock);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700725 ALOGV("Camera %d: Creating new input stream %d: %d x %d, format %d",
726 mId, mNextStreamId, width, height, format);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700727
728 status_t res;
729 bool wasActive = false;
730
731 switch (mStatus) {
732 case STATUS_ERROR:
733 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
734 return INVALID_OPERATION;
735 case STATUS_UNINITIALIZED:
736 ALOGE("%s: Device not initialized", __FUNCTION__);
737 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700738 case STATUS_UNCONFIGURED:
739 case STATUS_CONFIGURED:
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700740 // OK
741 break;
742 case STATUS_ACTIVE:
743 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700744 res = internalPauseAndWaitLocked();
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700745 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700746 SET_ERR_L("Can't pause captures to reconfigure streams!");
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700747 return res;
748 }
749 wasActive = true;
750 break;
751 default:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700752 SET_ERR_L("%s: Unexpected status: %d", mStatus);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700753 return INVALID_OPERATION;
754 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700755 assert(mStatus != STATUS_ACTIVE);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700756
757 if (mInputStream != 0) {
758 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
759 return INVALID_OPERATION;
760 }
761
762 sp<Camera3InputStream> newStream = new Camera3InputStream(mNextStreamId,
763 width, height, format);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700764 newStream->setStatusTracker(mStatusTracker);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700765
766 mInputStream = newStream;
767
768 *id = mNextStreamId++;
769
770 // Continue captures if active at start
771 if (wasActive) {
772 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
773 res = configureStreamsLocked();
774 if (res != OK) {
775 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
776 __FUNCTION__, mNextStreamId, strerror(-res), res);
777 return res;
778 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700779 internalResumeLocked();
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700780 }
781
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700782 ALOGV("Camera %d: Created input stream", mId);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700783 return OK;
784}
785
Igor Murashkin2fba5842013-04-22 14:03:54 -0700786
787status_t Camera3Device::createZslStream(
788 uint32_t width, uint32_t height,
789 int depth,
790 /*out*/
791 int *id,
792 sp<Camera3ZslStream>* zslStream) {
793 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700794 Mutex::Autolock il(mInterfaceLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700795 Mutex::Autolock l(mLock);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700796 ALOGV("Camera %d: Creating ZSL stream %d: %d x %d, depth %d",
797 mId, mNextStreamId, width, height, depth);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700798
799 status_t res;
800 bool wasActive = false;
801
802 switch (mStatus) {
803 case STATUS_ERROR:
804 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
805 return INVALID_OPERATION;
806 case STATUS_UNINITIALIZED:
807 ALOGE("%s: Device not initialized", __FUNCTION__);
808 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700809 case STATUS_UNCONFIGURED:
810 case STATUS_CONFIGURED:
Igor Murashkin2fba5842013-04-22 14:03:54 -0700811 // OK
812 break;
813 case STATUS_ACTIVE:
814 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700815 res = internalPauseAndWaitLocked();
Igor Murashkin2fba5842013-04-22 14:03:54 -0700816 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700817 SET_ERR_L("Can't pause captures to reconfigure streams!");
Igor Murashkin2fba5842013-04-22 14:03:54 -0700818 return res;
819 }
820 wasActive = true;
821 break;
822 default:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700823 SET_ERR_L("Unexpected status: %d", mStatus);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700824 return INVALID_OPERATION;
825 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700826 assert(mStatus != STATUS_ACTIVE);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700827
828 if (mInputStream != 0) {
829 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
830 return INVALID_OPERATION;
831 }
832
833 sp<Camera3ZslStream> newStream = new Camera3ZslStream(mNextStreamId,
834 width, height, depth);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700835 newStream->setStatusTracker(mStatusTracker);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700836
837 res = mOutputStreams.add(mNextStreamId, newStream);
838 if (res < 0) {
839 ALOGE("%s: Can't add new stream to set: %s (%d)",
840 __FUNCTION__, strerror(-res), res);
841 return res;
842 }
843 mInputStream = newStream;
844
Yuvraj Pasie5e3d082014-04-15 18:37:45 +0530845 mNeedConfig = true;
846
Igor Murashkin2fba5842013-04-22 14:03:54 -0700847 *id = mNextStreamId++;
848 *zslStream = newStream;
849
850 // Continue captures if active at start
851 if (wasActive) {
852 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
853 res = configureStreamsLocked();
854 if (res != OK) {
855 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
856 __FUNCTION__, mNextStreamId, strerror(-res), res);
857 return res;
858 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700859 internalResumeLocked();
Igor Murashkin2fba5842013-04-22 14:03:54 -0700860 }
861
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700862 ALOGV("Camera %d: Created ZSL stream", mId);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700863 return OK;
864}
865
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700866status_t Camera3Device::createStream(sp<Surface> consumer,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800867 uint32_t width, uint32_t height, int format, android_dataspace dataSpace,
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700868 camera3_stream_rotation_t rotation, int *id) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800869 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700870 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800871 Mutex::Autolock l(mLock);
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700872 ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d",
873 mId, mNextStreamId, width, height, format, dataSpace, rotation);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800874
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800875 status_t res;
876 bool wasActive = false;
877
878 switch (mStatus) {
879 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700880 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800881 return INVALID_OPERATION;
882 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700883 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800884 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700885 case STATUS_UNCONFIGURED:
886 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800887 // OK
888 break;
889 case STATUS_ACTIVE:
890 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700891 res = internalPauseAndWaitLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800892 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700893 SET_ERR_L("Can't pause captures to reconfigure streams!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800894 return res;
895 }
896 wasActive = true;
897 break;
898 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700899 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800900 return INVALID_OPERATION;
901 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700902 assert(mStatus != STATUS_ACTIVE);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800903
904 sp<Camera3OutputStream> newStream;
905 if (format == HAL_PIXEL_FORMAT_BLOB) {
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700906 ssize_t blobBufferSize;
907 if (dataSpace != HAL_DATASPACE_DEPTH) {
908 blobBufferSize = getJpegBufferSize(width, height);
909 if (blobBufferSize <= 0) {
910 SET_ERR_L("Invalid jpeg buffer size %zd", blobBufferSize);
911 return BAD_VALUE;
912 }
913 } else {
914 blobBufferSize = getPointCloudBufferSize();
915 if (blobBufferSize <= 0) {
916 SET_ERR_L("Invalid point cloud buffer size %zd", blobBufferSize);
917 return BAD_VALUE;
918 }
Zhijun Hef7da0962014-04-24 13:27:56 -0700919 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800920 newStream = new Camera3OutputStream(mNextStreamId, consumer,
Eino-Ville Talvala95a1d0f2015-08-11 15:08:53 -0700921 width, height, blobBufferSize, format, dataSpace, rotation);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800922 } else {
923 newStream = new Camera3OutputStream(mNextStreamId, consumer,
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700924 width, height, format, dataSpace, rotation);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800925 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700926 newStream->setStatusTracker(mStatusTracker);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800927
928 res = mOutputStreams.add(mNextStreamId, newStream);
929 if (res < 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700930 SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800931 return res;
932 }
933
934 *id = mNextStreamId++;
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -0700935 mNeedConfig = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800936
937 // Continue captures if active at start
938 if (wasActive) {
939 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
940 res = configureStreamsLocked();
941 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700942 CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
943 mNextStreamId, strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800944 return res;
945 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700946 internalResumeLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800947 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700948 ALOGV("Camera %d: Created new stream", mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800949 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800950}
951
952status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
953 ATRACE_CALL();
954 (void)outputId; (void)id;
955
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700956 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800957 return INVALID_OPERATION;
958}
959
960
961status_t Camera3Device::getStreamInfo(int id,
Eino-Ville Talvalad46a6b92015-05-14 17:26:24 -0700962 uint32_t *width, uint32_t *height,
963 uint32_t *format, android_dataspace *dataSpace) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800964 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700965 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800966 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800967
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800968 switch (mStatus) {
969 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700970 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800971 return INVALID_OPERATION;
972 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700973 CLOGE("Device not initialized!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800974 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700975 case STATUS_UNCONFIGURED:
976 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800977 case STATUS_ACTIVE:
978 // OK
979 break;
980 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700981 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800982 return INVALID_OPERATION;
983 }
984
985 ssize_t idx = mOutputStreams.indexOfKey(id);
986 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700987 CLOGE("Stream %d is unknown", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800988 return idx;
989 }
990
991 if (width) *width = mOutputStreams[idx]->getWidth();
992 if (height) *height = mOutputStreams[idx]->getHeight();
993 if (format) *format = mOutputStreams[idx]->getFormat();
Eino-Ville Talvalad46a6b92015-05-14 17:26:24 -0700994 if (dataSpace) *dataSpace = mOutputStreams[idx]->getDataSpace();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800995 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800996}
997
998status_t Camera3Device::setStreamTransform(int id,
999 int transform) {
1000 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001001 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001002 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001003
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001004 switch (mStatus) {
1005 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001006 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001007 return INVALID_OPERATION;
1008 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001009 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001010 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001011 case STATUS_UNCONFIGURED:
1012 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001013 case STATUS_ACTIVE:
1014 // OK
1015 break;
1016 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001017 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001018 return INVALID_OPERATION;
1019 }
1020
1021 ssize_t idx = mOutputStreams.indexOfKey(id);
1022 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001023 CLOGE("Stream %d does not exist",
1024 id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001025 return BAD_VALUE;
1026 }
1027
1028 return mOutputStreams.editValueAt(idx)->setTransform(transform);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001029}
1030
1031status_t Camera3Device::deleteStream(int id) {
1032 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001033 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001034 Mutex::Autolock l(mLock);
1035 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001036
Igor Murashkine2172be2013-05-28 15:31:39 -07001037 ALOGV("%s: Camera %d: Deleting stream %d", __FUNCTION__, mId, id);
1038
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001039 // CameraDevice semantics require device to already be idle before
1040 // deleteStream is called, unlike for createStream.
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001041 if (mStatus == STATUS_ACTIVE) {
Igor Murashkin52827132013-05-13 14:53:44 -07001042 ALOGV("%s: Camera %d: Device not idle", __FUNCTION__, mId);
1043 return -EBUSY;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001044 }
1045
Igor Murashkin2fba5842013-04-22 14:03:54 -07001046 sp<Camera3StreamInterface> deletedStream;
Zhijun He5f446352014-01-22 09:49:33 -08001047 ssize_t outputStreamIdx = mOutputStreams.indexOfKey(id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001048 if (mInputStream != NULL && id == mInputStream->getId()) {
1049 deletedStream = mInputStream;
1050 mInputStream.clear();
1051 } else {
Zhijun He5f446352014-01-22 09:49:33 -08001052 if (outputStreamIdx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001053 CLOGE("Stream %d does not exist", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001054 return BAD_VALUE;
1055 }
Zhijun He5f446352014-01-22 09:49:33 -08001056 }
1057
1058 // Delete output stream or the output part of a bi-directional stream.
1059 if (outputStreamIdx != NAME_NOT_FOUND) {
1060 deletedStream = mOutputStreams.editValueAt(outputStreamIdx);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001061 mOutputStreams.removeItem(id);
1062 }
1063
1064 // Free up the stream endpoint so that it can be used by some other stream
1065 res = deletedStream->disconnect();
1066 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001067 SET_ERR_L("Can't disconnect deleted stream %d", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001068 // fall through since we want to still list the stream as deleted.
1069 }
1070 mDeletedStreams.add(deletedStream);
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001071 mNeedConfig = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001072
1073 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001074}
1075
1076status_t Camera3Device::deleteReprocessStream(int id) {
1077 ATRACE_CALL();
1078 (void)id;
1079
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001080 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001081 return INVALID_OPERATION;
1082}
1083
Zhijun He1fa89992015-06-01 15:44:31 -07001084status_t Camera3Device::configureStreams(bool isConstrainedHighSpeed) {
Igor Murashkine2d167e2014-08-19 16:19:59 -07001085 ATRACE_CALL();
1086 ALOGV("%s: E", __FUNCTION__);
1087
1088 Mutex::Autolock il(mInterfaceLock);
1089 Mutex::Autolock l(mLock);
Chien-Yu Chen17338fc2015-06-18 16:30:12 -07001090
1091 if (mIsConstrainedHighSpeedConfiguration != isConstrainedHighSpeed) {
1092 mNeedConfig = true;
1093 mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
1094 }
Igor Murashkine2d167e2014-08-19 16:19:59 -07001095
1096 return configureStreamsLocked();
1097}
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001098
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001099status_t Camera3Device::getInputBufferProducer(
1100 sp<IGraphicBufferProducer> *producer) {
1101 Mutex::Autolock il(mInterfaceLock);
1102 Mutex::Autolock l(mLock);
1103
1104 if (producer == NULL) {
1105 return BAD_VALUE;
1106 } else if (mInputStream == NULL) {
1107 return INVALID_OPERATION;
1108 }
1109
1110 return mInputStream->getInputBufferProducer(producer);
1111}
1112
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001113status_t Camera3Device::createDefaultRequest(int templateId,
1114 CameraMetadata *request) {
1115 ATRACE_CALL();
Alex Rayfe7e0c62013-05-30 00:12:13 -07001116 ALOGV("%s: for template %d", __FUNCTION__, templateId);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001117 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001118 Mutex::Autolock l(mLock);
1119
1120 switch (mStatus) {
1121 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001122 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001123 return INVALID_OPERATION;
1124 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001125 CLOGE("Device is not initialized!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001126 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001127 case STATUS_UNCONFIGURED:
1128 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001129 case STATUS_ACTIVE:
1130 // OK
1131 break;
1132 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001133 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001134 return INVALID_OPERATION;
1135 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001136
Zhijun Hea1530f12014-09-14 12:44:20 -07001137 if (!mRequestTemplateCache[templateId].isEmpty()) {
1138 *request = mRequestTemplateCache[templateId];
1139 return OK;
1140 }
1141
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001142 const camera_metadata_t *rawRequest;
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001143 ATRACE_BEGIN("camera3->construct_default_request_settings");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001144 rawRequest = mHal3Device->ops->construct_default_request_settings(
1145 mHal3Device, templateId);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001146 ATRACE_END();
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001147 if (rawRequest == NULL) {
Yin-Chia Yeh0336d362015-04-14 12:34:22 -07001148 ALOGI("%s: template %d is not supported on this camera device",
1149 __FUNCTION__, templateId);
1150 return BAD_VALUE;
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001151 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001152 *request = rawRequest;
Zhijun Hea1530f12014-09-14 12:44:20 -07001153 mRequestTemplateCache[templateId] = rawRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001154
1155 return OK;
1156}
1157
1158status_t Camera3Device::waitUntilDrained() {
1159 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001160 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001161 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001162
Zhijun He69a37482014-03-23 18:44:49 -07001163 return waitUntilDrainedLocked();
1164}
1165
1166status_t Camera3Device::waitUntilDrainedLocked() {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001167 switch (mStatus) {
1168 case STATUS_UNINITIALIZED:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001169 case STATUS_UNCONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001170 ALOGV("%s: Already idle", __FUNCTION__);
1171 return OK;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001172 case STATUS_CONFIGURED:
1173 // To avoid race conditions, check with tracker to be sure
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001174 case STATUS_ERROR:
1175 case STATUS_ACTIVE:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001176 // Need to verify shut down
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001177 break;
1178 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001179 SET_ERR_L("Unexpected status: %d",mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001180 return INVALID_OPERATION;
1181 }
1182
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001183 ALOGV("%s: Camera %d: Waiting until idle", __FUNCTION__, mId);
1184 status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
Eino-Ville Talvala9c8a0912014-09-14 14:52:19 -07001185 if (res != OK) {
1186 SET_ERR_L("Error waiting for HAL to drain: %s (%d)", strerror(-res),
1187 res);
1188 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001189 return res;
1190}
1191
Ruben Brunk183f0562015-08-12 12:55:02 -07001192
1193void Camera3Device::internalUpdateStatusLocked(Status status) {
1194 mStatus = status;
1195 mRecentStatusUpdates.add(mStatus);
1196 mStatusChanged.broadcast();
1197}
1198
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001199// Pause to reconfigure
1200status_t Camera3Device::internalPauseAndWaitLocked() {
1201 mRequestThread->setPaused(true);
1202 mPauseStateNotify = true;
1203
1204 ALOGV("%s: Camera %d: Internal wait until idle", __FUNCTION__, mId);
1205 status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
1206 if (res != OK) {
1207 SET_ERR_L("Can't idle device in %f seconds!",
1208 kShutdownTimeout/1e9);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001209 }
1210
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001211 return res;
1212}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001213
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001214// Resume after internalPauseAndWaitLocked
1215status_t Camera3Device::internalResumeLocked() {
1216 status_t res;
1217
1218 mRequestThread->setPaused(false);
1219
1220 res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
1221 if (res != OK) {
1222 SET_ERR_L("Can't transition to active in %f seconds!",
1223 kActiveTimeout/1e9);
1224 }
1225 mPauseStateNotify = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001226 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001227}
1228
Ruben Brunk183f0562015-08-12 12:55:02 -07001229status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001230 status_t res = OK;
Ruben Brunk183f0562015-08-12 12:55:02 -07001231
1232 size_t startIndex = 0;
1233 if (mStatusWaiters == 0) {
1234 // Clear the list of recent statuses if there are no existing threads waiting on updates to
1235 // this status list
1236 mRecentStatusUpdates.clear();
1237 } else {
1238 // If other threads are waiting on updates to this status list, set the position of the
1239 // first element that this list will check rather than clearing the list.
1240 startIndex = mRecentStatusUpdates.size();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001241 }
1242
Ruben Brunk183f0562015-08-12 12:55:02 -07001243 mStatusWaiters++;
1244
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001245 bool stateSeen = false;
1246 do {
Ruben Brunk183f0562015-08-12 12:55:02 -07001247 if (active == (mStatus == STATUS_ACTIVE)) {
1248 // Desired state is current
1249 break;
1250 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001251
1252 res = mStatusChanged.waitRelative(mLock, timeout);
1253 if (res != OK) break;
1254
Ruben Brunk183f0562015-08-12 12:55:02 -07001255 // This is impossible, but if not, could result in subtle deadlocks and invalid state
1256 // transitions.
1257 LOG_ALWAYS_FATAL_IF(startIndex > mRecentStatusUpdates.size(),
1258 "%s: Skipping status updates in Camera3Device, may result in deadlock.",
1259 __FUNCTION__);
1260
1261 // Encountered desired state since we began waiting
1262 for (size_t i = startIndex; i < mRecentStatusUpdates.size(); i++) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001263 if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
1264 stateSeen = true;
1265 break;
1266 }
1267 }
1268 } while (!stateSeen);
1269
Ruben Brunk183f0562015-08-12 12:55:02 -07001270 mStatusWaiters--;
1271
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001272 return res;
1273}
1274
1275
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001276status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
1277 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001278 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001279
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001280 if (listener != NULL && mListener != NULL) {
1281 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
1282 }
1283 mListener = listener;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001284 mRequestThread->setNotificationListener(listener);
1285 mPreparerThread->setNotificationListener(listener);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001286
1287 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001288}
1289
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -07001290bool Camera3Device::willNotify3A() {
1291 return false;
1292}
1293
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001294status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001295 status_t res;
1296 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001297
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001298 while (mResultQueue.empty()) {
1299 res = mResultSignal.waitRelative(mOutputLock, timeout);
1300 if (res == TIMED_OUT) {
1301 return res;
1302 } else if (res != OK) {
Colin Crosse5729fa2014-03-21 15:04:25 -07001303 ALOGW("%s: Camera %d: No frame in %" PRId64 " ns: %s (%d)",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001304 __FUNCTION__, mId, timeout, strerror(-res), res);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001305 return res;
1306 }
1307 }
1308 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001309}
1310
Jianing Weicb0652e2014-03-12 18:29:36 -07001311status_t Camera3Device::getNextResult(CaptureResult *frame) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001312 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001313 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001314
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001315 if (mResultQueue.empty()) {
1316 return NOT_ENOUGH_DATA;
1317 }
1318
Jianing Weicb0652e2014-03-12 18:29:36 -07001319 if (frame == NULL) {
1320 ALOGE("%s: argument cannot be NULL", __FUNCTION__);
1321 return BAD_VALUE;
1322 }
1323
1324 CaptureResult &result = *(mResultQueue.begin());
1325 frame->mResultExtras = result.mResultExtras;
1326 frame->mMetadata.acquire(result.mMetadata);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001327 mResultQueue.erase(mResultQueue.begin());
1328
1329 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001330}
1331
1332status_t Camera3Device::triggerAutofocus(uint32_t id) {
1333 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001334 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001335
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001336 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
1337 // Mix-in this trigger into the next request and only the next request.
1338 RequestTrigger trigger[] = {
1339 {
1340 ANDROID_CONTROL_AF_TRIGGER,
1341 ANDROID_CONTROL_AF_TRIGGER_START
1342 },
1343 {
1344 ANDROID_CONTROL_AF_TRIGGER_ID,
1345 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07001346 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001347 };
1348
1349 return mRequestThread->queueTrigger(trigger,
1350 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001351}
1352
1353status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
1354 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001355 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001356
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001357 ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
1358 // Mix-in this trigger into the next request and only the next request.
1359 RequestTrigger trigger[] = {
1360 {
1361 ANDROID_CONTROL_AF_TRIGGER,
1362 ANDROID_CONTROL_AF_TRIGGER_CANCEL
1363 },
1364 {
1365 ANDROID_CONTROL_AF_TRIGGER_ID,
1366 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07001367 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001368 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001369
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001370 return mRequestThread->queueTrigger(trigger,
1371 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001372}
1373
1374status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
1375 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001376 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001377
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001378 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
1379 // Mix-in this trigger into the next request and only the next request.
1380 RequestTrigger trigger[] = {
1381 {
1382 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1383 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
1384 },
1385 {
1386 ANDROID_CONTROL_AE_PRECAPTURE_ID,
1387 static_cast<int32_t>(id)
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07001388 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001389 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001390
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001391 return mRequestThread->queueTrigger(trigger,
1392 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001393}
1394
1395status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
1396 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
1397 ATRACE_CALL();
1398 (void)reprocessStreamId; (void)buffer; (void)listener;
1399
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001400 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001401 return INVALID_OPERATION;
1402}
1403
Jianing Weicb0652e2014-03-12 18:29:36 -07001404status_t Camera3Device::flush(int64_t *frameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001405 ATRACE_CALL();
1406 ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001407 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001408
Eino-Ville Talvala17543512014-08-06 14:32:02 -07001409 NotificationListener* listener;
1410 {
1411 Mutex::Autolock l(mOutputLock);
1412 listener = mListener;
1413 }
1414
Zhijun He7ef20392014-04-21 16:04:17 -07001415 {
1416 Mutex::Autolock l(mLock);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07001417 mRequestThread->clear(listener, /*out*/frameNumber);
Zhijun He7ef20392014-04-21 16:04:17 -07001418 }
1419
Zhijun He491e3412013-12-27 10:57:44 -08001420 status_t res;
1421 if (mHal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_1) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07001422 res = mRequestThread->flush();
Zhijun He491e3412013-12-27 10:57:44 -08001423 } else {
Zhijun He7ef20392014-04-21 16:04:17 -07001424 Mutex::Autolock l(mLock);
Zhijun He69a37482014-03-23 18:44:49 -07001425 res = waitUntilDrainedLocked();
Zhijun He491e3412013-12-27 10:57:44 -08001426 }
1427
1428 return res;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001429}
1430
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001431status_t Camera3Device::prepare(int streamId) {
Ruben Brunkc78ac262015-08-13 17:58:46 -07001432 return prepare(camera3::Camera3StreamInterface::ALLOCATE_PIPELINE_MAX, streamId);
1433}
1434
1435status_t Camera3Device::prepare(int maxCount, int streamId) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001436 ATRACE_CALL();
1437 ALOGV("%s: Camera %d: Preparing stream %d", __FUNCTION__, mId, streamId);
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07001438 Mutex::Autolock il(mInterfaceLock);
1439 Mutex::Autolock l(mLock);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001440
1441 sp<Camera3StreamInterface> stream;
1442 ssize_t outputStreamIdx = mOutputStreams.indexOfKey(streamId);
1443 if (outputStreamIdx == NAME_NOT_FOUND) {
1444 CLOGE("Stream %d does not exist", streamId);
1445 return BAD_VALUE;
1446 }
1447
1448 stream = mOutputStreams.editValueAt(outputStreamIdx);
1449
1450 if (stream->isUnpreparable() || stream->hasOutstandingBuffers() ) {
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07001451 CLOGE("Stream %d has already been a request target", streamId);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001452 return BAD_VALUE;
1453 }
1454
1455 if (mRequestThread->isStreamPending(stream)) {
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07001456 CLOGE("Stream %d is already a target in a pending request", streamId);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001457 return BAD_VALUE;
1458 }
1459
Ruben Brunkc78ac262015-08-13 17:58:46 -07001460 return mPreparerThread->prepare(maxCount, stream);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001461}
1462
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001463status_t Camera3Device::tearDown(int streamId) {
1464 ATRACE_CALL();
1465 ALOGV("%s: Camera %d: Tearing down stream %d", __FUNCTION__, mId, streamId);
1466 Mutex::Autolock il(mInterfaceLock);
1467 Mutex::Autolock l(mLock);
1468
1469 // Teardown can only be accomplished on devices that don't require register_stream_buffers,
1470 // since we cannot call register_stream_buffers except right after configure_streams.
1471 if (mHal3Device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
1472 ALOGE("%s: Unable to tear down streams on device HAL v%x",
1473 __FUNCTION__, mHal3Device->common.version);
1474 return NO_INIT;
1475 }
1476
1477 sp<Camera3StreamInterface> stream;
1478 ssize_t outputStreamIdx = mOutputStreams.indexOfKey(streamId);
1479 if (outputStreamIdx == NAME_NOT_FOUND) {
1480 CLOGE("Stream %d does not exist", streamId);
1481 return BAD_VALUE;
1482 }
1483
1484 stream = mOutputStreams.editValueAt(outputStreamIdx);
1485
1486 if (stream->hasOutstandingBuffers() || mRequestThread->isStreamPending(stream)) {
1487 CLOGE("Stream %d is a target of a in-progress request", streamId);
1488 return BAD_VALUE;
1489 }
1490
1491 return stream->tearDown();
1492}
1493
Zhijun He204e3292014-07-14 17:09:23 -07001494uint32_t Camera3Device::getDeviceVersion() {
1495 ATRACE_CALL();
1496 Mutex::Autolock il(mInterfaceLock);
1497 return mDeviceVersion;
1498}
1499
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001500/**
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001501 * Methods called by subclasses
1502 */
1503
1504void Camera3Device::notifyStatus(bool idle) {
1505 {
1506 // Need mLock to safely update state and synchronize to current
1507 // state of methods in flight.
1508 Mutex::Autolock l(mLock);
1509 // We can get various system-idle notices from the status tracker
1510 // while starting up. Only care about them if we've actually sent
1511 // in some requests recently.
1512 if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
1513 return;
1514 }
1515 ALOGV("%s: Camera %d: Now %s", __FUNCTION__, mId,
1516 idle ? "idle" : "active");
Ruben Brunk183f0562015-08-12 12:55:02 -07001517 internalUpdateStatusLocked(idle ? STATUS_CONFIGURED : STATUS_ACTIVE);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001518
1519 // Skip notifying listener if we're doing some user-transparent
1520 // state changes
1521 if (mPauseStateNotify) return;
1522 }
1523 NotificationListener *listener;
1524 {
1525 Mutex::Autolock l(mOutputLock);
1526 listener = mListener;
1527 }
1528 if (idle && listener != NULL) {
1529 listener->notifyIdle();
1530 }
1531}
1532
1533/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001534 * Camera3Device private methods
1535 */
1536
1537sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
1538 const CameraMetadata &request) {
1539 ATRACE_CALL();
1540 status_t res;
1541
1542 sp<CaptureRequest> newRequest = new CaptureRequest;
1543 newRequest->mSettings = request;
1544
1545 camera_metadata_entry_t inputStreams =
1546 newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
1547 if (inputStreams.count > 0) {
1548 if (mInputStream == NULL ||
Zhijun Hed1d64672013-09-06 15:00:01 -07001549 mInputStream->getId() != inputStreams.data.i32[0]) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001550 CLOGE("Request references unknown input stream %d",
1551 inputStreams.data.u8[0]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001552 return NULL;
1553 }
1554 // Lazy completion of stream configuration (allocation/registration)
1555 // on first use
1556 if (mInputStream->isConfiguring()) {
1557 res = mInputStream->finishConfiguration(mHal3Device);
1558 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001559 SET_ERR_L("Unable to finish configuring input stream %d:"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001560 " %s (%d)",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001561 mInputStream->getId(), strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001562 return NULL;
1563 }
1564 }
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001565 // Check if stream is being prepared
1566 if (mInputStream->isPreparing()) {
1567 CLOGE("Request references an input stream that's being prepared!");
1568 return NULL;
1569 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001570
1571 newRequest->mInputStream = mInputStream;
1572 newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
1573 }
1574
1575 camera_metadata_entry_t streams =
1576 newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
1577 if (streams.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001578 CLOGE("Zero output streams specified!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001579 return NULL;
1580 }
1581
1582 for (size_t i = 0; i < streams.count; i++) {
Zhijun Hed1d64672013-09-06 15:00:01 -07001583 int idx = mOutputStreams.indexOfKey(streams.data.i32[i]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001584 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001585 CLOGE("Request references unknown stream %d",
1586 streams.data.u8[i]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001587 return NULL;
1588 }
Igor Murashkin2fba5842013-04-22 14:03:54 -07001589 sp<Camera3OutputStreamInterface> stream =
1590 mOutputStreams.editValueAt(idx);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001591
1592 // Lazy completion of stream configuration (allocation/registration)
1593 // on first use
1594 if (stream->isConfiguring()) {
1595 res = stream->finishConfiguration(mHal3Device);
1596 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001597 SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
1598 stream->getId(), strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001599 return NULL;
1600 }
1601 }
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001602 // Check if stream is being prepared
1603 if (stream->isPreparing()) {
1604 CLOGE("Request references an output stream that's being prepared!");
1605 return NULL;
1606 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001607
1608 newRequest->mOutputStreams.push(stream);
1609 }
1610 newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07001611 newRequest->mBatchSize = 1;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001612
1613 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001614}
1615
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001616bool Camera3Device::isOpaqueInputSizeSupported(uint32_t width, uint32_t height) {
1617 for (uint32_t i = 0; i < mSupportedOpaqueInputSizes.size(); i++) {
1618 Size size = mSupportedOpaqueInputSizes[i];
1619 if (size.width == width && size.height == height) {
1620 return true;
1621 }
1622 }
1623
1624 return false;
1625}
1626
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001627status_t Camera3Device::configureStreamsLocked() {
1628 ATRACE_CALL();
1629 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001630
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001631 if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001632 CLOGE("Not idle");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001633 return INVALID_OPERATION;
1634 }
1635
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001636 if (!mNeedConfig) {
1637 ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
1638 return OK;
1639 }
1640
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07001641 // Workaround for device HALv3.2 or older spec bug - zero streams requires
1642 // adding a dummy stream instead.
1643 // TODO: Bug: 17321404 for fixing the HAL spec and removing this workaround.
1644 if (mOutputStreams.size() == 0) {
1645 addDummyStreamLocked();
1646 } else {
1647 tryRemoveDummyStreamLocked();
1648 }
1649
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001650 // Start configuring the streams
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001651 ALOGV("%s: Camera %d: Starting stream configuration", __FUNCTION__, mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001652
1653 camera3_stream_configuration config;
Zhijun He1fa89992015-06-01 15:44:31 -07001654 config.operation_mode = mIsConstrainedHighSpeedConfiguration ?
1655 CAMERA3_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE :
1656 CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001657 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
1658
1659 Vector<camera3_stream_t*> streams;
1660 streams.setCapacity(config.num_streams);
1661
1662 if (mInputStream != NULL) {
1663 camera3_stream_t *inputStream;
1664 inputStream = mInputStream->startConfiguration();
1665 if (inputStream == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001666 SET_ERR_L("Can't start input stream configuration");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001667 return INVALID_OPERATION;
1668 }
1669 streams.add(inputStream);
1670 }
1671
1672 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Igor Murashkin2fba5842013-04-22 14:03:54 -07001673
1674 // Don't configure bidi streams twice, nor add them twice to the list
1675 if (mOutputStreams[i].get() ==
1676 static_cast<Camera3StreamInterface*>(mInputStream.get())) {
1677
1678 config.num_streams--;
1679 continue;
1680 }
1681
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001682 camera3_stream_t *outputStream;
1683 outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
1684 if (outputStream == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001685 SET_ERR_L("Can't start output stream configuration");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001686 return INVALID_OPERATION;
1687 }
1688 streams.add(outputStream);
1689 }
1690
1691 config.streams = streams.editArray();
1692
1693 // Do the HAL configuration; will potentially touch stream
1694 // max_buffers, usage, priv fields.
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001695 ATRACE_BEGIN("camera3->configure_streams");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001696 res = mHal3Device->ops->configure_streams(mHal3Device, &config);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001697 ATRACE_END();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001698
Eino-Ville Talvala17543512014-08-06 14:32:02 -07001699 if (res == BAD_VALUE) {
1700 // HAL rejected this set of streams as unsupported, clean up config
1701 // attempt and return to unconfigured state
1702 if (mInputStream != NULL && mInputStream->isConfiguring()) {
1703 res = mInputStream->cancelConfiguration();
1704 if (res != OK) {
1705 SET_ERR_L("Can't cancel configuring input stream %d: %s (%d)",
1706 mInputStream->getId(), strerror(-res), res);
1707 return res;
1708 }
1709 }
1710
1711 for (size_t i = 0; i < mOutputStreams.size(); i++) {
1712 sp<Camera3OutputStreamInterface> outputStream =
1713 mOutputStreams.editValueAt(i);
1714 if (outputStream->isConfiguring()) {
1715 res = outputStream->cancelConfiguration();
1716 if (res != OK) {
1717 SET_ERR_L(
1718 "Can't cancel configuring output stream %d: %s (%d)",
1719 outputStream->getId(), strerror(-res), res);
1720 return res;
1721 }
1722 }
1723 }
1724
1725 // Return state to that at start of call, so that future configures
1726 // properly clean things up
Ruben Brunk183f0562015-08-12 12:55:02 -07001727 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07001728 mNeedConfig = true;
1729
1730 ALOGV("%s: Camera %d: Stream configuration failed", __FUNCTION__, mId);
1731 return BAD_VALUE;
1732 } else if (res != OK) {
1733 // Some other kind of error from configure_streams - this is not
1734 // expected
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001735 SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
1736 strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001737 return res;
1738 }
1739
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07001740 // Finish all stream configuration immediately.
1741 // TODO: Try to relax this later back to lazy completion, which should be
1742 // faster
1743
Igor Murashkin073f8572013-05-02 14:59:28 -07001744 if (mInputStream != NULL && mInputStream->isConfiguring()) {
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07001745 res = mInputStream->finishConfiguration(mHal3Device);
1746 if (res != OK) {
1747 SET_ERR_L("Can't finish configuring input stream %d: %s (%d)",
1748 mInputStream->getId(), strerror(-res), res);
1749 return res;
1750 }
1751 }
1752
1753 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Igor Murashkin073f8572013-05-02 14:59:28 -07001754 sp<Camera3OutputStreamInterface> outputStream =
1755 mOutputStreams.editValueAt(i);
1756 if (outputStream->isConfiguring()) {
1757 res = outputStream->finishConfiguration(mHal3Device);
1758 if (res != OK) {
1759 SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
1760 outputStream->getId(), strerror(-res), res);
1761 return res;
1762 }
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07001763 }
1764 }
1765
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001766 // Request thread needs to know to avoid using repeat-last-settings protocol
1767 // across configure_streams() calls
1768 mRequestThread->configurationComplete();
1769
Eino-Ville Talvalaf99498e2015-09-25 16:52:55 -07001770 // Boost priority of request thread for high speed recording to SCHED_FIFO
1771 if (mIsConstrainedHighSpeedConfiguration) {
1772 pid_t requestThreadTid = mRequestThread->getTid();
1773 res = requestPriority(getpid(), requestThreadTid,
1774 kConstrainedHighSpeedThreadPriority, true);
1775 if (res != OK) {
1776 ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
1777 strerror(-res), res);
1778 } else {
1779 ALOGD("Set real time priority for request queue thread (tid %d)", requestThreadTid);
1780 }
1781 } else {
1782 // TODO: Set/restore normal priority for normal use cases
1783 }
1784
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001785 // Update device state
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001786
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001787 mNeedConfig = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001788
Ruben Brunk183f0562015-08-12 12:55:02 -07001789 internalUpdateStatusLocked((mDummyStreamId == NO_STREAM) ?
1790 STATUS_CONFIGURED : STATUS_UNCONFIGURED);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001791
1792 ALOGV("%s: Camera %d: Stream configuration complete", __FUNCTION__, mId);
1793
Zhijun He0a210512014-07-24 13:45:15 -07001794 // tear down the deleted streams after configure streams.
1795 mDeletedStreams.clear();
1796
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001797 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001798}
1799
Eino-Ville Talvala16a2ada2014-08-27 14:41:33 -07001800status_t Camera3Device::addDummyStreamLocked() {
1801 ATRACE_CALL();
1802 status_t res;
1803
1804 if (mDummyStreamId != NO_STREAM) {
1805 // Should never be adding a second dummy stream when one is already
1806 // active
1807 SET_ERR_L("%s: Camera %d: A dummy stream already exists!",
1808 __FUNCTION__, mId);
1809 return INVALID_OPERATION;
1810 }
1811
1812 ALOGV("%s: Camera %d: Adding a dummy stream", __FUNCTION__, mId);
1813
1814 sp<Camera3OutputStreamInterface> dummyStream =
1815 new Camera3DummyStream(mNextStreamId);
1816
1817 res = mOutputStreams.add(mNextStreamId, dummyStream);
1818 if (res < 0) {
1819 SET_ERR_L("Can't add dummy stream to set: %s (%d)", strerror(-res), res);
1820 return res;
1821 }
1822
1823 mDummyStreamId = mNextStreamId;
1824 mNextStreamId++;
1825
1826 return OK;
1827}
1828
1829status_t Camera3Device::tryRemoveDummyStreamLocked() {
1830 ATRACE_CALL();
1831 status_t res;
1832
1833 if (mDummyStreamId == NO_STREAM) return OK;
1834 if (mOutputStreams.size() == 1) return OK;
1835
1836 ALOGV("%s: Camera %d: Removing the dummy stream", __FUNCTION__, mId);
1837
1838 // Ok, have a dummy stream and there's at least one other output stream,
1839 // so remove the dummy
1840
1841 sp<Camera3StreamInterface> deletedStream;
1842 ssize_t outputStreamIdx = mOutputStreams.indexOfKey(mDummyStreamId);
1843 if (outputStreamIdx == NAME_NOT_FOUND) {
1844 SET_ERR_L("Dummy stream %d does not appear to exist", mDummyStreamId);
1845 return INVALID_OPERATION;
1846 }
1847
1848 deletedStream = mOutputStreams.editValueAt(outputStreamIdx);
1849 mOutputStreams.removeItemsAt(outputStreamIdx);
1850
1851 // Free up the stream endpoint so that it can be used by some other stream
1852 res = deletedStream->disconnect();
1853 if (res != OK) {
1854 SET_ERR_L("Can't disconnect deleted dummy stream %d", mDummyStreamId);
1855 // fall through since we want to still list the stream as deleted.
1856 }
1857 mDeletedStreams.add(deletedStream);
1858 mDummyStreamId = NO_STREAM;
1859
1860 return res;
1861}
1862
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001863void Camera3Device::setErrorState(const char *fmt, ...) {
1864 Mutex::Autolock l(mLock);
1865 va_list args;
1866 va_start(args, fmt);
1867
1868 setErrorStateLockedV(fmt, args);
1869
1870 va_end(args);
1871}
1872
1873void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
1874 Mutex::Autolock l(mLock);
1875 setErrorStateLockedV(fmt, args);
1876}
1877
1878void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
1879 va_list args;
1880 va_start(args, fmt);
1881
1882 setErrorStateLockedV(fmt, args);
1883
1884 va_end(args);
1885}
1886
1887void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001888 // Print out all error messages to log
1889 String8 errorCause = String8::formatV(fmt, args);
1890 ALOGE("Camera %d: %s", mId, errorCause.string());
1891
1892 // But only do error state transition steps for the first error
Zhijun Heb05eeae2013-06-06 13:51:22 -07001893 if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001894
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001895 mErrorCause = errorCause;
1896
1897 mRequestThread->setPaused(true);
Ruben Brunk183f0562015-08-12 12:55:02 -07001898 internalUpdateStatusLocked(STATUS_ERROR);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07001899
1900 // Notify upstream about a device error
1901 if (mListener != NULL) {
1902 mListener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
1903 CaptureResultExtras());
1904 }
1905
1906 // Save stack trace. View by dumping it later.
1907 CameraTraces::saveTrace();
1908 // TODO: consider adding errorCause and client pid/procname
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001909}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001910
1911/**
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001912 * In-flight request management
1913 */
1914
Jianing Weicb0652e2014-03-12 18:29:36 -07001915status_t Camera3Device::registerInFlight(uint32_t frameNumber,
Chien-Yu Chend196d612015-06-22 19:49:01 -07001916 int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
1917 const AeTriggerCancelOverride_t &aeTriggerCancelOverride) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001918 ATRACE_CALL();
1919 Mutex::Autolock l(mInFlightLock);
1920
1921 ssize_t res;
Chien-Yu Chend196d612015-06-22 19:49:01 -07001922 res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
1923 aeTriggerCancelOverride));
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001924 if (res < 0) return res;
1925
1926 return OK;
1927}
1928
1929/**
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001930 * Check if all 3A fields are ready, and send off a partial 3A-only result
1931 * to the output frame queue
1932 */
Zhijun He204e3292014-07-14 17:09:23 -07001933bool Camera3Device::processPartial3AResult(
Jianing Weicb0652e2014-03-12 18:29:36 -07001934 uint32_t frameNumber,
1935 const CameraMetadata& partial, const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001936
1937 // Check if all 3A states are present
1938 // The full list of fields is
1939 // android.control.afMode
1940 // android.control.awbMode
1941 // android.control.aeState
1942 // android.control.awbState
1943 // android.control.afState
1944 // android.control.afTriggerID
1945 // android.control.aePrecaptureID
1946 // TODO: Add android.control.aeMode
1947
1948 bool gotAllStates = true;
1949
1950 uint8_t afMode;
1951 uint8_t awbMode;
1952 uint8_t aeState;
1953 uint8_t afState;
1954 uint8_t awbState;
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001955
1956 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE,
1957 &afMode, frameNumber);
1958
1959 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE,
1960 &awbMode, frameNumber);
1961
1962 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE,
1963 &aeState, frameNumber);
1964
1965 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE,
1966 &afState, frameNumber);
1967
1968 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE,
1969 &awbState, frameNumber);
1970
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001971 if (!gotAllStates) return false;
1972
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001973 ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, "
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001974 "AF state %d, AE state %d, AWB state %d, "
1975 "AF trigger %d, AE precapture trigger %d",
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07001976 __FUNCTION__, mId, frameNumber, resultExtras.requestId,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001977 afMode, awbMode,
1978 afState, aeState, awbState,
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07001979 resultExtras.afTriggerId, resultExtras.precaptureTriggerId);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001980
1981 // Got all states, so construct a minimal result to send
1982 // In addition to the above fields, this means adding in
1983 // android.request.frameCount
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001984 // android.request.requestId
Zhijun He204e3292014-07-14 17:09:23 -07001985 // android.quirks.partialResult (for HAL version below HAL3.2)
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001986
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001987 const size_t kMinimal3AResultEntries = 10;
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001988
1989 Mutex::Autolock l(mOutputLock);
1990
Jianing Weicb0652e2014-03-12 18:29:36 -07001991 CaptureResult captureResult;
1992 captureResult.mResultExtras = resultExtras;
1993 captureResult.mMetadata = CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0);
1994 // TODO: change this to sp<CaptureResult>. This will need other changes, including,
1995 // but not limited to CameraDeviceBase::getNextResult
1996 CaptureResult& min3AResult =
1997 *mResultQueue.insert(mResultQueue.end(), captureResult);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001998
Jianing Weicb0652e2014-03-12 18:29:36 -07001999 if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_FRAME_COUNT,
2000 // TODO: This is problematic casting. Need to fix CameraMetadata.
2001 reinterpret_cast<int32_t*>(&frameNumber), frameNumber)) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002002 return false;
2003 }
2004
Jianing Weicb0652e2014-03-12 18:29:36 -07002005 int32_t requestId = resultExtras.requestId;
2006 if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_ID,
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08002007 &requestId, frameNumber)) {
2008 return false;
2009 }
2010
Zhijun He204e3292014-07-14 17:09:23 -07002011 if (mDeviceVersion < CAMERA_DEVICE_API_VERSION_3_2) {
2012 static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL;
2013 if (!insert3AResult(min3AResult.mMetadata, ANDROID_QUIRKS_PARTIAL_RESULT,
2014 &partialResult, frameNumber)) {
2015 return false;
2016 }
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002017 }
2018
Jianing Weicb0652e2014-03-12 18:29:36 -07002019 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_MODE,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002020 &afMode, frameNumber)) {
2021 return false;
2022 }
2023
Jianing Weicb0652e2014-03-12 18:29:36 -07002024 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_MODE,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002025 &awbMode, frameNumber)) {
2026 return false;
2027 }
2028
Jianing Weicb0652e2014-03-12 18:29:36 -07002029 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_STATE,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002030 &aeState, frameNumber)) {
2031 return false;
2032 }
2033
Jianing Weicb0652e2014-03-12 18:29:36 -07002034 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_STATE,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002035 &afState, frameNumber)) {
2036 return false;
2037 }
2038
Jianing Weicb0652e2014-03-12 18:29:36 -07002039 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_STATE,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002040 &awbState, frameNumber)) {
2041 return false;
2042 }
2043
Jianing Weicb0652e2014-03-12 18:29:36 -07002044 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_TRIGGER_ID,
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07002045 &resultExtras.afTriggerId, frameNumber)) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002046 return false;
2047 }
2048
Jianing Weicb0652e2014-03-12 18:29:36 -07002049 if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_PRECAPTURE_ID,
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07002050 &resultExtras.precaptureTriggerId, frameNumber)) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002051 return false;
2052 }
2053
Zhijun He204e3292014-07-14 17:09:23 -07002054 // We only send the aggregated partial when all 3A related metadata are available
2055 // For both API1 and API2.
2056 // TODO: we probably should pass through all partials to API2 unconditionally.
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002057 mResultSignal.signal();
2058
2059 return true;
2060}
2061
2062template<typename T>
2063bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag,
Jianing Weicb0652e2014-03-12 18:29:36 -07002064 T* value, uint32_t frameNumber) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002065 (void) frameNumber;
2066
2067 camera_metadata_ro_entry_t entry;
2068
2069 entry = result.find(tag);
2070 if (entry.count == 0) {
2071 ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__,
2072 mId, frameNumber, get_camera_metadata_tag_name(tag));
2073 return false;
2074 }
2075
2076 if (sizeof(T) == sizeof(uint8_t)) {
2077 *value = entry.data.u8[0];
2078 } else if (sizeof(T) == sizeof(int32_t)) {
2079 *value = entry.data.i32[0];
2080 } else {
2081 ALOGE("%s: Unexpected type", __FUNCTION__);
2082 return false;
2083 }
2084 return true;
2085}
2086
2087template<typename T>
2088bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag,
Jianing Weicb0652e2014-03-12 18:29:36 -07002089 const T* value, uint32_t frameNumber) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002090 if (result.update(tag, value, 1) != NO_ERROR) {
2091 mResultQueue.erase(--mResultQueue.end(), mResultQueue.end());
2092 SET_ERR("Frame %d: Failed to set %s in partial metadata",
2093 frameNumber, get_camera_metadata_tag_name(tag));
2094 return false;
2095 }
2096 return true;
2097}
2098
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002099void Camera3Device::returnOutputBuffers(
2100 const camera3_stream_buffer_t *outputBuffers, size_t numBuffers,
2101 nsecs_t timestamp) {
2102 for (size_t i = 0; i < numBuffers; i++)
2103 {
2104 Camera3Stream *stream = Camera3Stream::cast(outputBuffers[i].stream);
2105 status_t res = stream->returnBuffer(outputBuffers[i], timestamp);
2106 // Note: stream may be deallocated at this point, if this buffer was
2107 // the last reference to it.
2108 if (res != OK) {
2109 ALOGE("Can't return buffer to its stream: %s (%d)",
2110 strerror(-res), res);
2111 }
2112 }
2113}
2114
2115
2116void Camera3Device::removeInFlightRequestIfReadyLocked(int idx) {
2117
2118 const InFlightRequest &request = mInFlightMap.valueAt(idx);
2119 const uint32_t frameNumber = mInFlightMap.keyAt(idx);
2120
2121 nsecs_t sensorTimestamp = request.sensorTimestamp;
2122 nsecs_t shutterTimestamp = request.shutterTimestamp;
2123
2124 // Check if it's okay to remove the request from InFlightMap:
2125 // In the case of a successful request:
2126 // all input and output buffers, all result metadata, shutter callback
2127 // arrived.
2128 // In the case of a unsuccessful request:
2129 // all input and output buffers arrived.
2130 if (request.numBuffersLeft == 0 &&
2131 (request.requestStatus != OK ||
2132 (request.haveResultMetadata && shutterTimestamp != 0))) {
2133 ATRACE_ASYNC_END("frame capture", frameNumber);
2134
2135 // Sanity check - if sensor timestamp matches shutter timestamp
2136 if (request.requestStatus == OK &&
2137 sensorTimestamp != shutterTimestamp) {
2138 SET_ERR("sensor timestamp (%" PRId64
2139 ") for frame %d doesn't match shutter timestamp (%" PRId64 ")",
2140 sensorTimestamp, frameNumber, shutterTimestamp);
2141 }
2142
2143 // for an unsuccessful request, it may have pending output buffers to
2144 // return.
2145 assert(request.requestStatus != OK ||
2146 request.pendingOutputBuffers.size() == 0);
2147 returnOutputBuffers(request.pendingOutputBuffers.array(),
2148 request.pendingOutputBuffers.size(), 0);
2149
2150 mInFlightMap.removeItemsAt(idx, 1);
2151
2152 ALOGVV("%s: removed frame %d from InFlightMap", __FUNCTION__, frameNumber);
2153 }
2154
2155 // Sanity check - if we have too many in-flight frames, something has
2156 // likely gone wrong
Chien-Yu Chenc96ac8d2015-08-12 16:46:24 -07002157 if (!mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() > kInFlightWarnLimit) {
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002158 CLOGE("In-flight list too large: %zu", mInFlightMap.size());
Chien-Yu Chenc96ac8d2015-08-12 16:46:24 -07002159 } else if (mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() >
2160 kInFlightWarnLimitHighSpeed) {
2161 CLOGE("In-flight list too large for high speed configuration: %zu",
2162 mInFlightMap.size());
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002163 }
2164}
2165
2166
2167void Camera3Device::sendCaptureResult(CameraMetadata &pendingMetadata,
2168 CaptureResultExtras &resultExtras,
2169 CameraMetadata &collectedPartialResult,
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07002170 uint32_t frameNumber,
Chien-Yu Chend196d612015-06-22 19:49:01 -07002171 bool reprocess,
2172 const AeTriggerCancelOverride_t &aeTriggerCancelOverride) {
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002173 if (pendingMetadata.isEmpty())
2174 return;
2175
2176 Mutex::Autolock l(mOutputLock);
2177
2178 // TODO: need to track errors for tighter bounds on expected frame number
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07002179 if (reprocess) {
2180 if (frameNumber < mNextReprocessResultFrameNumber) {
2181 SET_ERR("Out-of-order reprocess capture result metadata submitted! "
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002182 "(got frame number %d, expecting %d)",
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07002183 frameNumber, mNextReprocessResultFrameNumber);
2184 return;
2185 }
2186 mNextReprocessResultFrameNumber = frameNumber + 1;
2187 } else {
2188 if (frameNumber < mNextResultFrameNumber) {
2189 SET_ERR("Out-of-order capture result metadata submitted! "
2190 "(got frame number %d, expecting %d)",
2191 frameNumber, mNextResultFrameNumber);
2192 return;
2193 }
2194 mNextResultFrameNumber = frameNumber + 1;
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002195 }
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002196
2197 CaptureResult captureResult;
2198 captureResult.mResultExtras = resultExtras;
2199 captureResult.mMetadata = pendingMetadata;
2200
2201 if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT,
2202 (int32_t*)&frameNumber, 1) != OK) {
2203 SET_ERR("Failed to set frame# in metadata (%d)",
2204 frameNumber);
2205 return;
2206 } else {
2207 ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
2208 __FUNCTION__, mId, frameNumber);
2209 }
2210
2211 // Append any previous partials to form a complete result
2212 if (mUsePartialResult && !collectedPartialResult.isEmpty()) {
2213 captureResult.mMetadata.append(collectedPartialResult);
2214 }
2215
2216 captureResult.mMetadata.sort();
2217
2218 // Check that there's a timestamp in the result metadata
2219 camera_metadata_entry entry =
2220 captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
2221 if (entry.count == 0) {
2222 SET_ERR("No timestamp provided by HAL for frame %d!",
2223 frameNumber);
2224 return;
2225 }
2226
Chien-Yu Chend196d612015-06-22 19:49:01 -07002227 overrideResultForPrecaptureCancel(&captureResult.mMetadata, aeTriggerCancelOverride);
2228
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002229 // Valid result, insert into queue
2230 List<CaptureResult>::iterator queuedResult =
2231 mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult));
2232 ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64
2233 ", burstId = %" PRId32, __FUNCTION__,
2234 queuedResult->mResultExtras.requestId,
2235 queuedResult->mResultExtras.frameNumber,
2236 queuedResult->mResultExtras.burstId);
2237
2238 mResultSignal.signal();
2239}
2240
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002241/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002242 * Camera HAL device callback methods
2243 */
2244
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002245void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002246 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002247
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002248 status_t res;
2249
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002250 uint32_t frameNumber = result->frame_number;
Zhijun Hef0d962a2014-06-30 10:24:11 -07002251 if (result->result == NULL && result->num_output_buffers == 0 &&
2252 result->input_buffer == NULL) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002253 SET_ERR("No result data provided by HAL for frame %d",
2254 frameNumber);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002255 return;
2256 }
Zhijun He204e3292014-07-14 17:09:23 -07002257
2258 // For HAL3.2 or above, If HAL doesn't support partial, it must always set
2259 // partial_result to 1 when metadata is included in this result.
2260 if (!mUsePartialResult &&
2261 mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
2262 result->result != NULL &&
2263 result->partial_result != 1) {
2264 SET_ERR("Result is malformed for frame %d: partial_result %u must be 1"
2265 " if partial result is not supported",
2266 frameNumber, result->partial_result);
2267 return;
2268 }
2269
2270 bool isPartialResult = false;
2271 CameraMetadata collectedPartialResult;
Jianing Weicb0652e2014-03-12 18:29:36 -07002272 CaptureResultExtras resultExtras;
Zhijun Hec98bd8d2014-07-07 12:44:10 -07002273 bool hasInputBufferInRequest = false;
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002274
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002275 // Get shutter timestamp and resultExtras from list of in-flight requests,
2276 // where it was added by the shutter notification for this frame. If the
2277 // shutter timestamp isn't received yet, append the output buffers to the
2278 // in-flight request and they will be returned when the shutter timestamp
2279 // arrives. Update the in-flight status and remove the in-flight entry if
2280 // all result data and shutter timestamp have been received.
2281 nsecs_t shutterTimestamp = 0;
2282
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002283 {
2284 Mutex::Autolock l(mInFlightLock);
2285 ssize_t idx = mInFlightMap.indexOfKey(frameNumber);
2286 if (idx == NAME_NOT_FOUND) {
2287 SET_ERR("Unknown frame number for capture result: %d",
2288 frameNumber);
2289 return;
2290 }
2291 InFlightRequest &request = mInFlightMap.editValueAt(idx);
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002292 ALOGVV("%s: got InFlightRequest requestId = %" PRId32
2293 ", frameNumber = %" PRId64 ", burstId = %" PRId32
2294 ", partialResultCount = %d",
2295 __FUNCTION__, request.resultExtras.requestId,
2296 request.resultExtras.frameNumber, request.resultExtras.burstId,
2297 result->partial_result);
2298 // Always update the partial count to the latest one if it's not 0
2299 // (buffers only). When framework aggregates adjacent partial results
2300 // into one, the latest partial count will be used.
2301 if (result->partial_result != 0)
2302 request.resultExtras.partialResultCount = result->partial_result;
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002303
2304 // Check if this result carries only partial metadata
Zhijun He204e3292014-07-14 17:09:23 -07002305 if (mUsePartialResult && result->result != NULL) {
2306 if (mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
2307 if (result->partial_result > mNumPartialResults || result->partial_result < 1) {
2308 SET_ERR("Result is malformed for frame %d: partial_result %u must be in"
2309 " the range of [1, %d] when metadata is included in the result",
2310 frameNumber, result->partial_result, mNumPartialResults);
2311 return;
2312 }
2313 isPartialResult = (result->partial_result < mNumPartialResults);
Zhijun He5d76e1a2014-07-22 16:08:13 -07002314 if (isPartialResult) {
2315 request.partialResult.collectedResult.append(result->result);
2316 }
Zhijun He204e3292014-07-14 17:09:23 -07002317 } else {
2318 camera_metadata_ro_entry_t partialResultEntry;
2319 res = find_camera_metadata_ro_entry(result->result,
2320 ANDROID_QUIRKS_PARTIAL_RESULT, &partialResultEntry);
2321 if (res != NAME_NOT_FOUND &&
2322 partialResultEntry.count > 0 &&
2323 partialResultEntry.data.u8[0] ==
2324 ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
2325 // A partial result. Flag this as such, and collect this
2326 // set of metadata into the in-flight entry.
2327 isPartialResult = true;
2328 request.partialResult.collectedResult.append(
2329 result->result);
2330 request.partialResult.collectedResult.erase(
2331 ANDROID_QUIRKS_PARTIAL_RESULT);
2332 }
2333 }
2334
2335 if (isPartialResult) {
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002336 // Fire off a 3A-only result if possible
Zhijun He204e3292014-07-14 17:09:23 -07002337 if (!request.partialResult.haveSent3A) {
2338 request.partialResult.haveSent3A =
2339 processPartial3AResult(frameNumber,
2340 request.partialResult.collectedResult,
Jianing Weicb0652e2014-03-12 18:29:36 -07002341 request.resultExtras);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002342 }
2343 }
2344 }
2345
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002346 shutterTimestamp = request.shutterTimestamp;
Zhijun Hec98bd8d2014-07-07 12:44:10 -07002347 hasInputBufferInRequest = request.hasInputBuffer;
Jianing Weicb0652e2014-03-12 18:29:36 -07002348
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002349 // Did we get the (final) result metadata for this capture?
Zhijun He204e3292014-07-14 17:09:23 -07002350 if (result->result != NULL && !isPartialResult) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002351 if (request.haveResultMetadata) {
2352 SET_ERR("Called multiple times with metadata for frame %d",
2353 frameNumber);
2354 return;
2355 }
Zhijun He204e3292014-07-14 17:09:23 -07002356 if (mUsePartialResult &&
2357 !request.partialResult.collectedResult.isEmpty()) {
2358 collectedPartialResult.acquire(
2359 request.partialResult.collectedResult);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002360 }
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002361 request.haveResultMetadata = true;
2362 }
2363
Zhijun Hec98bd8d2014-07-07 12:44:10 -07002364 uint32_t numBuffersReturned = result->num_output_buffers;
2365 if (result->input_buffer != NULL) {
2366 if (hasInputBufferInRequest) {
2367 numBuffersReturned += 1;
2368 } else {
2369 ALOGW("%s: Input buffer should be NULL if there is no input"
2370 " buffer sent in the request",
2371 __FUNCTION__);
2372 }
2373 }
2374 request.numBuffersLeft -= numBuffersReturned;
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002375 if (request.numBuffersLeft < 0) {
2376 SET_ERR("Too many buffers returned for frame %d",
2377 frameNumber);
2378 return;
2379 }
2380
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002381 camera_metadata_ro_entry_t entry;
2382 res = find_camera_metadata_ro_entry(result->result,
2383 ANDROID_SENSOR_TIMESTAMP, &entry);
2384 if (res == OK && entry.count == 1) {
2385 request.sensorTimestamp = entry.data.i64[0];
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002386 }
2387
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002388 // If shutter event isn't received yet, append the output buffers to
2389 // the in-flight request. Otherwise, return the output buffers to
2390 // streams.
2391 if (shutterTimestamp == 0) {
2392 request.pendingOutputBuffers.appendArray(result->output_buffers,
2393 result->num_output_buffers);
Igor Murashkind2c90692013-04-02 12:32:32 -07002394 } else {
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002395 returnOutputBuffers(result->output_buffers,
2396 result->num_output_buffers, shutterTimestamp);
Igor Murashkind2c90692013-04-02 12:32:32 -07002397 }
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002398
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002399 if (result->result != NULL && !isPartialResult) {
2400 if (shutterTimestamp == 0) {
2401 request.pendingMetadata = result->result;
2402 request.partialResult.collectedResult = collectedPartialResult;
2403 } else {
2404 CameraMetadata metadata;
2405 metadata = result->result;
2406 sendCaptureResult(metadata, request.resultExtras,
Chien-Yu Chend196d612015-06-22 19:49:01 -07002407 collectedPartialResult, frameNumber, hasInputBufferInRequest,
2408 request.aeTriggerCancelOverride);
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002409 }
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07002410 }
2411
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002412 removeInFlightRequestIfReadyLocked(idx);
2413 } // scope for mInFlightLock
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002414
Zhijun Hef0d962a2014-06-30 10:24:11 -07002415 if (result->input_buffer != NULL) {
Zhijun Hec98bd8d2014-07-07 12:44:10 -07002416 if (hasInputBufferInRequest) {
2417 Camera3Stream *stream =
2418 Camera3Stream::cast(result->input_buffer->stream);
2419 res = stream->returnInputBuffer(*(result->input_buffer));
2420 // Note: stream may be deallocated at this point, if this buffer was the
2421 // last reference to it.
2422 if (res != OK) {
2423 ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
2424 " its stream:%s (%d)", __FUNCTION__,
2425 frameNumber, strerror(-res), res);
Zhijun He0ea8fa42014-07-07 17:05:38 -07002426 }
2427 } else {
2428 ALOGW("%s: Input buffer should be NULL if there is no input"
2429 " buffer sent in the request, skipping input buffer return.",
2430 __FUNCTION__);
Zhijun Hef0d962a2014-06-30 10:24:11 -07002431 }
2432 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002433}
2434
2435void Camera3Device::notify(const camera3_notify_msg *msg) {
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07002436 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002437 NotificationListener *listener;
2438 {
2439 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002440 listener = mListener;
2441 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002442
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002443 if (msg == NULL) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002444 SET_ERR("HAL sent NULL notify message!");
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002445 return;
2446 }
2447
2448 switch (msg->type) {
2449 case CAMERA3_MSG_ERROR: {
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002450 notifyError(msg->message.error, listener);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002451 break;
2452 }
2453 case CAMERA3_MSG_SHUTTER: {
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002454 notifyShutter(msg->message.shutter, listener);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002455 break;
2456 }
2457 default:
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002458 SET_ERR("Unknown notify message from HAL: %d",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002459 msg->type);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07002460 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002461}
2462
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002463void Camera3Device::notifyError(const camera3_error_msg_t &msg,
2464 NotificationListener *listener) {
2465
2466 // Map camera HAL error codes to ICameraDeviceCallback error codes
2467 // Index into this with the HAL error code
2468 static const ICameraDeviceCallbacks::CameraErrorCode
2469 halErrorMap[CAMERA3_MSG_NUM_ERRORS] = {
2470 // 0 = Unused error code
2471 ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR,
2472 // 1 = CAMERA3_MSG_ERROR_DEVICE
2473 ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
2474 // 2 = CAMERA3_MSG_ERROR_REQUEST
2475 ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
2476 // 3 = CAMERA3_MSG_ERROR_RESULT
2477 ICameraDeviceCallbacks::ERROR_CAMERA_RESULT,
2478 // 4 = CAMERA3_MSG_ERROR_BUFFER
2479 ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER
2480 };
2481
2482 ICameraDeviceCallbacks::CameraErrorCode errorCode =
2483 ((msg.error_code >= 0) &&
2484 (msg.error_code < CAMERA3_MSG_NUM_ERRORS)) ?
2485 halErrorMap[msg.error_code] :
2486 ICameraDeviceCallbacks::ERROR_CAMERA_INVALID_ERROR;
2487
2488 int streamId = 0;
2489 if (msg.error_stream != NULL) {
2490 Camera3Stream *stream =
2491 Camera3Stream::cast(msg.error_stream);
2492 streamId = stream->getId();
2493 }
2494 ALOGV("Camera %d: %s: HAL error, frame %d, stream %d: %d",
2495 mId, __FUNCTION__, msg.frame_number,
2496 streamId, msg.error_code);
2497
2498 CaptureResultExtras resultExtras;
2499 switch (errorCode) {
2500 case ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE:
2501 // SET_ERR calls notifyError
2502 SET_ERR("Camera HAL reported serious device error");
2503 break;
2504 case ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST:
2505 case ICameraDeviceCallbacks::ERROR_CAMERA_RESULT:
2506 case ICameraDeviceCallbacks::ERROR_CAMERA_BUFFER:
2507 {
2508 Mutex::Autolock l(mInFlightLock);
2509 ssize_t idx = mInFlightMap.indexOfKey(msg.frame_number);
2510 if (idx >= 0) {
2511 InFlightRequest &r = mInFlightMap.editValueAt(idx);
2512 r.requestStatus = msg.error_code;
2513 resultExtras = r.resultExtras;
2514 } else {
2515 resultExtras.frameNumber = msg.frame_number;
2516 ALOGE("Camera %d: %s: cannot find in-flight request on "
2517 "frame %" PRId64 " error", mId, __FUNCTION__,
2518 resultExtras.frameNumber);
2519 }
2520 }
2521 if (listener != NULL) {
2522 listener->notifyError(errorCode, resultExtras);
2523 } else {
2524 ALOGE("Camera %d: %s: no listener available", mId, __FUNCTION__);
2525 }
2526 break;
2527 default:
2528 // SET_ERR calls notifyError
2529 SET_ERR("Unknown error message from HAL: %d", msg.error_code);
2530 break;
2531 }
2532}
2533
2534void Camera3Device::notifyShutter(const camera3_shutter_msg_t &msg,
2535 NotificationListener *listener) {
2536 ssize_t idx;
2537 // Verify ordering of shutter notifications
2538 {
2539 Mutex::Autolock l(mOutputLock);
2540 // TODO: need to track errors for tighter bounds on expected frame number.
2541 if (msg.frame_number < mNextShutterFrameNumber) {
2542 SET_ERR("Shutter notification out-of-order. Expected "
2543 "notification for frame %d, got frame %d",
2544 mNextShutterFrameNumber, msg.frame_number);
2545 return;
2546 }
2547 mNextShutterFrameNumber = msg.frame_number + 1;
2548 }
2549
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002550 // Set timestamp for the request in the in-flight tracking
2551 // and get the request ID to send upstream
2552 {
2553 Mutex::Autolock l(mInFlightLock);
2554 idx = mInFlightMap.indexOfKey(msg.frame_number);
2555 if (idx >= 0) {
2556 InFlightRequest &r = mInFlightMap.editValueAt(idx);
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002557
2558 ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
2559 mId, __FUNCTION__,
2560 msg.frame_number, r.resultExtras.requestId, msg.timestamp);
2561 // Call listener, if any
2562 if (listener != NULL) {
2563 listener->notifyShutter(r.resultExtras, msg.timestamp);
2564 }
2565
2566 r.shutterTimestamp = msg.timestamp;
2567
2568 // send pending result and buffers
2569 sendCaptureResult(r.pendingMetadata, r.resultExtras,
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07002570 r.partialResult.collectedResult, msg.frame_number,
Chien-Yu Chend196d612015-06-22 19:49:01 -07002571 r.hasInputBuffer, r.aeTriggerCancelOverride);
Chien-Yu Chen43e69a62014-11-25 16:38:33 -08002572 returnOutputBuffers(r.pendingOutputBuffers.array(),
2573 r.pendingOutputBuffers.size(), r.shutterTimestamp);
2574 r.pendingOutputBuffers.clear();
2575
2576 removeInFlightRequestIfReadyLocked(idx);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002577 }
2578 }
2579 if (idx < 0) {
2580 SET_ERR("Shutter notification for non-existent frame number %d",
2581 msg.frame_number);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002582 }
2583}
2584
2585
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002586CameraMetadata Camera3Device::getLatestRequestLocked() {
Igor Murashkin1e479c02013-09-06 16:55:14 -07002587 ALOGV("%s", __FUNCTION__);
2588
Igor Murashkin1e479c02013-09-06 16:55:14 -07002589 CameraMetadata retVal;
2590
2591 if (mRequestThread != NULL) {
2592 retVal = mRequestThread->getLatestRequest();
2593 }
2594
Igor Murashkin1e479c02013-09-06 16:55:14 -07002595 return retVal;
2596}
2597
Jianing Weicb0652e2014-03-12 18:29:36 -07002598
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002599/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002600 * RequestThread inner class methods
2601 */
2602
2603Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002604 sp<StatusTracker> statusTracker,
Chien-Yu Chenab5135b2015-06-30 11:20:58 -07002605 camera3_device_t *hal3Device,
2606 bool aeLockAvailable) :
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002607 Thread(/*canCallJava*/false),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002608 mParent(parent),
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002609 mStatusTracker(statusTracker),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002610 mHal3Device(hal3Device),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002611 mId(getId(parent)),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002612 mReconfigured(false),
2613 mDoPause(false),
2614 mPaused(true),
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002615 mFrameNumber(0),
Jianing Weicb0652e2014-03-12 18:29:36 -07002616 mLatestRequestId(NAME_NOT_FOUND),
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07002617 mCurrentAfTriggerId(0),
2618 mCurrentPreCaptureTriggerId(0),
Chien-Yu Chenab5135b2015-06-30 11:20:58 -07002619 mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES),
2620 mAeLockAvailable(aeLockAvailable) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002621 mStatusId = statusTracker->addComponent();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002622}
2623
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002624void Camera3Device::RequestThread::setNotificationListener(
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002625 NotificationListener *listener) {
2626 Mutex::Autolock l(mRequestLock);
2627 mListener = listener;
2628}
2629
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002630void Camera3Device::RequestThread::configurationComplete() {
2631 Mutex::Autolock l(mRequestLock);
2632 mReconfigured = true;
2633}
2634
Jianing Wei90e59c92014-03-12 18:29:36 -07002635status_t Camera3Device::RequestThread::queueRequestList(
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002636 List<sp<CaptureRequest> > &requests,
2637 /*out*/
2638 int64_t *lastFrameNumber) {
Jianing Wei90e59c92014-03-12 18:29:36 -07002639 Mutex::Autolock l(mRequestLock);
2640 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
2641 ++it) {
2642 mRequestQueue.push_back(*it);
2643 }
2644
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002645 if (lastFrameNumber != NULL) {
2646 *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
2647 ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
2648 __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
2649 *lastFrameNumber);
2650 }
Jianing Weicb0652e2014-03-12 18:29:36 -07002651
Jianing Wei90e59c92014-03-12 18:29:36 -07002652 unpauseForNewRequests();
2653
2654 return OK;
2655}
2656
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002657
2658status_t Camera3Device::RequestThread::queueTrigger(
2659 RequestTrigger trigger[],
2660 size_t count) {
2661
2662 Mutex::Autolock l(mTriggerMutex);
2663 status_t ret;
2664
2665 for (size_t i = 0; i < count; ++i) {
2666 ret = queueTriggerLocked(trigger[i]);
2667
2668 if (ret != OK) {
2669 return ret;
2670 }
2671 }
2672
2673 return OK;
2674}
2675
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002676int Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
2677 sp<Camera3Device> d = device.promote();
2678 if (d != NULL) return d->mId;
2679 return 0;
2680}
2681
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002682status_t Camera3Device::RequestThread::queueTriggerLocked(
2683 RequestTrigger trigger) {
2684
2685 uint32_t tag = trigger.metadataTag;
2686 ssize_t index = mTriggerMap.indexOfKey(tag);
2687
2688 switch (trigger.getTagType()) {
2689 case TYPE_BYTE:
2690 // fall-through
2691 case TYPE_INT32:
2692 break;
2693 default:
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002694 ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
2695 trigger.getTagType());
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002696 return INVALID_OPERATION;
2697 }
2698
2699 /**
2700 * Collect only the latest trigger, since we only have 1 field
2701 * in the request settings per trigger tag, and can't send more than 1
2702 * trigger per request.
2703 */
2704 if (index != NAME_NOT_FOUND) {
2705 mTriggerMap.editValueAt(index) = trigger;
2706 } else {
2707 mTriggerMap.add(tag, trigger);
2708 }
2709
2710 return OK;
2711}
2712
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002713status_t Camera3Device::RequestThread::setRepeatingRequests(
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002714 const RequestList &requests,
2715 /*out*/
2716 int64_t *lastFrameNumber) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002717 Mutex::Autolock l(mRequestLock);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002718 if (lastFrameNumber != NULL) {
2719 *lastFrameNumber = mRepeatingLastFrameNumber;
2720 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002721 mRepeatingRequests.clear();
2722 mRepeatingRequests.insert(mRepeatingRequests.begin(),
2723 requests.begin(), requests.end());
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07002724
2725 unpauseForNewRequests();
2726
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002727 mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002728 return OK;
2729}
2730
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07002731bool Camera3Device::RequestThread::isRepeatingRequestLocked(const sp<CaptureRequest> requestIn) {
2732 if (mRepeatingRequests.empty()) {
2733 return false;
2734 }
2735 int32_t requestId = requestIn->mResultExtras.requestId;
2736 const RequestList &repeatRequests = mRepeatingRequests;
2737 // All repeating requests are guaranteed to have same id so only check first quest
2738 const sp<CaptureRequest> firstRequest = *repeatRequests.begin();
2739 return (firstRequest->mResultExtras.requestId == requestId);
2740}
2741
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002742status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002743 Mutex::Autolock l(mRequestLock);
2744 mRepeatingRequests.clear();
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002745 if (lastFrameNumber != NULL) {
2746 *lastFrameNumber = mRepeatingLastFrameNumber;
2747 }
2748 mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002749 return OK;
2750}
2751
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002752status_t Camera3Device::RequestThread::clear(
2753 NotificationListener *listener,
2754 /*out*/int64_t *lastFrameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002755 Mutex::Autolock l(mRequestLock);
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002756 ALOGV("RequestThread::%s:", __FUNCTION__);
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002757
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002758 mRepeatingRequests.clear();
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07002759
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002760 // Send errors for all requests pending in the request queue, including
2761 // pending repeating requests
2762 if (listener != NULL) {
2763 for (RequestList::iterator it = mRequestQueue.begin();
2764 it != mRequestQueue.end(); ++it) {
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07002765 // Abort the input buffers for reprocess requests.
2766 if ((*it)->mInputStream != NULL) {
2767 camera3_stream_buffer_t inputBuffer;
2768 status_t res = (*it)->mInputStream->getInputBuffer(&inputBuffer);
2769 if (res != OK) {
2770 ALOGW("%s: %d: couldn't get input buffer while clearing the request "
2771 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
2772 } else {
2773 res = (*it)->mInputStream->returnInputBuffer(inputBuffer);
2774 if (res != OK) {
2775 ALOGE("%s: %d: couldn't return input buffer while clearing the request "
2776 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
2777 }
2778 }
2779 }
Eino-Ville Talvala17543512014-08-06 14:32:02 -07002780 // Set the frame number this request would have had, if it
2781 // had been submitted; this frame number will not be reused.
2782 // The requestId and burstId fields were set when the request was
2783 // submitted originally (in convertMetadataListToRequestListLocked)
2784 (*it)->mResultExtras.frameNumber = mFrameNumber++;
2785 listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
2786 (*it)->mResultExtras);
Yin-Chia Yeh8684b7f2014-06-13 14:53:05 -07002787 }
2788 }
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002789 mRequestQueue.clear();
2790 mTriggerMap.clear();
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07002791 if (lastFrameNumber != NULL) {
2792 *lastFrameNumber = mRepeatingLastFrameNumber;
2793 }
2794 mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07002795 return OK;
2796}
2797
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002798status_t Camera3Device::RequestThread::flush() {
2799 ATRACE_CALL();
2800 Mutex::Autolock l(mFlushLock);
2801
2802 if (mHal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_1) {
2803 return mHal3Device->ops->flush(mHal3Device);
2804 }
2805
2806 return -ENOTSUP;
2807}
2808
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002809void Camera3Device::RequestThread::setPaused(bool paused) {
2810 Mutex::Autolock l(mPauseLock);
2811 mDoPause = paused;
2812 mDoPauseSignal.signal();
2813}
2814
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002815status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
2816 int32_t requestId, nsecs_t timeout) {
2817 Mutex::Autolock l(mLatestRequestMutex);
2818 status_t res;
2819 while (mLatestRequestId != requestId) {
2820 nsecs_t startTime = systemTime();
2821
2822 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
2823 if (res != OK) return res;
2824
2825 timeout -= (systemTime() - startTime);
2826 }
2827
2828 return OK;
2829}
2830
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002831void Camera3Device::RequestThread::requestExit() {
2832 // Call parent to set up shutdown
2833 Thread::requestExit();
2834 // The exit from any possible waits
2835 mDoPauseSignal.signal();
2836 mRequestSignal.signal();
2837}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002838
Chien-Yu Chend196d612015-06-22 19:49:01 -07002839
2840/**
2841 * For devices <= CAMERA_DEVICE_API_VERSION_3_2, AE_PRECAPTURE_TRIGGER_CANCEL is not supported so
2842 * we need to override AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE and AE_LOCK_OFF
2843 * to AE_LOCK_ON to start cancelling AE precapture. If AE lock is not available, it still overrides
2844 * AE_PRECAPTURE_TRIGGER_CANCEL to AE_PRECAPTURE_TRIGGER_IDLE but doesn't add AE_LOCK_ON to the
2845 * request.
2846 */
2847void Camera3Device::RequestThread::handleAePrecaptureCancelRequest(sp<CaptureRequest> request) {
2848 request->mAeTriggerCancelOverride.applyAeLock = false;
2849 request->mAeTriggerCancelOverride.applyAePrecaptureTrigger = false;
2850
2851 if (mHal3Device->common.version > CAMERA_DEVICE_API_VERSION_3_2) {
2852 return;
2853 }
2854
2855 camera_metadata_entry_t aePrecaptureTrigger =
2856 request->mSettings.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
2857 if (aePrecaptureTrigger.count > 0 &&
2858 aePrecaptureTrigger.data.u8[0] == ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL) {
2859 // Always override CANCEL to IDLE
2860 uint8_t aePrecaptureTrigger = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE;
2861 request->mSettings.update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &aePrecaptureTrigger, 1);
2862 request->mAeTriggerCancelOverride.applyAePrecaptureTrigger = true;
2863 request->mAeTriggerCancelOverride.aePrecaptureTrigger =
2864 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL;
2865
2866 if (mAeLockAvailable == true) {
2867 camera_metadata_entry_t aeLock = request->mSettings.find(ANDROID_CONTROL_AE_LOCK);
2868 if (aeLock.count == 0 || aeLock.data.u8[0] == ANDROID_CONTROL_AE_LOCK_OFF) {
2869 uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_ON;
2870 request->mSettings.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1);
2871 request->mAeTriggerCancelOverride.applyAeLock = true;
2872 request->mAeTriggerCancelOverride.aeLock = ANDROID_CONTROL_AE_LOCK_OFF;
2873 }
2874 }
2875 }
2876}
2877
2878/**
2879 * Override result metadata for cancelling AE precapture trigger applied in
2880 * handleAePrecaptureCancelRequest().
2881 */
2882void Camera3Device::overrideResultForPrecaptureCancel(
2883 CameraMetadata *result, const AeTriggerCancelOverride_t &aeTriggerCancelOverride) {
2884 if (aeTriggerCancelOverride.applyAeLock) {
2885 // Only devices <= v3.2 should have this override
2886 assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2);
2887 result->update(ANDROID_CONTROL_AE_LOCK, &aeTriggerCancelOverride.aeLock, 1);
2888 }
2889
2890 if (aeTriggerCancelOverride.applyAePrecaptureTrigger) {
2891 // Only devices <= v3.2 should have this override
2892 assert(mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_2);
2893 result->update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
2894 &aeTriggerCancelOverride.aePrecaptureTrigger, 1);
2895 }
2896}
2897
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002898bool Camera3Device::RequestThread::threadLoop() {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002899 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002900 status_t res;
2901
2902 // Handle paused state.
2903 if (waitIfPaused()) {
2904 return true;
2905 }
2906
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07002907 // Wait for the next batch of requests.
2908 waitForNextRequestBatch();
2909 if (mNextRequests.size() == 0) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002910 return true;
2911 }
2912
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002913 // Get the latest request ID, if any
2914 int latestRequestId;
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07002915 camera_metadata_entry_t requestIdEntry = mNextRequests[mNextRequests.size() - 1].
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002916 captureRequest->mSettings.find(ANDROID_REQUEST_ID);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002917 if (requestIdEntry.count > 0) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002918 latestRequestId = requestIdEntry.data.i32[0];
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002919 } else {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002920 ALOGW("%s: Did not have android.request.id set in the request.", __FUNCTION__);
2921 latestRequestId = NAME_NOT_FOUND;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002922 }
2923
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002924 // Prepare a batch of HAL requests and output buffers.
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07002925 res = prepareHalRequests();
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002926 if (res == TIMED_OUT) {
2927 // Not a fatal error if getting output buffers time out.
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07002928 cleanUpFailedRequests(/*sendRequestError*/ true);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002929 return true;
2930 } else if (res != OK) {
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07002931 cleanUpFailedRequests(/*sendRequestError*/ false);
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002932 return false;
2933 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002934
Zhijun Hecc27e112013-10-03 16:12:43 -07002935 // Inform waitUntilRequestProcessed thread of a new request ID
2936 {
2937 Mutex::Autolock al(mLatestRequestMutex);
2938
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002939 mLatestRequestId = latestRequestId;
Zhijun Hecc27e112013-10-03 16:12:43 -07002940 mLatestRequestSignal.signal();
2941 }
2942
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002943 // Submit a batch of requests to HAL.
2944 // Use flush lock only when submitting multilple requests in a batch.
2945 // TODO: The problem with flush lock is flush() will be blocked by process_capture_request()
2946 // which may take a long time to finish so synchronizing flush() and
2947 // process_capture_request() defeats the purpose of cancelling requests ASAP with flush().
2948 // For now, only synchronize for high speed recording and we should figure something out for
2949 // removing the synchronization.
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07002950 bool useFlushLock = mNextRequests.size() > 1;
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07002951
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002952 if (useFlushLock) {
2953 mFlushLock.lock();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002954 }
2955
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002956 ALOGVV("%s: %d: submitting %d requests in a batch.", __FUNCTION__, __LINE__,
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07002957 mNextRequests.size());
2958 for (auto& nextRequest : mNextRequests) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002959 // Submit request and block until ready for next one
2960 ATRACE_ASYNC_BEGIN("frame capture", nextRequest.halRequest.frame_number);
2961 ATRACE_BEGIN("camera3->process_capture_request");
2962 res = mHal3Device->ops->process_capture_request(mHal3Device, &nextRequest.halRequest);
2963 ATRACE_END();
Igor Murashkin1e479c02013-09-06 16:55:14 -07002964
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002965 if (res != OK) {
2966 // Should only get a failure here for malformed requests or device-level
2967 // errors, so consider all errors fatal. Bad metadata failures should
2968 // come through notify.
2969 SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
2970 " device: %s (%d)", nextRequest.halRequest.frame_number, strerror(-res),
2971 res);
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07002972 cleanUpFailedRequests(/*sendRequestError*/ false);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07002973 if (useFlushLock) {
2974 mFlushLock.unlock();
2975 }
2976 return false;
2977 }
2978
2979 // Mark that the request has be submitted successfully.
2980 nextRequest.submitted = true;
2981
2982 // Update the latest request sent to HAL
2983 if (nextRequest.halRequest.settings != NULL) { // Don't update if they were unchanged
2984 Mutex::Autolock al(mLatestRequestMutex);
2985
2986 camera_metadata_t* cloned = clone_camera_metadata(nextRequest.halRequest.settings);
2987 mLatestRequest.acquire(cloned);
2988 }
2989
2990 if (nextRequest.halRequest.settings != NULL) {
2991 nextRequest.captureRequest->mSettings.unlock(nextRequest.halRequest.settings);
2992 }
2993
2994 // Remove any previously queued triggers (after unlock)
2995 res = removeTriggers(mPrevRequest);
2996 if (res != OK) {
2997 SET_ERR("RequestThread: Unable to remove triggers "
2998 "(capture request %d, HAL device: %s (%d)",
2999 nextRequest.halRequest.frame_number, strerror(-res), res);
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07003000 cleanUpFailedRequests(/*sendRequestError*/ false);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003001 if (useFlushLock) {
3002 mFlushLock.unlock();
3003 }
3004 return false;
3005 }
Igor Murashkin1e479c02013-09-06 16:55:14 -07003006 }
3007
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003008 if (useFlushLock) {
3009 mFlushLock.unlock();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003010 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003011
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07003012 // Unset as current request
3013 {
3014 Mutex::Autolock l(mRequestLock);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003015 mNextRequests.clear();
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07003016 }
3017
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003018 return true;
3019}
3020
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07003021status_t Camera3Device::RequestThread::prepareHalRequests() {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003022 ATRACE_CALL();
3023
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07003024 for (auto& nextRequest : mNextRequests) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003025 sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
3026 camera3_capture_request_t* halRequest = &nextRequest.halRequest;
3027 Vector<camera3_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
3028
3029 // Prepare a request to HAL
3030 halRequest->frame_number = captureRequest->mResultExtras.frameNumber;
3031
3032 // Insert any queued triggers (before metadata is locked)
3033 status_t res = insertTriggers(captureRequest);
3034
3035 if (res < 0) {
3036 SET_ERR("RequestThread: Unable to insert triggers "
3037 "(capture request %d, HAL device: %s (%d)",
3038 halRequest->frame_number, strerror(-res), res);
3039 return INVALID_OPERATION;
3040 }
3041 int triggerCount = res;
3042 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
3043 mPrevTriggers = triggerCount;
3044
3045 // If the request is the same as last, or we had triggers last time
3046 if (mPrevRequest != captureRequest || triggersMixedIn) {
3047 /**
3048 * HAL workaround:
3049 * Insert a dummy trigger ID if a trigger is set but no trigger ID is
3050 */
3051 res = addDummyTriggerIds(captureRequest);
3052 if (res != OK) {
3053 SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
3054 "(capture request %d, HAL device: %s (%d)",
3055 halRequest->frame_number, strerror(-res), res);
3056 return INVALID_OPERATION;
3057 }
3058
3059 /**
3060 * The request should be presorted so accesses in HAL
3061 * are O(logn). Sidenote, sorting a sorted metadata is nop.
3062 */
3063 captureRequest->mSettings.sort();
3064 halRequest->settings = captureRequest->mSettings.getAndLock();
3065 mPrevRequest = captureRequest;
3066 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
3067
3068 IF_ALOGV() {
3069 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
3070 find_camera_metadata_ro_entry(
3071 halRequest->settings,
3072 ANDROID_CONTROL_AF_TRIGGER,
3073 &e
3074 );
3075 if (e.count > 0) {
3076 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
3077 __FUNCTION__,
3078 halRequest->frame_number,
3079 e.data.u8[0]);
3080 }
3081 }
3082 } else {
3083 // leave request.settings NULL to indicate 'reuse latest given'
3084 ALOGVV("%s: Request settings are REUSED",
3085 __FUNCTION__);
3086 }
3087
3088 uint32_t totalNumBuffers = 0;
3089
3090 // Fill in buffers
3091 if (captureRequest->mInputStream != NULL) {
3092 halRequest->input_buffer = &captureRequest->mInputBuffer;
3093 totalNumBuffers += 1;
3094 } else {
3095 halRequest->input_buffer = NULL;
3096 }
3097
3098 outputBuffers->insertAt(camera3_stream_buffer_t(), 0,
3099 captureRequest->mOutputStreams.size());
3100 halRequest->output_buffers = outputBuffers->array();
3101 for (size_t i = 0; i < captureRequest->mOutputStreams.size(); i++) {
3102 res = captureRequest->mOutputStreams.editItemAt(i)->
3103 getBuffer(&outputBuffers->editItemAt(i));
3104 if (res != OK) {
3105 // Can't get output buffer from gralloc queue - this could be due to
3106 // abandoned queue or other consumer misbehavior, so not a fatal
3107 // error
3108 ALOGE("RequestThread: Can't get output buffer, skipping request:"
3109 " %s (%d)", strerror(-res), res);
3110
3111 return TIMED_OUT;
3112 }
3113 halRequest->num_output_buffers++;
3114 }
3115 totalNumBuffers += halRequest->num_output_buffers;
3116
3117 // Log request in the in-flight queue
3118 sp<Camera3Device> parent = mParent.promote();
3119 if (parent == NULL) {
3120 // Should not happen, and nowhere to send errors to, so just log it
3121 CLOGE("RequestThread: Parent is gone");
3122 return INVALID_OPERATION;
3123 }
3124 res = parent->registerInFlight(halRequest->frame_number,
3125 totalNumBuffers, captureRequest->mResultExtras,
3126 /*hasInput*/halRequest->input_buffer != NULL,
3127 captureRequest->mAeTriggerCancelOverride);
3128 ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
3129 ", burstId = %" PRId32 ".",
3130 __FUNCTION__,
3131 captureRequest->mResultExtras.requestId, captureRequest->mResultExtras.frameNumber,
3132 captureRequest->mResultExtras.burstId);
3133 if (res != OK) {
3134 SET_ERR("RequestThread: Unable to register new in-flight request:"
3135 " %s (%d)", strerror(-res), res);
3136 return INVALID_OPERATION;
3137 }
3138 }
3139
3140 return OK;
3141}
3142
Igor Murashkin1e479c02013-09-06 16:55:14 -07003143CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
3144 Mutex::Autolock al(mLatestRequestMutex);
3145
3146 ALOGV("RequestThread::%s", __FUNCTION__);
3147
3148 return mLatestRequest;
3149}
3150
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07003151bool Camera3Device::RequestThread::isStreamPending(
3152 sp<Camera3StreamInterface>& stream) {
3153 Mutex::Autolock l(mRequestLock);
3154
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003155 for (const auto& nextRequest : mNextRequests) {
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07003156 if (!nextRequest.submitted) {
3157 for (const auto& s : nextRequest.captureRequest->mOutputStreams) {
3158 if (stream == s) return true;
3159 }
3160 if (stream == nextRequest.captureRequest->mInputStream) return true;
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07003161 }
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07003162 }
3163
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07003164 for (const auto& request : mRequestQueue) {
3165 for (const auto& s : request->mOutputStreams) {
3166 if (stream == s) return true;
3167 }
3168 if (stream == request->mInputStream) return true;
3169 }
3170
3171 for (const auto& request : mRepeatingRequests) {
3172 for (const auto& s : request->mOutputStreams) {
3173 if (stream == s) return true;
3174 }
3175 if (stream == request->mInputStream) return true;
3176 }
3177
3178 return false;
3179}
Jianing Weicb0652e2014-03-12 18:29:36 -07003180
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07003181void Camera3Device::RequestThread::cleanUpFailedRequests(bool sendRequestError) {
3182 if (mNextRequests.empty()) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003183 return;
3184 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003185
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07003186 for (auto& nextRequest : mNextRequests) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003187 // Skip the ones that have been submitted successfully.
3188 if (nextRequest.submitted) {
3189 continue;
3190 }
3191
3192 sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
3193 camera3_capture_request_t* halRequest = &nextRequest.halRequest;
3194 Vector<camera3_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
3195
3196 if (halRequest->settings != NULL) {
3197 captureRequest->mSettings.unlock(halRequest->settings);
3198 }
3199
3200 if (captureRequest->mInputStream != NULL) {
3201 captureRequest->mInputBuffer.status = CAMERA3_BUFFER_STATUS_ERROR;
3202 captureRequest->mInputStream->returnInputBuffer(captureRequest->mInputBuffer);
3203 }
3204
3205 for (size_t i = 0; i < halRequest->num_output_buffers; i++) {
3206 outputBuffers->editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
3207 captureRequest->mOutputStreams.editItemAt(i)->returnBuffer((*outputBuffers)[i], 0);
3208 }
3209
3210 if (sendRequestError) {
3211 Mutex::Autolock l(mRequestLock);
3212 if (mListener != NULL) {
3213 mListener->notifyError(
3214 ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
3215 captureRequest->mResultExtras);
3216 }
3217 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003218 }
Eino-Ville Talvalae74c2282015-05-27 14:46:23 -07003219
3220 Mutex::Autolock l(mRequestLock);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003221 mNextRequests.clear();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003222}
3223
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07003224void Camera3Device::RequestThread::waitForNextRequestBatch() {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003225 // Optimized a bit for the simple steady-state case (single repeating
3226 // request), to avoid putting that request in the queue temporarily.
3227 Mutex::Autolock l(mRequestLock);
3228
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003229 assert(mNextRequests.empty());
3230
3231 NextRequest nextRequest;
3232 nextRequest.captureRequest = waitForNextRequestLocked();
3233 if (nextRequest.captureRequest == nullptr) {
3234 return;
3235 }
3236
3237 nextRequest.halRequest = camera3_capture_request_t();
3238 nextRequest.submitted = false;
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07003239 mNextRequests.add(nextRequest);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003240
3241 // Wait for additional requests
3242 const size_t batchSize = nextRequest.captureRequest->mBatchSize;
3243
3244 for (size_t i = 1; i < batchSize; i++) {
3245 NextRequest additionalRequest;
3246 additionalRequest.captureRequest = waitForNextRequestLocked();
3247 if (additionalRequest.captureRequest == nullptr) {
3248 break;
3249 }
3250
3251 additionalRequest.halRequest = camera3_capture_request_t();
3252 additionalRequest.submitted = false;
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07003253 mNextRequests.add(additionalRequest);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003254 }
3255
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07003256 if (mNextRequests.size() < batchSize) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003257 ALOGE("RequestThread: only get %d out of %d requests. Skipping requests.",
Chien-Yu Chen57ea2922015-09-04 12:58:56 -07003258 mNextRequests.size(), batchSize);
3259 cleanUpFailedRequests(/*sendRequestError*/true);
Chien-Yu Chen85a64552015-08-28 15:46:12 -07003260 }
3261
3262 return;
3263}
3264
3265sp<Camera3Device::CaptureRequest>
3266 Camera3Device::RequestThread::waitForNextRequestLocked() {
3267 status_t res;
3268 sp<CaptureRequest> nextRequest;
3269
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003270 while (mRequestQueue.empty()) {
3271 if (!mRepeatingRequests.empty()) {
3272 // Always atomically enqueue all requests in a repeating request
3273 // list. Guarantees a complete in-sequence set of captures to
3274 // application.
3275 const RequestList &requests = mRepeatingRequests;
3276 RequestList::const_iterator firstRequest =
3277 requests.begin();
3278 nextRequest = *firstRequest;
3279 mRequestQueue.insert(mRequestQueue.end(),
3280 ++firstRequest,
3281 requests.end());
3282 // No need to wait any longer
Jianing Weicb0652e2014-03-12 18:29:36 -07003283
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07003284 mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
Jianing Weicb0652e2014-03-12 18:29:36 -07003285
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003286 break;
3287 }
3288
3289 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
3290
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003291 if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
3292 exitPending()) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003293 Mutex::Autolock pl(mPauseLock);
3294 if (mPaused == false) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003295 ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003296 mPaused = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003297 // Let the tracker know
3298 sp<StatusTracker> statusTracker = mStatusTracker.promote();
3299 if (statusTracker != 0) {
3300 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
3301 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003302 }
3303 // Stop waiting for now and let thread management happen
3304 return NULL;
3305 }
3306 }
3307
3308 if (nextRequest == NULL) {
3309 // Don't have a repeating request already in hand, so queue
3310 // must have an entry now.
3311 RequestList::iterator firstRequest =
3312 mRequestQueue.begin();
3313 nextRequest = *firstRequest;
3314 mRequestQueue.erase(firstRequest);
3315 }
3316
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07003317 // In case we've been unpaused by setPaused clearing mDoPause, need to
3318 // update internal pause state (capture/setRepeatingRequest unpause
3319 // directly).
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003320 Mutex::Autolock pl(mPauseLock);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003321 if (mPaused) {
3322 ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
3323 sp<StatusTracker> statusTracker = mStatusTracker.promote();
3324 if (statusTracker != 0) {
3325 statusTracker->markComponentActive(mStatusId);
3326 }
3327 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003328 mPaused = false;
3329
3330 // Check if we've reconfigured since last time, and reset the preview
3331 // request if so. Can't use 'NULL request == repeat' across configure calls.
3332 if (mReconfigured) {
3333 mPrevRequest.clear();
3334 mReconfigured = false;
3335 }
3336
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07003337 if (nextRequest != NULL) {
3338 nextRequest->mResultExtras.frameNumber = mFrameNumber++;
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07003339 nextRequest->mResultExtras.afTriggerId = mCurrentAfTriggerId;
3340 nextRequest->mResultExtras.precaptureTriggerId = mCurrentPreCaptureTriggerId;
Chien-Yu Chenc2adf482015-05-27 14:27:49 -07003341
3342 // Since RequestThread::clear() removes buffers from the input stream,
3343 // get the right buffer here before unlocking mRequestLock
3344 if (nextRequest->mInputStream != NULL) {
3345 res = nextRequest->mInputStream->getInputBuffer(&nextRequest->mInputBuffer);
3346 if (res != OK) {
3347 // Can't get input buffer from gralloc queue - this could be due to
3348 // disconnected queue or other producer misbehavior, so not a fatal
3349 // error
3350 ALOGE("%s: Can't get input buffer, skipping request:"
3351 " %s (%d)", __FUNCTION__, strerror(-res), res);
3352 if (mListener != NULL) {
3353 mListener->notifyError(
3354 ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
3355 nextRequest->mResultExtras);
3356 }
3357 return NULL;
3358 }
3359 }
Jianing Wei2d6bb3f2014-04-11 10:00:31 -07003360 }
Chien-Yu Chend196d612015-06-22 19:49:01 -07003361
3362 handleAePrecaptureCancelRequest(nextRequest);
3363
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003364 return nextRequest;
3365}
3366
3367bool Camera3Device::RequestThread::waitIfPaused() {
3368 status_t res;
3369 Mutex::Autolock l(mPauseLock);
3370 while (mDoPause) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003371 if (mPaused == false) {
3372 mPaused = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003373 ALOGV("%s: RequestThread: Paused", __FUNCTION__);
3374 // Let the tracker know
3375 sp<StatusTracker> statusTracker = mStatusTracker.promote();
3376 if (statusTracker != 0) {
3377 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
3378 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003379 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003380
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003381 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003382 if (res == TIMED_OUT || exitPending()) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003383 return true;
3384 }
3385 }
3386 // We don't set mPaused to false here, because waitForNextRequest needs
3387 // to further manage the paused state in case of starvation.
3388 return false;
3389}
3390
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07003391void Camera3Device::RequestThread::unpauseForNewRequests() {
3392 // With work to do, mark thread as unpaused.
3393 // If paused by request (setPaused), don't resume, to avoid
3394 // extra signaling/waiting overhead to waitUntilPaused
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003395 mRequestSignal.signal();
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07003396 Mutex::Autolock p(mPauseLock);
3397 if (!mDoPause) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07003398 ALOGV("%s: RequestThread: Going active", __FUNCTION__);
3399 if (mPaused) {
3400 sp<StatusTracker> statusTracker = mStatusTracker.promote();
3401 if (statusTracker != 0) {
3402 statusTracker->markComponentActive(mStatusId);
3403 }
3404 }
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07003405 mPaused = false;
3406 }
3407}
3408
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07003409void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
3410 sp<Camera3Device> parent = mParent.promote();
3411 if (parent != NULL) {
3412 va_list args;
3413 va_start(args, fmt);
3414
3415 parent->setErrorStateV(fmt, args);
3416
3417 va_end(args);
3418 }
3419}
3420
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003421status_t Camera3Device::RequestThread::insertTriggers(
3422 const sp<CaptureRequest> &request) {
3423
3424 Mutex::Autolock al(mTriggerMutex);
3425
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07003426 sp<Camera3Device> parent = mParent.promote();
3427 if (parent == NULL) {
3428 CLOGE("RequestThread: Parent is gone");
3429 return DEAD_OBJECT;
3430 }
3431
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003432 CameraMetadata &metadata = request->mSettings;
3433 size_t count = mTriggerMap.size();
3434
3435 for (size_t i = 0; i < count; ++i) {
3436 RequestTrigger trigger = mTriggerMap.valueAt(i);
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003437 uint32_t tag = trigger.metadataTag;
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07003438
3439 if (tag == ANDROID_CONTROL_AF_TRIGGER_ID || tag == ANDROID_CONTROL_AE_PRECAPTURE_ID) {
3440 bool isAeTrigger = (trigger.metadataTag == ANDROID_CONTROL_AE_PRECAPTURE_ID);
3441 uint32_t triggerId = static_cast<uint32_t>(trigger.entryValue);
Yin-Chia Yehc00a25c2014-08-21 14:27:44 -07003442 if (isAeTrigger) {
3443 request->mResultExtras.precaptureTriggerId = triggerId;
3444 mCurrentPreCaptureTriggerId = triggerId;
3445 } else {
3446 request->mResultExtras.afTriggerId = triggerId;
3447 mCurrentAfTriggerId = triggerId;
3448 }
Yin-Chia Yeh741ace82014-06-23 14:07:56 -07003449 if (parent->mDeviceVersion >= CAMERA_DEVICE_API_VERSION_3_2) {
3450 continue; // Trigger ID tag is deprecated since device HAL 3.2
3451 }
3452 }
3453
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003454 camera_metadata_entry entry = metadata.find(tag);
3455
3456 if (entry.count > 0) {
3457 /**
3458 * Already has an entry for this trigger in the request.
3459 * Rewrite it with our requested trigger value.
3460 */
3461 RequestTrigger oldTrigger = trigger;
3462
3463 oldTrigger.entryValue = entry.data.u8[0];
3464
3465 mTriggerReplacedMap.add(tag, oldTrigger);
3466 } else {
3467 /**
3468 * More typical, no trigger entry, so we just add it
3469 */
3470 mTriggerRemovedMap.add(tag, trigger);
3471 }
3472
3473 status_t res;
3474
3475 switch (trigger.getTagType()) {
3476 case TYPE_BYTE: {
3477 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
3478 res = metadata.update(tag,
3479 &entryValue,
3480 /*count*/1);
3481 break;
3482 }
3483 case TYPE_INT32:
3484 res = metadata.update(tag,
3485 &trigger.entryValue,
3486 /*count*/1);
3487 break;
3488 default:
3489 ALOGE("%s: Type not supported: 0x%x",
3490 __FUNCTION__,
3491 trigger.getTagType());
3492 return INVALID_OPERATION;
3493 }
3494
3495 if (res != OK) {
3496 ALOGE("%s: Failed to update request metadata with trigger tag %s"
3497 ", value %d", __FUNCTION__, trigger.getTagName(),
3498 trigger.entryValue);
3499 return res;
3500 }
3501
3502 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
3503 trigger.getTagName(),
3504 trigger.entryValue);
3505 }
3506
3507 mTriggerMap.clear();
3508
3509 return count;
3510}
3511
3512status_t Camera3Device::RequestThread::removeTriggers(
3513 const sp<CaptureRequest> &request) {
3514 Mutex::Autolock al(mTriggerMutex);
3515
3516 CameraMetadata &metadata = request->mSettings;
3517
3518 /**
3519 * Replace all old entries with their old values.
3520 */
3521 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
3522 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
3523
3524 status_t res;
3525
3526 uint32_t tag = trigger.metadataTag;
3527 switch (trigger.getTagType()) {
3528 case TYPE_BYTE: {
3529 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
3530 res = metadata.update(tag,
3531 &entryValue,
3532 /*count*/1);
3533 break;
3534 }
3535 case TYPE_INT32:
3536 res = metadata.update(tag,
3537 &trigger.entryValue,
3538 /*count*/1);
3539 break;
3540 default:
3541 ALOGE("%s: Type not supported: 0x%x",
3542 __FUNCTION__,
3543 trigger.getTagType());
3544 return INVALID_OPERATION;
3545 }
3546
3547 if (res != OK) {
3548 ALOGE("%s: Failed to restore request metadata with trigger tag %s"
3549 ", trigger value %d", __FUNCTION__,
3550 trigger.getTagName(), trigger.entryValue);
3551 return res;
3552 }
3553 }
3554 mTriggerReplacedMap.clear();
3555
3556 /**
3557 * Remove all new entries.
3558 */
3559 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
3560 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
3561 status_t res = metadata.erase(trigger.metadataTag);
3562
3563 if (res != OK) {
3564 ALOGE("%s: Failed to erase metadata with trigger tag %s"
3565 ", trigger value %d", __FUNCTION__,
3566 trigger.getTagName(), trigger.entryValue);
3567 return res;
3568 }
3569 }
3570 mTriggerRemovedMap.clear();
3571
3572 return OK;
3573}
3574
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07003575status_t Camera3Device::RequestThread::addDummyTriggerIds(
3576 const sp<CaptureRequest> &request) {
3577 // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here
3578 static const int32_t dummyTriggerId = 1;
3579 status_t res;
3580
3581 CameraMetadata &metadata = request->mSettings;
3582
3583 // If AF trigger is active, insert a dummy AF trigger ID if none already
3584 // exists
3585 camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
3586 camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
3587 if (afTrigger.count > 0 &&
3588 afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
3589 afId.count == 0) {
3590 res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
3591 if (res != OK) return res;
3592 }
3593
3594 // If AE precapture trigger is active, insert a dummy precapture trigger ID
3595 // if none already exists
3596 camera_metadata_entry pcTrigger =
3597 metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
3598 camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
3599 if (pcTrigger.count > 0 &&
3600 pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
3601 pcId.count == 0) {
3602 res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
3603 &dummyTriggerId, 1);
3604 if (res != OK) return res;
3605 }
3606
3607 return OK;
3608}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003609
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07003610/**
3611 * PreparerThread inner class methods
3612 */
3613
3614Camera3Device::PreparerThread::PreparerThread() :
3615 Thread(/*canCallJava*/false), mActive(false), mCancelNow(false) {
3616}
3617
3618Camera3Device::PreparerThread::~PreparerThread() {
3619 Thread::requestExitAndWait();
3620 if (mCurrentStream != nullptr) {
3621 mCurrentStream->cancelPrepare();
3622 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
3623 mCurrentStream.clear();
3624 }
3625 clear();
3626}
3627
Ruben Brunkc78ac262015-08-13 17:58:46 -07003628status_t Camera3Device::PreparerThread::prepare(int maxCount, sp<Camera3StreamInterface>& stream) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07003629 status_t res;
3630
3631 Mutex::Autolock l(mLock);
3632
Ruben Brunkc78ac262015-08-13 17:58:46 -07003633 res = stream->startPrepare(maxCount);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07003634 if (res == OK) {
3635 // No preparation needed, fire listener right off
3636 ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId());
3637 if (mListener) {
3638 mListener->notifyPrepared(stream->getId());
3639 }
3640 return OK;
3641 } else if (res != NOT_ENOUGH_DATA) {
3642 return res;
3643 }
3644
3645 // Need to prepare, start up thread if necessary
3646 if (!mActive) {
3647 // mRunning will change to false before the thread fully shuts down, so wait to be sure it
3648 // isn't running
3649 Thread::requestExitAndWait();
3650 res = Thread::run("C3PrepThread", PRIORITY_BACKGROUND);
3651 if (res != OK) {
3652 ALOGE("%s: Unable to start preparer stream: %d (%s)", __FUNCTION__, res, strerror(-res));
3653 if (mListener) {
3654 mListener->notifyPrepared(stream->getId());
3655 }
3656 return res;
3657 }
3658 mCancelNow = false;
3659 mActive = true;
3660 ALOGV("%s: Preparer stream started", __FUNCTION__);
3661 }
3662
3663 // queue up the work
3664 mPendingStreams.push_back(stream);
3665 ALOGV("%s: Stream %d queued for preparing", __FUNCTION__, stream->getId());
3666
3667 return OK;
3668}
3669
3670status_t Camera3Device::PreparerThread::clear() {
3671 status_t res;
3672
3673 Mutex::Autolock l(mLock);
3674
3675 for (const auto& stream : mPendingStreams) {
3676 stream->cancelPrepare();
3677 }
3678 mPendingStreams.clear();
3679 mCancelNow = true;
3680
3681 return OK;
3682}
3683
3684void Camera3Device::PreparerThread::setNotificationListener(NotificationListener *listener) {
3685 Mutex::Autolock l(mLock);
3686 mListener = listener;
3687}
3688
3689bool Camera3Device::PreparerThread::threadLoop() {
3690 status_t res;
3691 {
3692 Mutex::Autolock l(mLock);
3693 if (mCurrentStream == nullptr) {
3694 // End thread if done with work
3695 if (mPendingStreams.empty()) {
3696 ALOGV("%s: Preparer stream out of work", __FUNCTION__);
3697 // threadLoop _must not_ re-acquire mLock after it sets mActive to false; would
3698 // cause deadlock with prepare()'s requestExitAndWait triggered by !mActive.
3699 mActive = false;
3700 return false;
3701 }
3702
3703 // Get next stream to prepare
3704 auto it = mPendingStreams.begin();
3705 mCurrentStream = *it;
3706 mPendingStreams.erase(it);
3707 ATRACE_ASYNC_BEGIN("stream prepare", mCurrentStream->getId());
3708 ALOGV("%s: Preparing stream %d", __FUNCTION__, mCurrentStream->getId());
3709 } else if (mCancelNow) {
3710 mCurrentStream->cancelPrepare();
3711 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
3712 ALOGV("%s: Cancelling stream %d prepare", __FUNCTION__, mCurrentStream->getId());
3713 mCurrentStream.clear();
3714 mCancelNow = false;
3715 return true;
3716 }
3717 }
3718
3719 res = mCurrentStream->prepareNextBuffer();
3720 if (res == NOT_ENOUGH_DATA) return true;
3721 if (res != OK) {
3722 // Something bad happened; try to recover by cancelling prepare and
3723 // signalling listener anyway
3724 ALOGE("%s: Stream %d returned error %d (%s) during prepare", __FUNCTION__,
3725 mCurrentStream->getId(), res, strerror(-res));
3726 mCurrentStream->cancelPrepare();
3727 }
3728
3729 // This stream has finished, notify listener
3730 Mutex::Autolock l(mLock);
3731 if (mListener) {
3732 ALOGV("%s: Stream %d prepare done, signaling listener", __FUNCTION__,
3733 mCurrentStream->getId());
3734 mListener->notifyPrepared(mCurrentStream->getId());
3735 }
3736
3737 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
3738 mCurrentStream.clear();
3739
3740 return true;
3741}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07003742
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08003743/**
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08003744 * Static callback forwarding methods from HAL to instance
3745 */
3746
3747void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
3748 const camera3_capture_result *result) {
3749 Camera3Device *d =
3750 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
Chien-Yu Chend196d612015-06-22 19:49:01 -07003751
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08003752 d->processCaptureResult(result);
3753}
3754
3755void Camera3Device::sNotify(const camera3_callback_ops *cb,
3756 const camera3_notify_msg *msg) {
3757 Camera3Device *d =
3758 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
3759 d->notify(msg);
3760}
3761
3762}; // namespace android