blob: 7e11a3bfcc17e44771ce068d917ac2a0a6bf702d [file] [log] [blame]
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera3-Device"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20//#define LOG_NNDEBUG 0 // Per-frame verbose logging
21
22#ifdef LOG_NNDEBUG
23#define ALOGVV(...) ALOGV(__VA_ARGS__)
24#else
25#define ALOGVV(...) ((void)0)
26#endif
27
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -070028// Convenience macro for transient errors
29#define CLOGE(fmt, ...) ALOGE("Camera %d: %s: " fmt, mId, __FUNCTION__, \
30 ##__VA_ARGS__)
31
32// Convenience macros for transitioning to the error state
33#define SET_ERR(fmt, ...) setErrorState( \
34 "%s: " fmt, __FUNCTION__, \
35 ##__VA_ARGS__)
36#define SET_ERR_L(fmt, ...) setErrorStateLocked( \
37 "%s: " fmt, __FUNCTION__, \
38 ##__VA_ARGS__)
39
Colin Crosse5729fa2014-03-21 15:04:25 -070040#include <inttypes.h>
41
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080042#include <utils/Log.h>
43#include <utils/Trace.h>
44#include <utils/Timers.h>
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070045
Igor Murashkinff3e31d2013-10-23 16:40:06 -070046#include "utils/CameraTraces.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070047#include "device3/Camera3Device.h"
48#include "device3/Camera3OutputStream.h"
49#include "device3/Camera3InputStream.h"
50#include "device3/Camera3ZslStream.h"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080051
52using namespace android::camera3;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080053
54namespace android {
55
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080056Camera3Device::Camera3Device(int id):
57 mId(id),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080058 mHal3Device(NULL),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070059 mStatus(STATUS_UNINITIALIZED),
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -070060 mUsePartialResultQuirk(false),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -070061 mNextResultFrameNumber(0),
62 mNextShutterFrameNumber(0),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070063 mListener(NULL)
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080064{
65 ATRACE_CALL();
66 camera3_callback_ops::notify = &sNotify;
67 camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
68 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
69}
70
71Camera3Device::~Camera3Device()
72{
73 ATRACE_CALL();
74 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
75 disconnect();
76}
77
Igor Murashkin71381052013-03-04 14:53:08 -080078int Camera3Device::getId() const {
79 return mId;
80}
81
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080082/**
83 * CameraDeviceBase interface
84 */
85
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080086status_t Camera3Device::initialize(camera_module_t *module)
87{
88 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -070089 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080090 Mutex::Autolock l(mLock);
91
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080092 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080093 if (mStatus != STATUS_UNINITIALIZED) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -070094 CLOGE("Already initialized!");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080095 return INVALID_OPERATION;
96 }
97
98 /** Open HAL device */
99
100 status_t res;
101 String8 deviceName = String8::format("%d", mId);
102
103 camera3_device_t *device;
104
105 res = module->common.methods->open(&module->common, deviceName.string(),
106 reinterpret_cast<hw_device_t**>(&device));
107
108 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700109 SET_ERR_L("Could not open camera: %s (%d)", strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800110 return res;
111 }
112
113 /** Cross-check device version */
114
115 if (device->common.version != CAMERA_DEVICE_API_VERSION_3_0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700116 SET_ERR_L("Could not open camera: "
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800117 "Camera device is not version %x, reports %x instead",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700118 CAMERA_DEVICE_API_VERSION_3_0,
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800119 device->common.version);
120 device->common.close(&device->common);
121 return BAD_VALUE;
122 }
123
124 camera_info info;
125 res = module->get_camera_info(mId, &info);
126 if (res != OK) return res;
127
128 if (info.device_version != device->common.version) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700129 SET_ERR_L("HAL reporting mismatched camera_info version (%x)"
130 " and device version (%x).",
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800131 device->common.version, info.device_version);
132 device->common.close(&device->common);
133 return BAD_VALUE;
134 }
135
136 /** Initialize device with callback functions */
137
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700138 ATRACE_BEGIN("camera3->initialize");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800139 res = device->ops->initialize(device, this);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700140 ATRACE_END();
141
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800142 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700143 SET_ERR_L("Unable to initialize HAL device: %s (%d)",
144 strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800145 device->common.close(&device->common);
146 return BAD_VALUE;
147 }
148
149 /** Get vendor metadata tags */
150
151 mVendorTagOps.get_camera_vendor_section_name = NULL;
152
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700153 ATRACE_BEGIN("camera3->get_metadata_vendor_tag_ops");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800154 device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700155 ATRACE_END();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800156
157 if (mVendorTagOps.get_camera_vendor_section_name != NULL) {
158 res = set_camera_metadata_vendor_tag_ops(&mVendorTagOps);
159 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700160 SET_ERR_L("Unable to set tag ops: %s (%d)",
161 strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800162 device->common.close(&device->common);
163 return res;
164 }
165 }
166
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700167 /** Start up status tracker thread */
168 mStatusTracker = new StatusTracker(this);
169 res = mStatusTracker->run(String8::format("C3Dev-%d-Status", mId).string());
170 if (res != OK) {
171 SET_ERR_L("Unable to start status tracking thread: %s (%d)",
172 strerror(-res), res);
173 device->common.close(&device->common);
174 mStatusTracker.clear();
175 return res;
176 }
177
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800178 /** Start up request queue thread */
179
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700180 mRequestThread = new RequestThread(this, mStatusTracker, device);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800181 res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800182 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700183 SET_ERR_L("Unable to start request queue thread: %s (%d)",
184 strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800185 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800186 mRequestThread.clear();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800187 return res;
188 }
189
190 /** Everything is good to go */
191
192 mDeviceInfo = info.static_camera_characteristics;
193 mHal3Device = device;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700194 mStatus = STATUS_UNCONFIGURED;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800195 mNextStreamId = 0;
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -0700196 mNeedConfig = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700197 mPauseStateNotify = false;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800198
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -0700199 /** Check for quirks */
200
201 // Will the HAL be sending in early partial result metadata?
202 camera_metadata_entry partialResultsQuirk =
203 mDeviceInfo.find(ANDROID_QUIRKS_USE_PARTIAL_RESULT);
204 if (partialResultsQuirk.count > 0 && partialResultsQuirk.data.u8[0] == 1) {
205 mUsePartialResultQuirk = true;
206 }
207
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800208 return OK;
209}
210
211status_t Camera3Device::disconnect() {
212 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700213 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800214
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800215 ALOGV("%s: E", __FUNCTION__);
216
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700217 status_t res = OK;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800218
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700219 {
220 Mutex::Autolock l(mLock);
221 if (mStatus == STATUS_UNINITIALIZED) return res;
222
223 if (mStatus == STATUS_ACTIVE ||
224 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
225 res = mRequestThread->clearRepeatingRequests();
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700226 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700227 SET_ERR_L("Can't stop streaming");
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700228 // Continue to close device even in case of error
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700229 } else {
230 res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
231 if (res != OK) {
232 SET_ERR_L("Timeout waiting for HAL to drain");
233 // Continue to close device even in case of error
234 }
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700235 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800236 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800237
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700238 if (mStatus == STATUS_ERROR) {
239 CLOGE("Shutting down in an error state");
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700240 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700241
242 if (mStatusTracker != NULL) {
243 mStatusTracker->requestExit();
244 }
245
246 if (mRequestThread != NULL) {
247 mRequestThread->requestExit();
248 }
249
250 mOutputStreams.clear();
251 mInputStream.clear();
252 }
253
254 // Joining done without holding mLock, otherwise deadlocks may ensue
255 // as the threads try to access parent state
256 if (mRequestThread != NULL && mStatus != STATUS_ERROR) {
257 // HAL may be in a bad state, so waiting for request thread
258 // (which may be stuck in the HAL processCaptureRequest call)
259 // could be dangerous.
260 mRequestThread->join();
261 }
262
263 if (mStatusTracker != NULL) {
264 mStatusTracker->join();
265 }
266
267 {
268 Mutex::Autolock l(mLock);
269
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800270 mRequestThread.clear();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700271 mStatusTracker.clear();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800272
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700273 if (mHal3Device != NULL) {
274 mHal3Device->common.close(&mHal3Device->common);
275 mHal3Device = NULL;
276 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800277
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700278 mStatus = STATUS_UNINITIALIZED;
279 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800280
281 ALOGV("%s: X", __FUNCTION__);
Eino-Ville Talvala214a17f2013-06-13 12:20:02 -0700282 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800283}
284
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700285// For dumping/debugging only -
286// try to acquire a lock a few times, eventually give up to proceed with
287// debug/dump operations
288bool Camera3Device::tryLockSpinRightRound(Mutex& lock) {
289 bool gotLock = false;
290 for (size_t i = 0; i < kDumpLockAttempts; ++i) {
291 if (lock.tryLock() == NO_ERROR) {
292 gotLock = true;
293 break;
294 } else {
295 usleep(kDumpSleepDuration);
296 }
297 }
298 return gotLock;
299}
300
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800301status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
302 ATRACE_CALL();
303 (void)args;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700304
305 // Try to lock, but continue in case of failure (to avoid blocking in
306 // deadlocks)
307 bool gotInterfaceLock = tryLockSpinRightRound(mInterfaceLock);
308 bool gotLock = tryLockSpinRightRound(mLock);
309
310 ALOGW_IF(!gotInterfaceLock,
311 "Camera %d: %s: Unable to lock interface lock, proceeding anyway",
312 mId, __FUNCTION__);
313 ALOGW_IF(!gotLock,
314 "Camera %d: %s: Unable to lock main lock, proceeding anyway",
315 mId, __FUNCTION__);
316
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800317 String8 lines;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800318
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800319 const char *status =
320 mStatus == STATUS_ERROR ? "ERROR" :
321 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700322 mStatus == STATUS_UNCONFIGURED ? "UNCONFIGURED" :
323 mStatus == STATUS_CONFIGURED ? "CONFIGURED" :
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800324 mStatus == STATUS_ACTIVE ? "ACTIVE" :
325 "Unknown";
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700326
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800327 lines.appendFormat(" Device status: %s\n", status);
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700328 if (mStatus == STATUS_ERROR) {
329 lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
330 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800331 lines.appendFormat(" Stream configuration:\n");
332
333 if (mInputStream != NULL) {
334 write(fd, lines.string(), lines.size());
335 mInputStream->dump(fd, args);
336 } else {
337 lines.appendFormat(" No input stream.\n");
338 write(fd, lines.string(), lines.size());
339 }
340 for (size_t i = 0; i < mOutputStreams.size(); i++) {
341 mOutputStreams[i]->dump(fd,args);
342 }
343
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700344 lines = String8(" In-flight requests:\n");
345 if (mInFlightMap.size() == 0) {
346 lines.append(" None\n");
347 } else {
348 for (size_t i = 0; i < mInFlightMap.size(); i++) {
349 InFlightRequest r = mInFlightMap.valueAt(i);
Colin Crosse5729fa2014-03-21 15:04:25 -0700350 lines.appendFormat(" Frame %d | Timestamp: %" PRId64 ", metadata"
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700351 " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
352 r.captureTimestamp, r.haveResultMetadata ? "true" : "false",
353 r.numBuffersLeft);
354 }
355 }
356 write(fd, lines.string(), lines.size());
357
Igor Murashkin1e479c02013-09-06 16:55:14 -0700358 {
359 lines = String8(" Last request sent:\n");
360 write(fd, lines.string(), lines.size());
361
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700362 CameraMetadata lastRequest = getLatestRequestLocked();
Igor Murashkin1e479c02013-09-06 16:55:14 -0700363 lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
364 }
365
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800366 if (mHal3Device != NULL) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700367 lines = String8(" HAL device dump:\n");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800368 write(fd, lines.string(), lines.size());
369 mHal3Device->ops->dump(mHal3Device, fd);
370 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800371
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700372 if (gotLock) mLock.unlock();
373 if (gotInterfaceLock) mInterfaceLock.unlock();
374
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800375 return OK;
376}
377
378const CameraMetadata& Camera3Device::info() const {
379 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800380 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
381 mStatus == STATUS_ERROR)) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700382 ALOGW("%s: Access to static info %s!", __FUNCTION__,
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800383 mStatus == STATUS_ERROR ?
384 "when in error state" : "before init");
385 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800386 return mDeviceInfo;
387}
388
389status_t Camera3Device::capture(CameraMetadata &request) {
390 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700391 status_t res;
392 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800393 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800394
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700395 // TODO: take ownership of the request
396
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800397 switch (mStatus) {
398 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700399 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800400 return INVALID_OPERATION;
401 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700402 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800403 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700404 case STATUS_UNCONFIGURED:
405 // May be lazily configuring streams, will check during setup
406 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800407 case STATUS_ACTIVE:
408 // OK
409 break;
410 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700411 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800412 return INVALID_OPERATION;
413 }
414
415 sp<CaptureRequest> newRequest = setUpRequestLocked(request);
416 if (newRequest == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700417 CLOGE("Can't create capture request");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800418 return BAD_VALUE;
419 }
420
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700421 res = mRequestThread->queueRequest(newRequest);
422 if (res == OK) {
423 waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
424 if (res != OK) {
425 SET_ERR_L("Can't transition to active in %f seconds!",
426 kActiveTimeout/1e9);
427 }
428 ALOGV("Camera %d: Capture request enqueued", mId);
429 }
430 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800431}
432
433
434status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) {
435 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700436 status_t res;
437 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800438 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800439
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800440 switch (mStatus) {
441 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700442 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800443 return INVALID_OPERATION;
444 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700445 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800446 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700447 case STATUS_UNCONFIGURED:
448 // May be lazily configuring streams, will check during setup
449 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800450 case STATUS_ACTIVE:
451 // OK
452 break;
453 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700454 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800455 return INVALID_OPERATION;
456 }
457
458 sp<CaptureRequest> newRepeatingRequest = setUpRequestLocked(request);
459 if (newRepeatingRequest == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700460 CLOGE("Can't create repeating request");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800461 return BAD_VALUE;
462 }
463
464 RequestList newRepeatingRequests;
465 newRepeatingRequests.push_back(newRepeatingRequest);
466
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700467 res = mRequestThread->setRepeatingRequests(newRepeatingRequests);
468 if (res == OK) {
469 waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
470 if (res != OK) {
471 SET_ERR_L("Can't transition to active in %f seconds!",
472 kActiveTimeout/1e9);
473 }
474 ALOGV("Camera %d: Repeating request set", mId);
475 }
476 return res;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800477}
478
479
480sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
481 const CameraMetadata &request) {
482 status_t res;
483
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700484 if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800485 res = configureStreamsLocked();
486 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700487 SET_ERR_L("Can't set up streams: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800488 return NULL;
489 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700490 if (mStatus == STATUS_UNCONFIGURED) {
491 CLOGE("No streams configured");
492 return NULL;
493 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800494 }
495
496 sp<CaptureRequest> newRequest = createCaptureRequest(request);
497 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800498}
499
500status_t Camera3Device::clearStreamingRequest() {
501 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700502 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800503 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800504
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800505 switch (mStatus) {
506 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700507 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800508 return INVALID_OPERATION;
509 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700510 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800511 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700512 case STATUS_UNCONFIGURED:
513 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800514 case STATUS_ACTIVE:
515 // OK
516 break;
517 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700518 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800519 return INVALID_OPERATION;
520 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700521 ALOGV("Camera %d: Clearing repeating request", mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800522 return mRequestThread->clearRepeatingRequests();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800523}
524
525status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
526 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700527 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800528
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700529 return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800530}
531
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700532status_t Camera3Device::createInputStream(
533 uint32_t width, uint32_t height, int format, int *id) {
534 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700535 Mutex::Autolock il(mInterfaceLock);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700536 Mutex::Autolock l(mLock);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700537 ALOGV("Camera %d: Creating new input stream %d: %d x %d, format %d",
538 mId, mNextStreamId, width, height, format);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700539
540 status_t res;
541 bool wasActive = false;
542
543 switch (mStatus) {
544 case STATUS_ERROR:
545 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
546 return INVALID_OPERATION;
547 case STATUS_UNINITIALIZED:
548 ALOGE("%s: Device not initialized", __FUNCTION__);
549 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700550 case STATUS_UNCONFIGURED:
551 case STATUS_CONFIGURED:
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700552 // OK
553 break;
554 case STATUS_ACTIVE:
555 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700556 res = internalPauseAndWaitLocked();
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700557 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700558 SET_ERR_L("Can't pause captures to reconfigure streams!");
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700559 return res;
560 }
561 wasActive = true;
562 break;
563 default:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700564 SET_ERR_L("%s: Unexpected status: %d", mStatus);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700565 return INVALID_OPERATION;
566 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700567 assert(mStatus != STATUS_ACTIVE);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700568
569 if (mInputStream != 0) {
570 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
571 return INVALID_OPERATION;
572 }
573
574 sp<Camera3InputStream> newStream = new Camera3InputStream(mNextStreamId,
575 width, height, format);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700576 newStream->setStatusTracker(mStatusTracker);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700577
578 mInputStream = newStream;
579
580 *id = mNextStreamId++;
581
582 // Continue captures if active at start
583 if (wasActive) {
584 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
585 res = configureStreamsLocked();
586 if (res != OK) {
587 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
588 __FUNCTION__, mNextStreamId, strerror(-res), res);
589 return res;
590 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700591 internalResumeLocked();
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700592 }
593
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700594 ALOGV("Camera %d: Created input stream", mId);
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700595 return OK;
596}
597
Igor Murashkin2fba5842013-04-22 14:03:54 -0700598
599status_t Camera3Device::createZslStream(
600 uint32_t width, uint32_t height,
601 int depth,
602 /*out*/
603 int *id,
604 sp<Camera3ZslStream>* zslStream) {
605 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700606 Mutex::Autolock il(mInterfaceLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700607 Mutex::Autolock l(mLock);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700608 ALOGV("Camera %d: Creating ZSL stream %d: %d x %d, depth %d",
609 mId, mNextStreamId, width, height, depth);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700610
611 status_t res;
612 bool wasActive = false;
613
614 switch (mStatus) {
615 case STATUS_ERROR:
616 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
617 return INVALID_OPERATION;
618 case STATUS_UNINITIALIZED:
619 ALOGE("%s: Device not initialized", __FUNCTION__);
620 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700621 case STATUS_UNCONFIGURED:
622 case STATUS_CONFIGURED:
Igor Murashkin2fba5842013-04-22 14:03:54 -0700623 // OK
624 break;
625 case STATUS_ACTIVE:
626 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700627 res = internalPauseAndWaitLocked();
Igor Murashkin2fba5842013-04-22 14:03:54 -0700628 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700629 SET_ERR_L("Can't pause captures to reconfigure streams!");
Igor Murashkin2fba5842013-04-22 14:03:54 -0700630 return res;
631 }
632 wasActive = true;
633 break;
634 default:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700635 SET_ERR_L("Unexpected status: %d", mStatus);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700636 return INVALID_OPERATION;
637 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700638 assert(mStatus != STATUS_ACTIVE);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700639
640 if (mInputStream != 0) {
641 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
642 return INVALID_OPERATION;
643 }
644
645 sp<Camera3ZslStream> newStream = new Camera3ZslStream(mNextStreamId,
646 width, height, depth);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700647 newStream->setStatusTracker(mStatusTracker);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700648
649 res = mOutputStreams.add(mNextStreamId, newStream);
650 if (res < 0) {
651 ALOGE("%s: Can't add new stream to set: %s (%d)",
652 __FUNCTION__, strerror(-res), res);
653 return res;
654 }
655 mInputStream = newStream;
656
657 *id = mNextStreamId++;
658 *zslStream = newStream;
659
660 // Continue captures if active at start
661 if (wasActive) {
662 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
663 res = configureStreamsLocked();
664 if (res != OK) {
665 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
666 __FUNCTION__, mNextStreamId, strerror(-res), res);
667 return res;
668 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700669 internalResumeLocked();
Igor Murashkin2fba5842013-04-22 14:03:54 -0700670 }
671
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700672 ALOGV("Camera %d: Created ZSL stream", mId);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700673 return OK;
674}
675
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800676status_t Camera3Device::createStream(sp<ANativeWindow> consumer,
677 uint32_t width, uint32_t height, int format, size_t size, int *id) {
678 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700679 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800680 Mutex::Autolock l(mLock);
Colin Crosse5729fa2014-03-21 15:04:25 -0700681 ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, size %zu",
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700682 mId, mNextStreamId, width, height, format, size);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800683
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800684 status_t res;
685 bool wasActive = false;
686
687 switch (mStatus) {
688 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700689 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800690 return INVALID_OPERATION;
691 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700692 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800693 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700694 case STATUS_UNCONFIGURED:
695 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800696 // OK
697 break;
698 case STATUS_ACTIVE:
699 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700700 res = internalPauseAndWaitLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800701 if (res != OK) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700702 SET_ERR_L("Can't pause captures to reconfigure streams!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800703 return res;
704 }
705 wasActive = true;
706 break;
707 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700708 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800709 return INVALID_OPERATION;
710 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700711 assert(mStatus != STATUS_ACTIVE);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800712
713 sp<Camera3OutputStream> newStream;
714 if (format == HAL_PIXEL_FORMAT_BLOB) {
715 newStream = new Camera3OutputStream(mNextStreamId, consumer,
716 width, height, size, format);
717 } else {
718 newStream = new Camera3OutputStream(mNextStreamId, consumer,
719 width, height, format);
720 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700721 newStream->setStatusTracker(mStatusTracker);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800722
723 res = mOutputStreams.add(mNextStreamId, newStream);
724 if (res < 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700725 SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800726 return res;
727 }
728
729 *id = mNextStreamId++;
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -0700730 mNeedConfig = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800731
732 // Continue captures if active at start
733 if (wasActive) {
734 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
735 res = configureStreamsLocked();
736 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700737 CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
738 mNextStreamId, strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800739 return res;
740 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700741 internalResumeLocked();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800742 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700743 ALOGV("Camera %d: Created new stream", mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800744 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800745}
746
747status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
748 ATRACE_CALL();
749 (void)outputId; (void)id;
750
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700751 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800752 return INVALID_OPERATION;
753}
754
755
756status_t Camera3Device::getStreamInfo(int id,
757 uint32_t *width, uint32_t *height, uint32_t *format) {
758 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700759 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800760 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800761
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800762 switch (mStatus) {
763 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700764 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800765 return INVALID_OPERATION;
766 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700767 CLOGE("Device not initialized!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800768 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700769 case STATUS_UNCONFIGURED:
770 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800771 case STATUS_ACTIVE:
772 // OK
773 break;
774 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700775 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800776 return INVALID_OPERATION;
777 }
778
779 ssize_t idx = mOutputStreams.indexOfKey(id);
780 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700781 CLOGE("Stream %d is unknown", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800782 return idx;
783 }
784
785 if (width) *width = mOutputStreams[idx]->getWidth();
786 if (height) *height = mOutputStreams[idx]->getHeight();
787 if (format) *format = mOutputStreams[idx]->getFormat();
788
789 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800790}
791
792status_t Camera3Device::setStreamTransform(int id,
793 int transform) {
794 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700795 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800796 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800797
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800798 switch (mStatus) {
799 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700800 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800801 return INVALID_OPERATION;
802 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700803 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800804 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700805 case STATUS_UNCONFIGURED:
806 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800807 case STATUS_ACTIVE:
808 // OK
809 break;
810 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700811 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800812 return INVALID_OPERATION;
813 }
814
815 ssize_t idx = mOutputStreams.indexOfKey(id);
816 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700817 CLOGE("Stream %d does not exist",
818 id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800819 return BAD_VALUE;
820 }
821
822 return mOutputStreams.editValueAt(idx)->setTransform(transform);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800823}
824
825status_t Camera3Device::deleteStream(int id) {
826 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700827 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800828 Mutex::Autolock l(mLock);
829 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800830
Igor Murashkine2172be2013-05-28 15:31:39 -0700831 ALOGV("%s: Camera %d: Deleting stream %d", __FUNCTION__, mId, id);
832
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800833 // CameraDevice semantics require device to already be idle before
834 // deleteStream is called, unlike for createStream.
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700835 if (mStatus == STATUS_ACTIVE) {
Igor Murashkin52827132013-05-13 14:53:44 -0700836 ALOGV("%s: Camera %d: Device not idle", __FUNCTION__, mId);
837 return -EBUSY;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800838 }
839
Igor Murashkin2fba5842013-04-22 14:03:54 -0700840 sp<Camera3StreamInterface> deletedStream;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800841 if (mInputStream != NULL && id == mInputStream->getId()) {
842 deletedStream = mInputStream;
843 mInputStream.clear();
844 } else {
845 ssize_t idx = mOutputStreams.indexOfKey(id);
846 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700847 CLOGE("Stream %d does not exist", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800848 return BAD_VALUE;
849 }
850 deletedStream = mOutputStreams.editValueAt(idx);
851 mOutputStreams.removeItem(id);
852 }
853
854 // Free up the stream endpoint so that it can be used by some other stream
855 res = deletedStream->disconnect();
856 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700857 SET_ERR_L("Can't disconnect deleted stream %d", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800858 // fall through since we want to still list the stream as deleted.
859 }
860 mDeletedStreams.add(deletedStream);
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -0700861 mNeedConfig = true;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800862
863 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800864}
865
866status_t Camera3Device::deleteReprocessStream(int id) {
867 ATRACE_CALL();
868 (void)id;
869
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700870 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800871 return INVALID_OPERATION;
872}
873
874
875status_t Camera3Device::createDefaultRequest(int templateId,
876 CameraMetadata *request) {
877 ATRACE_CALL();
Alex Rayfe7e0c62013-05-30 00:12:13 -0700878 ALOGV("%s: for template %d", __FUNCTION__, templateId);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700879 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800880 Mutex::Autolock l(mLock);
881
882 switch (mStatus) {
883 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700884 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800885 return INVALID_OPERATION;
886 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700887 CLOGE("Device is not initialized!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800888 return INVALID_OPERATION;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700889 case STATUS_UNCONFIGURED:
890 case STATUS_CONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800891 case STATUS_ACTIVE:
892 // OK
893 break;
894 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700895 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800896 return INVALID_OPERATION;
897 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800898
899 const camera_metadata_t *rawRequest;
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700900 ATRACE_BEGIN("camera3->construct_default_request_settings");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800901 rawRequest = mHal3Device->ops->construct_default_request_settings(
902 mHal3Device, templateId);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -0700903 ATRACE_END();
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700904 if (rawRequest == NULL) {
905 SET_ERR_L("HAL is unable to construct default settings for template %d",
906 templateId);
907 return DEAD_OBJECT;
908 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800909 *request = rawRequest;
910
911 return OK;
912}
913
914status_t Camera3Device::waitUntilDrained() {
915 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700916 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800917 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800918
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800919 switch (mStatus) {
920 case STATUS_UNINITIALIZED:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700921 case STATUS_UNCONFIGURED:
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800922 ALOGV("%s: Already idle", __FUNCTION__);
923 return OK;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700924 case STATUS_CONFIGURED:
925 // To avoid race conditions, check with tracker to be sure
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800926 case STATUS_ERROR:
927 case STATUS_ACTIVE:
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700928 // Need to verify shut down
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800929 break;
930 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700931 SET_ERR_L("Unexpected status: %d",mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800932 return INVALID_OPERATION;
933 }
934
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700935 ALOGV("%s: Camera %d: Waiting until idle", __FUNCTION__, mId);
936 status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
937 return res;
938}
939
940// Pause to reconfigure
941status_t Camera3Device::internalPauseAndWaitLocked() {
942 mRequestThread->setPaused(true);
943 mPauseStateNotify = true;
944
945 ALOGV("%s: Camera %d: Internal wait until idle", __FUNCTION__, mId);
946 status_t res = waitUntilStateThenRelock(/*active*/ false, kShutdownTimeout);
947 if (res != OK) {
948 SET_ERR_L("Can't idle device in %f seconds!",
949 kShutdownTimeout/1e9);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800950 }
951
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700952 return res;
953}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800954
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700955// Resume after internalPauseAndWaitLocked
956status_t Camera3Device::internalResumeLocked() {
957 status_t res;
958
959 mRequestThread->setPaused(false);
960
961 res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
962 if (res != OK) {
963 SET_ERR_L("Can't transition to active in %f seconds!",
964 kActiveTimeout/1e9);
965 }
966 mPauseStateNotify = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800967 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800968}
969
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700970status_t Camera3Device::waitUntilStateThenRelock(bool active,
971 nsecs_t timeout) {
972 status_t res = OK;
973 if (active == (mStatus == STATUS_ACTIVE)) {
974 // Desired state already reached
975 return res;
976 }
977
978 bool stateSeen = false;
979 do {
980 mRecentStatusUpdates.clear();
981
982 res = mStatusChanged.waitRelative(mLock, timeout);
983 if (res != OK) break;
984
985 // Check state change history during wait
986 for (size_t i = 0; i < mRecentStatusUpdates.size(); i++) {
987 if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
988 stateSeen = true;
989 break;
990 }
991 }
992 } while (!stateSeen);
993
994 return res;
995}
996
997
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800998status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
999 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001000 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001001
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001002 if (listener != NULL && mListener != NULL) {
1003 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
1004 }
1005 mListener = listener;
1006
1007 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001008}
1009
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -07001010bool Camera3Device::willNotify3A() {
1011 return false;
1012}
1013
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001014status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001015 status_t res;
1016 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001017
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001018 while (mResultQueue.empty()) {
1019 res = mResultSignal.waitRelative(mOutputLock, timeout);
1020 if (res == TIMED_OUT) {
1021 return res;
1022 } else if (res != OK) {
Colin Crosse5729fa2014-03-21 15:04:25 -07001023 ALOGW("%s: Camera %d: No frame in %" PRId64 " ns: %s (%d)",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001024 __FUNCTION__, mId, timeout, strerror(-res), res);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001025 return res;
1026 }
1027 }
1028 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001029}
1030
1031status_t Camera3Device::getNextFrame(CameraMetadata *frame) {
1032 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001033 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001034
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001035 if (mResultQueue.empty()) {
1036 return NOT_ENOUGH_DATA;
1037 }
1038
1039 CameraMetadata &result = *(mResultQueue.begin());
1040 frame->acquire(result);
1041 mResultQueue.erase(mResultQueue.begin());
1042
1043 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001044}
1045
1046status_t Camera3Device::triggerAutofocus(uint32_t id) {
1047 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001048 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001049
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001050 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
1051 // Mix-in this trigger into the next request and only the next request.
1052 RequestTrigger trigger[] = {
1053 {
1054 ANDROID_CONTROL_AF_TRIGGER,
1055 ANDROID_CONTROL_AF_TRIGGER_START
1056 },
1057 {
1058 ANDROID_CONTROL_AF_TRIGGER_ID,
1059 static_cast<int32_t>(id)
1060 },
1061 };
1062
1063 return mRequestThread->queueTrigger(trigger,
1064 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001065}
1066
1067status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
1068 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001069 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001070
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001071 ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
1072 // Mix-in this trigger into the next request and only the next request.
1073 RequestTrigger trigger[] = {
1074 {
1075 ANDROID_CONTROL_AF_TRIGGER,
1076 ANDROID_CONTROL_AF_TRIGGER_CANCEL
1077 },
1078 {
1079 ANDROID_CONTROL_AF_TRIGGER_ID,
1080 static_cast<int32_t>(id)
1081 },
1082 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001083
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001084 return mRequestThread->queueTrigger(trigger,
1085 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001086}
1087
1088status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
1089 ATRACE_CALL();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001090 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001091
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001092 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
1093 // Mix-in this trigger into the next request and only the next request.
1094 RequestTrigger trigger[] = {
1095 {
1096 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
1097 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
1098 },
1099 {
1100 ANDROID_CONTROL_AE_PRECAPTURE_ID,
1101 static_cast<int32_t>(id)
1102 },
1103 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001104
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001105 return mRequestThread->queueTrigger(trigger,
1106 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001107}
1108
1109status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
1110 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
1111 ATRACE_CALL();
1112 (void)reprocessStreamId; (void)buffer; (void)listener;
1113
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001114 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001115 return INVALID_OPERATION;
1116}
1117
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001118status_t Camera3Device::flush() {
1119 ATRACE_CALL();
1120 ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001121 Mutex::Autolock il(mInterfaceLock);
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001122 Mutex::Autolock l(mLock);
1123
1124 mRequestThread->clear();
1125 return mHal3Device->ops->flush(mHal3Device);
1126}
1127
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001128/**
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001129 * Methods called by subclasses
1130 */
1131
1132void Camera3Device::notifyStatus(bool idle) {
1133 {
1134 // Need mLock to safely update state and synchronize to current
1135 // state of methods in flight.
1136 Mutex::Autolock l(mLock);
1137 // We can get various system-idle notices from the status tracker
1138 // while starting up. Only care about them if we've actually sent
1139 // in some requests recently.
1140 if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
1141 return;
1142 }
1143 ALOGV("%s: Camera %d: Now %s", __FUNCTION__, mId,
1144 idle ? "idle" : "active");
1145 mStatus = idle ? STATUS_CONFIGURED : STATUS_ACTIVE;
1146 mRecentStatusUpdates.add(mStatus);
1147 mStatusChanged.signal();
1148
1149 // Skip notifying listener if we're doing some user-transparent
1150 // state changes
1151 if (mPauseStateNotify) return;
1152 }
1153 NotificationListener *listener;
1154 {
1155 Mutex::Autolock l(mOutputLock);
1156 listener = mListener;
1157 }
1158 if (idle && listener != NULL) {
1159 listener->notifyIdle();
1160 }
1161}
1162
1163/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001164 * Camera3Device private methods
1165 */
1166
1167sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
1168 const CameraMetadata &request) {
1169 ATRACE_CALL();
1170 status_t res;
1171
1172 sp<CaptureRequest> newRequest = new CaptureRequest;
1173 newRequest->mSettings = request;
1174
1175 camera_metadata_entry_t inputStreams =
1176 newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
1177 if (inputStreams.count > 0) {
1178 if (mInputStream == NULL ||
Zhijun Hed1d64672013-09-06 15:00:01 -07001179 mInputStream->getId() != inputStreams.data.i32[0]) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001180 CLOGE("Request references unknown input stream %d",
1181 inputStreams.data.u8[0]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001182 return NULL;
1183 }
1184 // Lazy completion of stream configuration (allocation/registration)
1185 // on first use
1186 if (mInputStream->isConfiguring()) {
1187 res = mInputStream->finishConfiguration(mHal3Device);
1188 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001189 SET_ERR_L("Unable to finish configuring input stream %d:"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001190 " %s (%d)",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001191 mInputStream->getId(), strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001192 return NULL;
1193 }
1194 }
1195
1196 newRequest->mInputStream = mInputStream;
1197 newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
1198 }
1199
1200 camera_metadata_entry_t streams =
1201 newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
1202 if (streams.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001203 CLOGE("Zero output streams specified!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001204 return NULL;
1205 }
1206
1207 for (size_t i = 0; i < streams.count; i++) {
Zhijun Hed1d64672013-09-06 15:00:01 -07001208 int idx = mOutputStreams.indexOfKey(streams.data.i32[i]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001209 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001210 CLOGE("Request references unknown stream %d",
1211 streams.data.u8[i]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001212 return NULL;
1213 }
Igor Murashkin2fba5842013-04-22 14:03:54 -07001214 sp<Camera3OutputStreamInterface> stream =
1215 mOutputStreams.editValueAt(idx);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001216
1217 // Lazy completion of stream configuration (allocation/registration)
1218 // on first use
1219 if (stream->isConfiguring()) {
1220 res = stream->finishConfiguration(mHal3Device);
1221 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001222 SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
1223 stream->getId(), strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001224 return NULL;
1225 }
1226 }
1227
1228 newRequest->mOutputStreams.push(stream);
1229 }
1230 newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
1231
1232 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001233}
1234
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001235status_t Camera3Device::configureStreamsLocked() {
1236 ATRACE_CALL();
1237 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001238
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001239 if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001240 CLOGE("Not idle");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001241 return INVALID_OPERATION;
1242 }
1243
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001244 if (!mNeedConfig) {
1245 ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
1246 return OK;
1247 }
1248
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001249 // Start configuring the streams
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001250 ALOGV("%s: Camera %d: Starting stream configuration", __FUNCTION__, mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001251
1252 camera3_stream_configuration config;
1253
1254 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
1255
1256 Vector<camera3_stream_t*> streams;
1257 streams.setCapacity(config.num_streams);
1258
1259 if (mInputStream != NULL) {
1260 camera3_stream_t *inputStream;
1261 inputStream = mInputStream->startConfiguration();
1262 if (inputStream == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001263 SET_ERR_L("Can't start input stream configuration");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001264 return INVALID_OPERATION;
1265 }
1266 streams.add(inputStream);
1267 }
1268
1269 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Igor Murashkin2fba5842013-04-22 14:03:54 -07001270
1271 // Don't configure bidi streams twice, nor add them twice to the list
1272 if (mOutputStreams[i].get() ==
1273 static_cast<Camera3StreamInterface*>(mInputStream.get())) {
1274
1275 config.num_streams--;
1276 continue;
1277 }
1278
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001279 camera3_stream_t *outputStream;
1280 outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
1281 if (outputStream == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001282 SET_ERR_L("Can't start output stream configuration");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001283 return INVALID_OPERATION;
1284 }
1285 streams.add(outputStream);
1286 }
1287
1288 config.streams = streams.editArray();
1289
1290 // Do the HAL configuration; will potentially touch stream
1291 // max_buffers, usage, priv fields.
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001292 ATRACE_BEGIN("camera3->configure_streams");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001293 res = mHal3Device->ops->configure_streams(mHal3Device, &config);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001294 ATRACE_END();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001295
1296 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001297 SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
1298 strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001299 return res;
1300 }
1301
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07001302 // Finish all stream configuration immediately.
1303 // TODO: Try to relax this later back to lazy completion, which should be
1304 // faster
1305
Igor Murashkin073f8572013-05-02 14:59:28 -07001306 if (mInputStream != NULL && mInputStream->isConfiguring()) {
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07001307 res = mInputStream->finishConfiguration(mHal3Device);
1308 if (res != OK) {
1309 SET_ERR_L("Can't finish configuring input stream %d: %s (%d)",
1310 mInputStream->getId(), strerror(-res), res);
1311 return res;
1312 }
1313 }
1314
1315 for (size_t i = 0; i < mOutputStreams.size(); i++) {
Igor Murashkin073f8572013-05-02 14:59:28 -07001316 sp<Camera3OutputStreamInterface> outputStream =
1317 mOutputStreams.editValueAt(i);
1318 if (outputStream->isConfiguring()) {
1319 res = outputStream->finishConfiguration(mHal3Device);
1320 if (res != OK) {
1321 SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
1322 outputStream->getId(), strerror(-res), res);
1323 return res;
1324 }
Eino-Ville Talvala4c956762013-04-19 17:26:13 -07001325 }
1326 }
1327
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001328 // Request thread needs to know to avoid using repeat-last-settings protocol
1329 // across configure_streams() calls
1330 mRequestThread->configurationComplete();
1331
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001332 // Update device state
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001333
Eino-Ville Talvalaea26c772013-06-11 16:04:06 -07001334 mNeedConfig = false;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001335
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001336 if (config.num_streams > 0) {
1337 mStatus = STATUS_CONFIGURED;
1338 } else {
1339 mStatus = STATUS_UNCONFIGURED;
1340 }
1341
1342 ALOGV("%s: Camera %d: Stream configuration complete", __FUNCTION__, mId);
1343
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001344 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001345}
1346
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001347void Camera3Device::setErrorState(const char *fmt, ...) {
1348 Mutex::Autolock l(mLock);
1349 va_list args;
1350 va_start(args, fmt);
1351
1352 setErrorStateLockedV(fmt, args);
1353
1354 va_end(args);
1355}
1356
1357void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
1358 Mutex::Autolock l(mLock);
1359 setErrorStateLockedV(fmt, args);
1360}
1361
1362void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
1363 va_list args;
1364 va_start(args, fmt);
1365
1366 setErrorStateLockedV(fmt, args);
1367
1368 va_end(args);
1369}
1370
1371void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001372 // Print out all error messages to log
1373 String8 errorCause = String8::formatV(fmt, args);
1374 ALOGE("Camera %d: %s", mId, errorCause.string());
1375
1376 // But only do error state transition steps for the first error
Zhijun Heb05eeae2013-06-06 13:51:22 -07001377 if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001378
Igor Murashkinff3e31d2013-10-23 16:40:06 -07001379 // Save stack trace. View by dumping it later.
1380 CameraTraces::saveTrace();
1381 // TODO: consider adding errorCause and client pid/procname
1382
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001383 mErrorCause = errorCause;
1384
1385 mRequestThread->setPaused(true);
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001386 mStatus = STATUS_ERROR;
1387}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001388
1389/**
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001390 * In-flight request management
1391 */
1392
1393status_t Camera3Device::registerInFlight(int32_t frameNumber,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001394 int32_t requestId, int32_t numBuffers) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001395 ATRACE_CALL();
1396 Mutex::Autolock l(mInFlightLock);
1397
1398 ssize_t res;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001399 res = mInFlightMap.add(frameNumber, InFlightRequest(requestId, numBuffers));
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001400 if (res < 0) return res;
1401
1402 return OK;
1403}
1404
1405/**
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001406 * QUIRK(partial results)
1407 * Check if all 3A fields are ready, and send off a partial 3A-only result
1408 * to the output frame queue
1409 */
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001410bool Camera3Device::processPartial3AQuirk(
1411 int32_t frameNumber, int32_t requestId,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001412 const CameraMetadata& partial) {
1413
1414 // Check if all 3A states are present
1415 // The full list of fields is
1416 // android.control.afMode
1417 // android.control.awbMode
1418 // android.control.aeState
1419 // android.control.awbState
1420 // android.control.afState
1421 // android.control.afTriggerID
1422 // android.control.aePrecaptureID
1423 // TODO: Add android.control.aeMode
1424
1425 bool gotAllStates = true;
1426
1427 uint8_t afMode;
1428 uint8_t awbMode;
1429 uint8_t aeState;
1430 uint8_t afState;
1431 uint8_t awbState;
1432 int32_t afTriggerId;
1433 int32_t aeTriggerId;
1434
1435 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_MODE,
1436 &afMode, frameNumber);
1437
1438 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_MODE,
1439 &awbMode, frameNumber);
1440
1441 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_STATE,
1442 &aeState, frameNumber);
1443
1444 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_STATE,
1445 &afState, frameNumber);
1446
1447 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AWB_STATE,
1448 &awbState, frameNumber);
1449
1450 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AF_TRIGGER_ID,
1451 &afTriggerId, frameNumber);
1452
1453 gotAllStates &= get3AResult(partial, ANDROID_CONTROL_AE_PRECAPTURE_ID,
1454 &aeTriggerId, frameNumber);
1455
1456 if (!gotAllStates) return false;
1457
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001458 ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, "
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001459 "AF state %d, AE state %d, AWB state %d, "
1460 "AF trigger %d, AE precapture trigger %d",
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001461 __FUNCTION__, mId, frameNumber, requestId,
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001462 afMode, awbMode,
1463 afState, aeState, awbState,
1464 afTriggerId, aeTriggerId);
1465
1466 // Got all states, so construct a minimal result to send
1467 // In addition to the above fields, this means adding in
1468 // android.request.frameCount
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001469 // android.request.requestId
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001470 // android.quirks.partialResult
1471
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001472 const size_t kMinimal3AResultEntries = 10;
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001473
1474 Mutex::Autolock l(mOutputLock);
1475
1476 CameraMetadata& min3AResult =
1477 *mResultQueue.insert(
1478 mResultQueue.end(),
1479 CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0));
1480
1481 if (!insert3AResult(min3AResult, ANDROID_REQUEST_FRAME_COUNT,
1482 &frameNumber, frameNumber)) {
1483 return false;
1484 }
1485
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001486 if (!insert3AResult(min3AResult, ANDROID_REQUEST_ID,
1487 &requestId, frameNumber)) {
1488 return false;
1489 }
1490
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001491 static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL;
1492 if (!insert3AResult(min3AResult, ANDROID_QUIRKS_PARTIAL_RESULT,
1493 &partialResult, frameNumber)) {
1494 return false;
1495 }
1496
1497 if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_MODE,
1498 &afMode, frameNumber)) {
1499 return false;
1500 }
1501
1502 if (!insert3AResult(min3AResult, ANDROID_CONTROL_AWB_MODE,
1503 &awbMode, frameNumber)) {
1504 return false;
1505 }
1506
1507 if (!insert3AResult(min3AResult, ANDROID_CONTROL_AE_STATE,
1508 &aeState, frameNumber)) {
1509 return false;
1510 }
1511
1512 if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_STATE,
1513 &afState, frameNumber)) {
1514 return false;
1515 }
1516
1517 if (!insert3AResult(min3AResult, ANDROID_CONTROL_AWB_STATE,
1518 &awbState, frameNumber)) {
1519 return false;
1520 }
1521
1522 if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_TRIGGER_ID,
1523 &afTriggerId, frameNumber)) {
1524 return false;
1525 }
1526
1527 if (!insert3AResult(min3AResult, ANDROID_CONTROL_AE_PRECAPTURE_ID,
1528 &aeTriggerId, frameNumber)) {
1529 return false;
1530 }
1531
1532 mResultSignal.signal();
1533
1534 return true;
1535}
1536
1537template<typename T>
1538bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag,
1539 T* value, int32_t frameNumber) {
1540 (void) frameNumber;
1541
1542 camera_metadata_ro_entry_t entry;
1543
1544 entry = result.find(tag);
1545 if (entry.count == 0) {
1546 ALOGVV("%s: Camera %d: Frame %d: No %s provided by HAL!", __FUNCTION__,
1547 mId, frameNumber, get_camera_metadata_tag_name(tag));
1548 return false;
1549 }
1550
1551 if (sizeof(T) == sizeof(uint8_t)) {
1552 *value = entry.data.u8[0];
1553 } else if (sizeof(T) == sizeof(int32_t)) {
1554 *value = entry.data.i32[0];
1555 } else {
1556 ALOGE("%s: Unexpected type", __FUNCTION__);
1557 return false;
1558 }
1559 return true;
1560}
1561
1562template<typename T>
1563bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag,
1564 const T* value, int32_t frameNumber) {
1565 if (result.update(tag, value, 1) != NO_ERROR) {
1566 mResultQueue.erase(--mResultQueue.end(), mResultQueue.end());
1567 SET_ERR("Frame %d: Failed to set %s in partial metadata",
1568 frameNumber, get_camera_metadata_tag_name(tag));
1569 return false;
1570 }
1571 return true;
1572}
1573
1574/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001575 * Camera HAL device callback methods
1576 */
1577
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001578void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001579 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001580
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001581 status_t res;
1582
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001583 uint32_t frameNumber = result->frame_number;
1584 if (result->result == NULL && result->num_output_buffers == 0) {
1585 SET_ERR("No result data provided by HAL for frame %d",
1586 frameNumber);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001587 return;
1588 }
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001589 bool partialResultQuirk = false;
1590 CameraMetadata collectedQuirkResult;
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001591
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001592 // Get capture timestamp from list of in-flight requests, where it was added
1593 // by the shutter notification for this frame. Then update the in-flight
1594 // status and remove the in-flight entry if all result data has been
1595 // received.
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001596 nsecs_t timestamp = 0;
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001597 {
1598 Mutex::Autolock l(mInFlightLock);
1599 ssize_t idx = mInFlightMap.indexOfKey(frameNumber);
1600 if (idx == NAME_NOT_FOUND) {
1601 SET_ERR("Unknown frame number for capture result: %d",
1602 frameNumber);
1603 return;
1604 }
1605 InFlightRequest &request = mInFlightMap.editValueAt(idx);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001606
1607 // Check if this result carries only partial metadata
1608 if (mUsePartialResultQuirk && result->result != NULL) {
1609 camera_metadata_ro_entry_t partialResultEntry;
1610 res = find_camera_metadata_ro_entry(result->result,
1611 ANDROID_QUIRKS_PARTIAL_RESULT, &partialResultEntry);
1612 if (res != NAME_NOT_FOUND &&
1613 partialResultEntry.count > 0 &&
1614 partialResultEntry.data.u8[0] ==
1615 ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
1616 // A partial result. Flag this as such, and collect this
1617 // set of metadata into the in-flight entry.
1618 partialResultQuirk = true;
1619 request.partialResultQuirk.collectedResult.append(
1620 result->result);
1621 request.partialResultQuirk.collectedResult.erase(
1622 ANDROID_QUIRKS_PARTIAL_RESULT);
1623 // Fire off a 3A-only result if possible
1624 if (!request.partialResultQuirk.haveSent3A) {
1625 request.partialResultQuirk.haveSent3A =
1626 processPartial3AQuirk(frameNumber,
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -08001627 request.requestId,
1628 request.partialResultQuirk.collectedResult);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001629 }
1630 }
1631 }
1632
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001633 timestamp = request.captureTimestamp;
Zhijun He1d1f8462013-10-02 16:29:51 -07001634 /**
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001635 * One of the following must happen before it's legal to call process_capture_result,
1636 * unless partial metadata is being provided:
Zhijun He1d1f8462013-10-02 16:29:51 -07001637 * - CAMERA3_MSG_SHUTTER (expected during normal operation)
1638 * - CAMERA3_MSG_ERROR (expected during flush)
1639 */
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001640 if (request.requestStatus == OK && timestamp == 0 && !partialResultQuirk) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001641 SET_ERR("Called before shutter notify for frame %d",
1642 frameNumber);
1643 return;
1644 }
1645
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001646 // Did we get the (final) result metadata for this capture?
1647 if (result->result != NULL && !partialResultQuirk) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001648 if (request.haveResultMetadata) {
1649 SET_ERR("Called multiple times with metadata for frame %d",
1650 frameNumber);
1651 return;
1652 }
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001653 if (mUsePartialResultQuirk &&
1654 !request.partialResultQuirk.collectedResult.isEmpty()) {
1655 collectedQuirkResult.acquire(
1656 request.partialResultQuirk.collectedResult);
1657 }
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001658 request.haveResultMetadata = true;
1659 }
1660
1661 request.numBuffersLeft -= result->num_output_buffers;
1662
1663 if (request.numBuffersLeft < 0) {
1664 SET_ERR("Too many buffers returned for frame %d",
1665 frameNumber);
1666 return;
1667 }
1668
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001669 // Check if everything has arrived for this result (buffers and metadata)
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001670 if (request.haveResultMetadata && request.numBuffersLeft == 0) {
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001671 ATRACE_ASYNC_END("frame capture", frameNumber);
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001672 mInFlightMap.removeItemsAt(idx, 1);
1673 }
1674
1675 // Sanity check - if we have too many in-flight frames, something has
1676 // likely gone wrong
1677 if (mInFlightMap.size() > kInFlightWarnLimit) {
Colin Crosse5729fa2014-03-21 15:04:25 -07001678 CLOGE("In-flight list too large: %zu", mInFlightMap.size());
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001679 }
1680
1681 }
1682
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001683 // Process the result metadata, if provided
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001684 bool gotResult = false;
1685 if (result->result != NULL && !partialResultQuirk) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001686 Mutex::Autolock l(mOutputLock);
1687
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001688 gotResult = true;
1689
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001690 if (frameNumber != mNextResultFrameNumber) {
1691 SET_ERR("Out-of-order capture result metadata submitted! "
1692 "(got frame number %d, expecting %d)",
1693 frameNumber, mNextResultFrameNumber);
1694 return;
1695 }
1696 mNextResultFrameNumber++;
1697
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001698 CameraMetadata captureResult;
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001699 captureResult = result->result;
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001700
Igor Murashkind2c90692013-04-02 12:32:32 -07001701 if (captureResult.update(ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001702 (int32_t*)&frameNumber, 1) != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001703 SET_ERR("Failed to set frame# in metadata (%d)",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001704 frameNumber);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001705 gotResult = false;
Igor Murashkind2c90692013-04-02 12:32:32 -07001706 } else {
1707 ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001708 __FUNCTION__, mId, frameNumber);
Igor Murashkind2c90692013-04-02 12:32:32 -07001709 }
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001710
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001711 // Append any previous partials to form a complete result
1712 if (mUsePartialResultQuirk && !collectedQuirkResult.isEmpty()) {
1713 captureResult.append(collectedQuirkResult);
1714 }
1715
1716 captureResult.sort();
1717
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001718 // Check that there's a timestamp in the result metadata
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001719
1720 camera_metadata_entry entry =
1721 captureResult.find(ANDROID_SENSOR_TIMESTAMP);
1722 if (entry.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001723 SET_ERR("No timestamp provided by HAL for frame %d!",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001724 frameNumber);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001725 gotResult = false;
Alex Rayfe7e0c62013-05-30 00:12:13 -07001726 } else if (timestamp != entry.data.i64[0]) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001727 SET_ERR("Timestamp mismatch between shutter notify and result"
Colin Crosse5729fa2014-03-21 15:04:25 -07001728 " metadata for frame %d (%" PRId64 " vs %" PRId64 " respectively)",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001729 frameNumber, timestamp, entry.data.i64[0]);
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001730 gotResult = false;
1731 }
1732
1733 if (gotResult) {
1734 // Valid result, insert into queue
1735 CameraMetadata& queuedResult =
1736 *mResultQueue.insert(mResultQueue.end(), CameraMetadata());
1737 queuedResult.swap(captureResult);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001738 }
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001739 } // scope for mOutputLock
1740
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001741 // Return completed buffers to their streams with the timestamp
1742
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001743 for (size_t i = 0; i < result->num_output_buffers; i++) {
1744 Camera3Stream *stream =
1745 Camera3Stream::cast(result->output_buffers[i].stream);
1746 res = stream->returnBuffer(result->output_buffers[i], timestamp);
1747 // Note: stream may be deallocated at this point, if this buffer was the
1748 // last reference to it.
1749 if (res != OK) {
Colin Crosse5729fa2014-03-21 15:04:25 -07001750 ALOGE("Can't return buffer %zu for frame %d to its stream: "
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001751 " %s (%d)", i, frameNumber, strerror(-res), res);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001752 }
1753 }
1754
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -07001755 // Finally, signal any waiters for new frames
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001756
Eino-Ville Talvalafd6ecdd2013-10-11 09:51:09 -07001757 if (gotResult) {
Igor Murashkin4345d5b2013-05-17 14:39:53 -07001758 mResultSignal.signal();
1759 }
1760
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001761}
1762
Eino-Ville Talvala46910bd2013-07-18 19:15:17 -07001763
1764
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001765void Camera3Device::notify(const camera3_notify_msg *msg) {
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001766 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001767 NotificationListener *listener;
1768 {
1769 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001770 listener = mListener;
1771 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001772
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001773 if (msg == NULL) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001774 SET_ERR("HAL sent NULL notify message!");
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001775 return;
1776 }
1777
1778 switch (msg->type) {
1779 case CAMERA3_MSG_ERROR: {
1780 int streamId = 0;
1781 if (msg->message.error.error_stream != NULL) {
1782 Camera3Stream *stream =
1783 Camera3Stream::cast(
1784 msg->message.error.error_stream);
1785 streamId = stream->getId();
1786 }
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07001787 ALOGV("Camera %d: %s: HAL error, frame %d, stream %d: %d",
1788 mId, __FUNCTION__, msg->message.error.frame_number,
1789 streamId, msg->message.error.error_code);
Zhijun He1d1f8462013-10-02 16:29:51 -07001790
1791 // Set request error status for the request in the in-flight tracking
1792 {
1793 Mutex::Autolock l(mInFlightLock);
1794 ssize_t idx = mInFlightMap.indexOfKey(msg->message.error.frame_number);
1795 if (idx >= 0) {
1796 mInFlightMap.editValueAt(idx).requestStatus = msg->message.error.error_code;
1797 }
1798 }
1799
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001800 if (listener != NULL) {
1801 listener->notifyError(msg->message.error.error_code,
1802 msg->message.error.frame_number, streamId);
1803 }
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001804 break;
1805 }
1806 case CAMERA3_MSG_SHUTTER: {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001807 ssize_t idx;
1808 uint32_t frameNumber = msg->message.shutter.frame_number;
1809 nsecs_t timestamp = msg->message.shutter.timestamp;
1810 // Verify ordering of shutter notifications
1811 {
1812 Mutex::Autolock l(mOutputLock);
1813 if (frameNumber != mNextShutterFrameNumber) {
1814 SET_ERR("Shutter notification out-of-order. Expected "
1815 "notification for frame %d, got frame %d",
1816 mNextShutterFrameNumber, frameNumber);
1817 break;
1818 }
1819 mNextShutterFrameNumber++;
1820 }
1821
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001822 int32_t requestId = -1;
1823
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001824 // Set timestamp for the request in the in-flight tracking
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001825 // and get the request ID to send upstream
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001826 {
1827 Mutex::Autolock l(mInFlightLock);
1828 idx = mInFlightMap.indexOfKey(frameNumber);
1829 if (idx >= 0) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001830 InFlightRequest &r = mInFlightMap.editValueAt(idx);
1831 r.captureTimestamp = timestamp;
1832 requestId = r.requestId;
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001833 }
1834 }
1835 if (idx < 0) {
1836 SET_ERR("Shutter notification for non-existent frame number %d",
1837 frameNumber);
1838 break;
1839 }
Colin Crosse5729fa2014-03-21 15:04:25 -07001840 ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001841 mId, __FUNCTION__, frameNumber, requestId, timestamp);
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001842 // Call listener, if any
1843 if (listener != NULL) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001844 listener->notifyShutter(requestId, timestamp);
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001845 }
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001846 break;
1847 }
1848 default:
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001849 SET_ERR("Unknown notify message from HAL: %d",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001850 msg->type);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001851 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001852}
1853
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001854CameraMetadata Camera3Device::getLatestRequestLocked() {
Igor Murashkin1e479c02013-09-06 16:55:14 -07001855 ALOGV("%s", __FUNCTION__);
1856
Igor Murashkin1e479c02013-09-06 16:55:14 -07001857 CameraMetadata retVal;
1858
1859 if (mRequestThread != NULL) {
1860 retVal = mRequestThread->getLatestRequest();
1861 }
1862
Igor Murashkin1e479c02013-09-06 16:55:14 -07001863 return retVal;
1864}
1865
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001866/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001867 * RequestThread inner class methods
1868 */
1869
1870Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001871 sp<StatusTracker> statusTracker,
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001872 camera3_device_t *hal3Device) :
1873 Thread(false),
1874 mParent(parent),
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001875 mStatusTracker(statusTracker),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001876 mHal3Device(hal3Device),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001877 mId(getId(parent)),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001878 mReconfigured(false),
1879 mDoPause(false),
1880 mPaused(true),
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001881 mFrameNumber(0),
1882 mLatestRequestId(NAME_NOT_FOUND) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001883 mStatusId = statusTracker->addComponent();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001884}
1885
1886void Camera3Device::RequestThread::configurationComplete() {
1887 Mutex::Autolock l(mRequestLock);
1888 mReconfigured = true;
1889}
1890
1891status_t Camera3Device::RequestThread::queueRequest(
1892 sp<CaptureRequest> request) {
1893 Mutex::Autolock l(mRequestLock);
1894 mRequestQueue.push_back(request);
1895
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07001896 unpauseForNewRequests();
1897
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001898 return OK;
1899}
1900
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001901
1902status_t Camera3Device::RequestThread::queueTrigger(
1903 RequestTrigger trigger[],
1904 size_t count) {
1905
1906 Mutex::Autolock l(mTriggerMutex);
1907 status_t ret;
1908
1909 for (size_t i = 0; i < count; ++i) {
1910 ret = queueTriggerLocked(trigger[i]);
1911
1912 if (ret != OK) {
1913 return ret;
1914 }
1915 }
1916
1917 return OK;
1918}
1919
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001920int Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
1921 sp<Camera3Device> d = device.promote();
1922 if (d != NULL) return d->mId;
1923 return 0;
1924}
1925
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001926status_t Camera3Device::RequestThread::queueTriggerLocked(
1927 RequestTrigger trigger) {
1928
1929 uint32_t tag = trigger.metadataTag;
1930 ssize_t index = mTriggerMap.indexOfKey(tag);
1931
1932 switch (trigger.getTagType()) {
1933 case TYPE_BYTE:
1934 // fall-through
1935 case TYPE_INT32:
1936 break;
1937 default:
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001938 ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
1939 trigger.getTagType());
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001940 return INVALID_OPERATION;
1941 }
1942
1943 /**
1944 * Collect only the latest trigger, since we only have 1 field
1945 * in the request settings per trigger tag, and can't send more than 1
1946 * trigger per request.
1947 */
1948 if (index != NAME_NOT_FOUND) {
1949 mTriggerMap.editValueAt(index) = trigger;
1950 } else {
1951 mTriggerMap.add(tag, trigger);
1952 }
1953
1954 return OK;
1955}
1956
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001957status_t Camera3Device::RequestThread::setRepeatingRequests(
1958 const RequestList &requests) {
1959 Mutex::Autolock l(mRequestLock);
1960 mRepeatingRequests.clear();
1961 mRepeatingRequests.insert(mRepeatingRequests.begin(),
1962 requests.begin(), requests.end());
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07001963
1964 unpauseForNewRequests();
1965
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001966 return OK;
1967}
1968
1969status_t Camera3Device::RequestThread::clearRepeatingRequests() {
1970 Mutex::Autolock l(mRequestLock);
1971 mRepeatingRequests.clear();
1972 return OK;
1973}
1974
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001975status_t Camera3Device::RequestThread::clear() {
1976 Mutex::Autolock l(mRequestLock);
1977 mRepeatingRequests.clear();
1978 mRequestQueue.clear();
1979 mTriggerMap.clear();
1980 return OK;
1981}
1982
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001983void Camera3Device::RequestThread::setPaused(bool paused) {
1984 Mutex::Autolock l(mPauseLock);
1985 mDoPause = paused;
1986 mDoPauseSignal.signal();
1987}
1988
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001989status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
1990 int32_t requestId, nsecs_t timeout) {
1991 Mutex::Autolock l(mLatestRequestMutex);
1992 status_t res;
1993 while (mLatestRequestId != requestId) {
1994 nsecs_t startTime = systemTime();
1995
1996 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
1997 if (res != OK) return res;
1998
1999 timeout -= (systemTime() - startTime);
2000 }
2001
2002 return OK;
2003}
2004
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002005void Camera3Device::RequestThread::requestExit() {
2006 // Call parent to set up shutdown
2007 Thread::requestExit();
2008 // The exit from any possible waits
2009 mDoPauseSignal.signal();
2010 mRequestSignal.signal();
2011}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002012
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002013bool Camera3Device::RequestThread::threadLoop() {
2014
2015 status_t res;
2016
2017 // Handle paused state.
2018 if (waitIfPaused()) {
2019 return true;
2020 }
2021
2022 // Get work to do
2023
2024 sp<CaptureRequest> nextRequest = waitForNextRequest();
2025 if (nextRequest == NULL) {
2026 return true;
2027 }
2028
2029 // Create request to HAL
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002030 camera3_capture_request_t request = camera3_capture_request_t();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002031 Vector<camera3_stream_buffer_t> outputBuffers;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002032
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002033 // Get the request ID, if any
2034 int requestId;
2035 camera_metadata_entry_t requestIdEntry =
2036 nextRequest->mSettings.find(ANDROID_REQUEST_ID);
2037 if (requestIdEntry.count > 0) {
2038 requestId = requestIdEntry.data.i32[0];
2039 } else {
2040 ALOGW("%s: Did not have android.request.id set in the request",
2041 __FUNCTION__);
2042 requestId = NAME_NOT_FOUND;
2043 }
2044
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002045 // Insert any queued triggers (before metadata is locked)
2046 int32_t triggerCount;
2047 res = insertTriggers(nextRequest);
2048 if (res < 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002049 SET_ERR("RequestThread: Unable to insert triggers "
2050 "(capture request %d, HAL device: %s (%d)",
2051 (mFrameNumber+1), strerror(-res), res);
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002052 cleanUpFailedRequest(request, nextRequest, outputBuffers);
2053 return false;
2054 }
2055 triggerCount = res;
2056
2057 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
2058
2059 // If the request is the same as last, or we had triggers last time
2060 if (mPrevRequest != nextRequest || triggersMixedIn) {
2061 /**
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07002062 * HAL workaround:
2063 * Insert a dummy trigger ID if a trigger is set but no trigger ID is
2064 */
2065 res = addDummyTriggerIds(nextRequest);
2066 if (res != OK) {
2067 SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
2068 "(capture request %d, HAL device: %s (%d)",
2069 (mFrameNumber+1), strerror(-res), res);
2070 cleanUpFailedRequest(request, nextRequest, outputBuffers);
2071 return false;
2072 }
2073
2074 /**
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002075 * The request should be presorted so accesses in HAL
2076 * are O(logn). Sidenote, sorting a sorted metadata is nop.
2077 */
2078 nextRequest->mSettings.sort();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002079 request.settings = nextRequest->mSettings.getAndLock();
2080 mPrevRequest = nextRequest;
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002081 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
2082
2083 IF_ALOGV() {
2084 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
2085 find_camera_metadata_ro_entry(
2086 request.settings,
2087 ANDROID_CONTROL_AF_TRIGGER,
2088 &e
2089 );
2090 if (e.count > 0) {
2091 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
2092 __FUNCTION__,
2093 mFrameNumber+1,
2094 e.data.u8[0]);
2095 }
2096 }
2097 } else {
2098 // leave request.settings NULL to indicate 'reuse latest given'
2099 ALOGVV("%s: Request settings are REUSED",
2100 __FUNCTION__);
2101 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002102
2103 camera3_stream_buffer_t inputBuffer;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002104
2105 // Fill in buffers
2106
2107 if (nextRequest->mInputStream != NULL) {
2108 request.input_buffer = &inputBuffer;
Igor Murashkin5a269fa2013-04-15 14:59:22 -07002109 res = nextRequest->mInputStream->getInputBuffer(&inputBuffer);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002110 if (res != OK) {
Eino-Ville Talvala07d21692013-09-24 18:04:19 -07002111 ALOGE("RequestThread: Can't get input buffer, skipping request:"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002112 " %s (%d)", strerror(-res), res);
2113 cleanUpFailedRequest(request, nextRequest, outputBuffers);
2114 return true;
2115 }
2116 } else {
2117 request.input_buffer = NULL;
2118 }
2119
2120 outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
2121 nextRequest->mOutputStreams.size());
2122 request.output_buffers = outputBuffers.array();
2123 for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
2124 res = nextRequest->mOutputStreams.editItemAt(i)->
2125 getBuffer(&outputBuffers.editItemAt(i));
2126 if (res != OK) {
Eino-Ville Talvala07d21692013-09-24 18:04:19 -07002127 ALOGE("RequestThread: Can't get output buffer, skipping request:"
2128 " %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002129 cleanUpFailedRequest(request, nextRequest, outputBuffers);
2130 return true;
2131 }
2132 request.num_output_buffers++;
2133 }
2134
2135 request.frame_number = mFrameNumber++;
2136
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002137 // Log request in the in-flight queue
2138 sp<Camera3Device> parent = mParent.promote();
2139 if (parent == NULL) {
2140 CLOGE("RequestThread: Parent is gone");
2141 cleanUpFailedRequest(request, nextRequest, outputBuffers);
2142 return false;
2143 }
2144
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002145 res = parent->registerInFlight(request.frame_number, requestId,
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07002146 request.num_output_buffers);
2147 if (res != OK) {
2148 SET_ERR("RequestThread: Unable to register new in-flight request:"
2149 " %s (%d)", strerror(-res), res);
2150 cleanUpFailedRequest(request, nextRequest, outputBuffers);
2151 return false;
2152 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002153
Zhijun Hecc27e112013-10-03 16:12:43 -07002154 // Inform waitUntilRequestProcessed thread of a new request ID
2155 {
2156 Mutex::Autolock al(mLatestRequestMutex);
2157
2158 mLatestRequestId = requestId;
2159 mLatestRequestSignal.signal();
2160 }
2161
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002162 // Submit request and block until ready for next one
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07002163 ATRACE_ASYNC_BEGIN("frame capture", request.frame_number);
2164 ATRACE_BEGIN("camera3->process_capture_request");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002165 res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
Eino-Ville Talvala17a61ad2013-06-03 16:53:32 -07002166 ATRACE_END();
2167
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002168 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002169 SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002170 " device: %s (%d)", request.frame_number, strerror(-res), res);
2171 cleanUpFailedRequest(request, nextRequest, outputBuffers);
2172 return false;
2173 }
2174
Igor Murashkin1e479c02013-09-06 16:55:14 -07002175 // Update the latest request sent to HAL
2176 if (request.settings != NULL) { // Don't update them if they were unchanged
2177 Mutex::Autolock al(mLatestRequestMutex);
2178
2179 camera_metadata_t* cloned = clone_camera_metadata(request.settings);
2180 mLatestRequest.acquire(cloned);
2181 }
2182
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002183 if (request.settings != NULL) {
2184 nextRequest->mSettings.unlock(request.settings);
2185 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002186
2187 // Remove any previously queued triggers (after unlock)
2188 res = removeTriggers(mPrevRequest);
2189 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002190 SET_ERR("RequestThread: Unable to remove triggers "
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002191 "(capture request %d, HAL device: %s (%d)",
2192 request.frame_number, strerror(-res), res);
2193 return false;
2194 }
2195 mPrevTriggers = triggerCount;
2196
Igor Murashkin5a269fa2013-04-15 14:59:22 -07002197 // Return input buffer back to framework
2198 if (request.input_buffer != NULL) {
2199 Camera3Stream *stream =
2200 Camera3Stream::cast(request.input_buffer->stream);
2201 res = stream->returnInputBuffer(*(request.input_buffer));
2202 // Note: stream may be deallocated at this point, if this buffer was the
2203 // last reference to it.
2204 if (res != OK) {
2205 ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
2206 " its stream:%s (%d)", __FUNCTION__,
2207 request.frame_number, strerror(-res), res);
2208 // TODO: Report error upstream
2209 }
2210 }
2211
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002212 return true;
2213}
2214
Igor Murashkin1e479c02013-09-06 16:55:14 -07002215CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
2216 Mutex::Autolock al(mLatestRequestMutex);
2217
2218 ALOGV("RequestThread::%s", __FUNCTION__);
2219
2220 return mLatestRequest;
2221}
2222
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002223void Camera3Device::RequestThread::cleanUpFailedRequest(
2224 camera3_capture_request_t &request,
2225 sp<CaptureRequest> &nextRequest,
2226 Vector<camera3_stream_buffer_t> &outputBuffers) {
2227
2228 if (request.settings != NULL) {
2229 nextRequest->mSettings.unlock(request.settings);
2230 }
2231 if (request.input_buffer != NULL) {
2232 request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
Igor Murashkin5a269fa2013-04-15 14:59:22 -07002233 nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer));
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002234 }
2235 for (size_t i = 0; i < request.num_output_buffers; i++) {
2236 outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
2237 nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
2238 outputBuffers[i], 0);
2239 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002240}
2241
2242sp<Camera3Device::CaptureRequest>
2243 Camera3Device::RequestThread::waitForNextRequest() {
2244 status_t res;
2245 sp<CaptureRequest> nextRequest;
2246
2247 // Optimized a bit for the simple steady-state case (single repeating
2248 // request), to avoid putting that request in the queue temporarily.
2249 Mutex::Autolock l(mRequestLock);
2250
2251 while (mRequestQueue.empty()) {
2252 if (!mRepeatingRequests.empty()) {
2253 // Always atomically enqueue all requests in a repeating request
2254 // list. Guarantees a complete in-sequence set of captures to
2255 // application.
2256 const RequestList &requests = mRepeatingRequests;
2257 RequestList::const_iterator firstRequest =
2258 requests.begin();
2259 nextRequest = *firstRequest;
2260 mRequestQueue.insert(mRequestQueue.end(),
2261 ++firstRequest,
2262 requests.end());
2263 // No need to wait any longer
2264 break;
2265 }
2266
2267 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
2268
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002269 if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
2270 exitPending()) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002271 Mutex::Autolock pl(mPauseLock);
2272 if (mPaused == false) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002273 ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002274 mPaused = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002275 // Let the tracker know
2276 sp<StatusTracker> statusTracker = mStatusTracker.promote();
2277 if (statusTracker != 0) {
2278 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2279 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002280 }
2281 // Stop waiting for now and let thread management happen
2282 return NULL;
2283 }
2284 }
2285
2286 if (nextRequest == NULL) {
2287 // Don't have a repeating request already in hand, so queue
2288 // must have an entry now.
2289 RequestList::iterator firstRequest =
2290 mRequestQueue.begin();
2291 nextRequest = *firstRequest;
2292 mRequestQueue.erase(firstRequest);
2293 }
2294
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07002295 // In case we've been unpaused by setPaused clearing mDoPause, need to
2296 // update internal pause state (capture/setRepeatingRequest unpause
2297 // directly).
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002298 Mutex::Autolock pl(mPauseLock);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002299 if (mPaused) {
2300 ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
2301 sp<StatusTracker> statusTracker = mStatusTracker.promote();
2302 if (statusTracker != 0) {
2303 statusTracker->markComponentActive(mStatusId);
2304 }
2305 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002306 mPaused = false;
2307
2308 // Check if we've reconfigured since last time, and reset the preview
2309 // request if so. Can't use 'NULL request == repeat' across configure calls.
2310 if (mReconfigured) {
2311 mPrevRequest.clear();
2312 mReconfigured = false;
2313 }
2314
2315 return nextRequest;
2316}
2317
2318bool Camera3Device::RequestThread::waitIfPaused() {
2319 status_t res;
2320 Mutex::Autolock l(mPauseLock);
2321 while (mDoPause) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002322 if (mPaused == false) {
2323 mPaused = true;
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002324 ALOGV("%s: RequestThread: Paused", __FUNCTION__);
2325 // Let the tracker know
2326 sp<StatusTracker> statusTracker = mStatusTracker.promote();
2327 if (statusTracker != 0) {
2328 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
2329 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002330 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002331
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002332 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002333 if (res == TIMED_OUT || exitPending()) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002334 return true;
2335 }
2336 }
2337 // We don't set mPaused to false here, because waitForNextRequest needs
2338 // to further manage the paused state in case of starvation.
2339 return false;
2340}
2341
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07002342void Camera3Device::RequestThread::unpauseForNewRequests() {
2343 // With work to do, mark thread as unpaused.
2344 // If paused by request (setPaused), don't resume, to avoid
2345 // extra signaling/waiting overhead to waitUntilPaused
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002346 mRequestSignal.signal();
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07002347 Mutex::Autolock p(mPauseLock);
2348 if (!mDoPause) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002349 ALOGV("%s: RequestThread: Going active", __FUNCTION__);
2350 if (mPaused) {
2351 sp<StatusTracker> statusTracker = mStatusTracker.promote();
2352 if (statusTracker != 0) {
2353 statusTracker->markComponentActive(mStatusId);
2354 }
2355 }
Eino-Ville Talvala26fe6c72013-08-29 12:46:18 -07002356 mPaused = false;
2357 }
2358}
2359
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07002360void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
2361 sp<Camera3Device> parent = mParent.promote();
2362 if (parent != NULL) {
2363 va_list args;
2364 va_start(args, fmt);
2365
2366 parent->setErrorStateV(fmt, args);
2367
2368 va_end(args);
2369 }
2370}
2371
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002372status_t Camera3Device::RequestThread::insertTriggers(
2373 const sp<CaptureRequest> &request) {
2374
2375 Mutex::Autolock al(mTriggerMutex);
2376
2377 CameraMetadata &metadata = request->mSettings;
2378 size_t count = mTriggerMap.size();
2379
2380 for (size_t i = 0; i < count; ++i) {
2381 RequestTrigger trigger = mTriggerMap.valueAt(i);
2382
2383 uint32_t tag = trigger.metadataTag;
2384 camera_metadata_entry entry = metadata.find(tag);
2385
2386 if (entry.count > 0) {
2387 /**
2388 * Already has an entry for this trigger in the request.
2389 * Rewrite it with our requested trigger value.
2390 */
2391 RequestTrigger oldTrigger = trigger;
2392
2393 oldTrigger.entryValue = entry.data.u8[0];
2394
2395 mTriggerReplacedMap.add(tag, oldTrigger);
2396 } else {
2397 /**
2398 * More typical, no trigger entry, so we just add it
2399 */
2400 mTriggerRemovedMap.add(tag, trigger);
2401 }
2402
2403 status_t res;
2404
2405 switch (trigger.getTagType()) {
2406 case TYPE_BYTE: {
2407 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2408 res = metadata.update(tag,
2409 &entryValue,
2410 /*count*/1);
2411 break;
2412 }
2413 case TYPE_INT32:
2414 res = metadata.update(tag,
2415 &trigger.entryValue,
2416 /*count*/1);
2417 break;
2418 default:
2419 ALOGE("%s: Type not supported: 0x%x",
2420 __FUNCTION__,
2421 trigger.getTagType());
2422 return INVALID_OPERATION;
2423 }
2424
2425 if (res != OK) {
2426 ALOGE("%s: Failed to update request metadata with trigger tag %s"
2427 ", value %d", __FUNCTION__, trigger.getTagName(),
2428 trigger.entryValue);
2429 return res;
2430 }
2431
2432 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
2433 trigger.getTagName(),
2434 trigger.entryValue);
2435 }
2436
2437 mTriggerMap.clear();
2438
2439 return count;
2440}
2441
2442status_t Camera3Device::RequestThread::removeTriggers(
2443 const sp<CaptureRequest> &request) {
2444 Mutex::Autolock al(mTriggerMutex);
2445
2446 CameraMetadata &metadata = request->mSettings;
2447
2448 /**
2449 * Replace all old entries with their old values.
2450 */
2451 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
2452 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
2453
2454 status_t res;
2455
2456 uint32_t tag = trigger.metadataTag;
2457 switch (trigger.getTagType()) {
2458 case TYPE_BYTE: {
2459 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
2460 res = metadata.update(tag,
2461 &entryValue,
2462 /*count*/1);
2463 break;
2464 }
2465 case TYPE_INT32:
2466 res = metadata.update(tag,
2467 &trigger.entryValue,
2468 /*count*/1);
2469 break;
2470 default:
2471 ALOGE("%s: Type not supported: 0x%x",
2472 __FUNCTION__,
2473 trigger.getTagType());
2474 return INVALID_OPERATION;
2475 }
2476
2477 if (res != OK) {
2478 ALOGE("%s: Failed to restore request metadata with trigger tag %s"
2479 ", trigger value %d", __FUNCTION__,
2480 trigger.getTagName(), trigger.entryValue);
2481 return res;
2482 }
2483 }
2484 mTriggerReplacedMap.clear();
2485
2486 /**
2487 * Remove all new entries.
2488 */
2489 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
2490 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
2491 status_t res = metadata.erase(trigger.metadataTag);
2492
2493 if (res != OK) {
2494 ALOGE("%s: Failed to erase metadata with trigger tag %s"
2495 ", trigger value %d", __FUNCTION__,
2496 trigger.getTagName(), trigger.entryValue);
2497 return res;
2498 }
2499 }
2500 mTriggerRemovedMap.clear();
2501
2502 return OK;
2503}
2504
Eino-Ville Talvala2f876f92013-09-13 11:39:24 -07002505status_t Camera3Device::RequestThread::addDummyTriggerIds(
2506 const sp<CaptureRequest> &request) {
2507 // Trigger ID 0 has special meaning in the HAL2 spec, so avoid it here
2508 static const int32_t dummyTriggerId = 1;
2509 status_t res;
2510
2511 CameraMetadata &metadata = request->mSettings;
2512
2513 // If AF trigger is active, insert a dummy AF trigger ID if none already
2514 // exists
2515 camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
2516 camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
2517 if (afTrigger.count > 0 &&
2518 afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
2519 afId.count == 0) {
2520 res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &dummyTriggerId, 1);
2521 if (res != OK) return res;
2522 }
2523
2524 // If AE precapture trigger is active, insert a dummy precapture trigger ID
2525 // if none already exists
2526 camera_metadata_entry pcTrigger =
2527 metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
2528 camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
2529 if (pcTrigger.count > 0 &&
2530 pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
2531 pcId.count == 0) {
2532 res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
2533 &dummyTriggerId, 1);
2534 if (res != OK) return res;
2535 }
2536
2537 return OK;
2538}
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07002539
2540
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08002541/**
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08002542 * Static callback forwarding methods from HAL to instance
2543 */
2544
2545void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
2546 const camera3_capture_result *result) {
2547 Camera3Device *d =
2548 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2549 d->processCaptureResult(result);
2550}
2551
2552void Camera3Device::sNotify(const camera3_callback_ops *cb,
2553 const camera3_notify_msg *msg) {
2554 Camera3Device *d =
2555 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
2556 d->notify(msg);
2557}
2558
2559}; // namespace android