blob: d67b535e36549d1b78095253945d543b1c07a0fc [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
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080040#include <utils/Log.h>
41#include <utils/Trace.h>
42#include <utils/Timers.h>
43#include "Camera3Device.h"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080044#include "camera3/Camera3OutputStream.h"
45
46using namespace android::camera3;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080047
48namespace android {
49
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080050Camera3Device::Camera3Device(int id):
51 mId(id),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080052 mHal3Device(NULL),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070053 mStatus(STATUS_UNINITIALIZED),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -070054 mNextResultFrameNumber(0),
55 mNextShutterFrameNumber(0),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070056 mListener(NULL)
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080057{
58 ATRACE_CALL();
59 camera3_callback_ops::notify = &sNotify;
60 camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
61 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
62}
63
64Camera3Device::~Camera3Device()
65{
66 ATRACE_CALL();
67 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
68 disconnect();
69}
70
Igor Murashkin71381052013-03-04 14:53:08 -080071int Camera3Device::getId() const {
72 return mId;
73}
74
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080075/**
76 * CameraDeviceBase interface
77 */
78
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080079status_t Camera3Device::initialize(camera_module_t *module)
80{
81 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080082 Mutex::Autolock l(mLock);
83
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080084 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080085 if (mStatus != STATUS_UNINITIALIZED) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -070086 CLOGE("Already initialized!");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080087 return INVALID_OPERATION;
88 }
89
90 /** Open HAL device */
91
92 status_t res;
93 String8 deviceName = String8::format("%d", mId);
94
95 camera3_device_t *device;
96
97 res = module->common.methods->open(&module->common, deviceName.string(),
98 reinterpret_cast<hw_device_t**>(&device));
99
100 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700101 SET_ERR_L("Could not open camera: %s (%d)", strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800102 return res;
103 }
104
105 /** Cross-check device version */
106
107 if (device->common.version != CAMERA_DEVICE_API_VERSION_3_0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700108 SET_ERR_L("Could not open camera: "
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800109 "Camera device is not version %x, reports %x instead",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700110 CAMERA_DEVICE_API_VERSION_3_0,
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800111 device->common.version);
112 device->common.close(&device->common);
113 return BAD_VALUE;
114 }
115
116 camera_info info;
117 res = module->get_camera_info(mId, &info);
118 if (res != OK) return res;
119
120 if (info.device_version != device->common.version) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700121 SET_ERR_L("HAL reporting mismatched camera_info version (%x)"
122 " and device version (%x).",
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800123 device->common.version, info.device_version);
124 device->common.close(&device->common);
125 return BAD_VALUE;
126 }
127
128 /** Initialize device with callback functions */
129
130 res = device->ops->initialize(device, this);
131 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700132 SET_ERR_L("Unable to initialize HAL device: %s (%d)",
133 strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800134 device->common.close(&device->common);
135 return BAD_VALUE;
136 }
137
138 /** Get vendor metadata tags */
139
140 mVendorTagOps.get_camera_vendor_section_name = NULL;
141
142 device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
143
144 if (mVendorTagOps.get_camera_vendor_section_name != NULL) {
145 res = set_camera_metadata_vendor_tag_ops(&mVendorTagOps);
146 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700147 SET_ERR_L("Unable to set tag ops: %s (%d)",
148 strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800149 device->common.close(&device->common);
150 return res;
151 }
152 }
153
154 /** Start up request queue thread */
155
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800156 mRequestThread = new RequestThread(this, device);
157 res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800158 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700159 SET_ERR_L("Unable to start request queue thread: %s (%d)",
160 strerror(-res), res);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800161 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800162 mRequestThread.clear();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800163 return res;
164 }
165
166 /** Everything is good to go */
167
168 mDeviceInfo = info.static_camera_characteristics;
169 mHal3Device = device;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800170 mStatus = STATUS_IDLE;
171 mNextStreamId = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800172
173 return OK;
174}
175
176status_t Camera3Device::disconnect() {
177 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800178 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800179
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800180 ALOGV("%s: E", __FUNCTION__);
181
182 status_t res;
183 if (mStatus == STATUS_UNINITIALIZED) return OK;
184
185 if (mStatus == STATUS_ACTIVE ||
186 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
187 res = mRequestThread->clearRepeatingRequests();
188 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700189 SET_ERR_L("Can't stop streaming");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800190 return res;
191 }
192 res = waitUntilDrainedLocked();
193 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700194 SET_ERR_L("Timeout waiting for HAL to drain");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800195 return res;
196 }
197 }
198 assert(mStatus == STATUS_IDLE || mStatus == STATUS_ERROR);
199
200 if (mRequestThread != NULL) {
201 mRequestThread->requestExit();
202 }
203
204 mOutputStreams.clear();
205 mInputStream.clear();
206
207 if (mRequestThread != NULL) {
208 mRequestThread->join();
209 mRequestThread.clear();
210 }
211
212 if (mHal3Device != NULL) {
213 mHal3Device->common.close(&mHal3Device->common);
214 mHal3Device = NULL;
215 }
216
217 mStatus = STATUS_UNINITIALIZED;
218
219 ALOGV("%s: X", __FUNCTION__);
220 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800221}
222
223status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
224 ATRACE_CALL();
225 (void)args;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800226 String8 lines;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800227
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800228 const char *status =
229 mStatus == STATUS_ERROR ? "ERROR" :
230 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
231 mStatus == STATUS_IDLE ? "IDLE" :
232 mStatus == STATUS_ACTIVE ? "ACTIVE" :
233 "Unknown";
234 lines.appendFormat(" Device status: %s\n", status);
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700235 if (mStatus == STATUS_ERROR) {
236 lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
237 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800238 lines.appendFormat(" Stream configuration:\n");
239
240 if (mInputStream != NULL) {
241 write(fd, lines.string(), lines.size());
242 mInputStream->dump(fd, args);
243 } else {
244 lines.appendFormat(" No input stream.\n");
245 write(fd, lines.string(), lines.size());
246 }
247 for (size_t i = 0; i < mOutputStreams.size(); i++) {
248 mOutputStreams[i]->dump(fd,args);
249 }
250
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700251 lines = String8(" In-flight requests:\n");
252 if (mInFlightMap.size() == 0) {
253 lines.append(" None\n");
254 } else {
255 for (size_t i = 0; i < mInFlightMap.size(); i++) {
256 InFlightRequest r = mInFlightMap.valueAt(i);
257 lines.appendFormat(" Frame %d | Timestamp: %lld, metadata"
258 " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
259 r.captureTimestamp, r.haveResultMetadata ? "true" : "false",
260 r.numBuffersLeft);
261 }
262 }
263 write(fd, lines.string(), lines.size());
264
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800265 if (mHal3Device != NULL) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700266 lines = String8(" HAL device dump:\n");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800267 write(fd, lines.string(), lines.size());
268 mHal3Device->ops->dump(mHal3Device, fd);
269 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800270
271 return OK;
272}
273
274const CameraMetadata& Camera3Device::info() const {
275 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800276 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
277 mStatus == STATUS_ERROR)) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700278 ALOGW("%s: Access to static info %s!", __FUNCTION__,
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800279 mStatus == STATUS_ERROR ?
280 "when in error state" : "before init");
281 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800282 return mDeviceInfo;
283}
284
285status_t Camera3Device::capture(CameraMetadata &request) {
286 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800287 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800288
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700289 // TODO: take ownership of the request
290
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800291 switch (mStatus) {
292 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700293 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800294 return INVALID_OPERATION;
295 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700296 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800297 return INVALID_OPERATION;
298 case STATUS_IDLE:
299 case STATUS_ACTIVE:
300 // OK
301 break;
302 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700303 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800304 return INVALID_OPERATION;
305 }
306
307 sp<CaptureRequest> newRequest = setUpRequestLocked(request);
308 if (newRequest == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700309 CLOGE("Can't create capture request");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800310 return BAD_VALUE;
311 }
312
313 return mRequestThread->queueRequest(newRequest);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800314}
315
316
317status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) {
318 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800319 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800320
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800321 switch (mStatus) {
322 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700323 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800324 return INVALID_OPERATION;
325 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700326 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800327 return INVALID_OPERATION;
328 case STATUS_IDLE:
329 case STATUS_ACTIVE:
330 // OK
331 break;
332 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700333 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800334 return INVALID_OPERATION;
335 }
336
337 sp<CaptureRequest> newRepeatingRequest = setUpRequestLocked(request);
338 if (newRepeatingRequest == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700339 CLOGE("Can't create repeating request");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800340 return BAD_VALUE;
341 }
342
343 RequestList newRepeatingRequests;
344 newRepeatingRequests.push_back(newRepeatingRequest);
345
346 return mRequestThread->setRepeatingRequests(newRepeatingRequests);
347}
348
349
350sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
351 const CameraMetadata &request) {
352 status_t res;
353
354 if (mStatus == STATUS_IDLE) {
355 res = configureStreamsLocked();
356 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700357 SET_ERR_L("Can't set up streams: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800358 return NULL;
359 }
360 }
361
362 sp<CaptureRequest> newRequest = createCaptureRequest(request);
363 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800364}
365
366status_t Camera3Device::clearStreamingRequest() {
367 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800368 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800369
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800370 switch (mStatus) {
371 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700372 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800373 return INVALID_OPERATION;
374 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700375 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800376 return INVALID_OPERATION;
377 case STATUS_IDLE:
378 case STATUS_ACTIVE:
379 // OK
380 break;
381 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700382 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800383 return INVALID_OPERATION;
384 }
385
386 return mRequestThread->clearRepeatingRequests();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800387}
388
389status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
390 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800391
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700392 return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800393}
394
395status_t Camera3Device::createStream(sp<ANativeWindow> consumer,
396 uint32_t width, uint32_t height, int format, size_t size, int *id) {
397 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800398 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800399
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800400 status_t res;
401 bool wasActive = false;
402
403 switch (mStatus) {
404 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700405 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800406 return INVALID_OPERATION;
407 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700408 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800409 return INVALID_OPERATION;
410 case STATUS_IDLE:
411 // OK
412 break;
413 case STATUS_ACTIVE:
414 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
415 mRequestThread->setPaused(true);
416 res = waitUntilDrainedLocked();
417 if (res != OK) {
418 ALOGE("%s: Can't pause captures to reconfigure streams!",
419 __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800420 return res;
421 }
422 wasActive = true;
423 break;
424 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700425 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800426 return INVALID_OPERATION;
427 }
428 assert(mStatus == STATUS_IDLE);
429
430 sp<Camera3OutputStream> newStream;
431 if (format == HAL_PIXEL_FORMAT_BLOB) {
432 newStream = new Camera3OutputStream(mNextStreamId, consumer,
433 width, height, size, format);
434 } else {
435 newStream = new Camera3OutputStream(mNextStreamId, consumer,
436 width, height, format);
437 }
438
439 res = mOutputStreams.add(mNextStreamId, newStream);
440 if (res < 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700441 SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800442 return res;
443 }
444
445 *id = mNextStreamId++;
446
447 // Continue captures if active at start
448 if (wasActive) {
449 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
450 res = configureStreamsLocked();
451 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700452 CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
453 mNextStreamId, strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800454 return res;
455 }
456 mRequestThread->setPaused(false);
457 }
458
459 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800460}
461
462status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
463 ATRACE_CALL();
464 (void)outputId; (void)id;
465
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700466 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800467 return INVALID_OPERATION;
468}
469
470
471status_t Camera3Device::getStreamInfo(int id,
472 uint32_t *width, uint32_t *height, uint32_t *format) {
473 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800474 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800475
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800476 switch (mStatus) {
477 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700478 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800479 return INVALID_OPERATION;
480 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700481 CLOGE("Device not initialized!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800482 return INVALID_OPERATION;
483 case STATUS_IDLE:
484 case STATUS_ACTIVE:
485 // OK
486 break;
487 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700488 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800489 return INVALID_OPERATION;
490 }
491
492 ssize_t idx = mOutputStreams.indexOfKey(id);
493 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700494 CLOGE("Stream %d is unknown", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800495 return idx;
496 }
497
498 if (width) *width = mOutputStreams[idx]->getWidth();
499 if (height) *height = mOutputStreams[idx]->getHeight();
500 if (format) *format = mOutputStreams[idx]->getFormat();
501
502 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800503}
504
505status_t Camera3Device::setStreamTransform(int id,
506 int transform) {
507 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800508 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800509
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800510 switch (mStatus) {
511 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700512 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800513 return INVALID_OPERATION;
514 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700515 CLOGE("Device not initialized");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800516 return INVALID_OPERATION;
517 case STATUS_IDLE:
518 case STATUS_ACTIVE:
519 // OK
520 break;
521 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700522 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800523 return INVALID_OPERATION;
524 }
525
526 ssize_t idx = mOutputStreams.indexOfKey(id);
527 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700528 CLOGE("Stream %d does not exist",
529 id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800530 return BAD_VALUE;
531 }
532
533 return mOutputStreams.editValueAt(idx)->setTransform(transform);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800534}
535
536status_t Camera3Device::deleteStream(int id) {
537 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800538 Mutex::Autolock l(mLock);
539 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800540
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800541 // CameraDevice semantics require device to already be idle before
542 // deleteStream is called, unlike for createStream.
543 if (mStatus != STATUS_IDLE) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700544 CLOGE("Device not idle");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800545 return INVALID_OPERATION;
546 }
547
548 sp<Camera3Stream> deletedStream;
549 if (mInputStream != NULL && id == mInputStream->getId()) {
550 deletedStream = mInputStream;
551 mInputStream.clear();
552 } else {
553 ssize_t idx = mOutputStreams.indexOfKey(id);
554 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700555 CLOGE("Stream %d does not exist", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800556 return BAD_VALUE;
557 }
558 deletedStream = mOutputStreams.editValueAt(idx);
559 mOutputStreams.removeItem(id);
560 }
561
562 // Free up the stream endpoint so that it can be used by some other stream
563 res = deletedStream->disconnect();
564 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700565 SET_ERR_L("Can't disconnect deleted stream %d", id);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800566 // fall through since we want to still list the stream as deleted.
567 }
568 mDeletedStreams.add(deletedStream);
569
570 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800571}
572
573status_t Camera3Device::deleteReprocessStream(int id) {
574 ATRACE_CALL();
575 (void)id;
576
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700577 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800578 return INVALID_OPERATION;
579}
580
581
582status_t Camera3Device::createDefaultRequest(int templateId,
583 CameraMetadata *request) {
584 ATRACE_CALL();
585 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800586 Mutex::Autolock l(mLock);
587
588 switch (mStatus) {
589 case STATUS_ERROR:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700590 CLOGE("Device has encountered a serious error");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800591 return INVALID_OPERATION;
592 case STATUS_UNINITIALIZED:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700593 CLOGE("Device is not initialized!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800594 return INVALID_OPERATION;
595 case STATUS_IDLE:
596 case STATUS_ACTIVE:
597 // OK
598 break;
599 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700600 SET_ERR_L("Unexpected status: %d", mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800601 return INVALID_OPERATION;
602 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800603
604 const camera_metadata_t *rawRequest;
605 rawRequest = mHal3Device->ops->construct_default_request_settings(
606 mHal3Device, templateId);
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700607 if (rawRequest == NULL) {
608 SET_ERR_L("HAL is unable to construct default settings for template %d",
609 templateId);
610 return DEAD_OBJECT;
611 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800612 *request = rawRequest;
613
614 return OK;
615}
616
617status_t Camera3Device::waitUntilDrained() {
618 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800619 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800620
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800621 return waitUntilDrainedLocked();
622}
623
624status_t Camera3Device::waitUntilDrainedLocked() {
625 ATRACE_CALL();
626 status_t res;
627
628 switch (mStatus) {
629 case STATUS_UNINITIALIZED:
630 case STATUS_IDLE:
631 ALOGV("%s: Already idle", __FUNCTION__);
632 return OK;
633 case STATUS_ERROR:
634 case STATUS_ACTIVE:
635 // Need to shut down
636 break;
637 default:
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700638 SET_ERR_L("Unexpected status: %d",mStatus);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800639 return INVALID_OPERATION;
640 }
641
642 if (mRequestThread != NULL) {
643 res = mRequestThread->waitUntilPaused(kShutdownTimeout);
644 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700645 SET_ERR_L("Can't stop request thread in %f seconds!",
646 kShutdownTimeout/1e9);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800647 return res;
648 }
649 }
650 if (mInputStream != NULL) {
651 res = mInputStream->waitUntilIdle(kShutdownTimeout);
652 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700653 SET_ERR_L("Can't idle input stream %d in %f seconds!",
654 mInputStream->getId(), kShutdownTimeout/1e9);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800655 return res;
656 }
657 }
658 for (size_t i = 0; i < mOutputStreams.size(); i++) {
659 res = mOutputStreams.editValueAt(i)->waitUntilIdle(kShutdownTimeout);
660 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700661 SET_ERR_L("Can't idle output stream %d in %f seconds!",
662 mOutputStreams.keyAt(i), kShutdownTimeout/1e9);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800663 return res;
664 }
665 }
666
667 if (mStatus != STATUS_ERROR) {
668 mStatus = STATUS_IDLE;
669 }
670
671 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800672}
673
674status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
675 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700676 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800677
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700678 if (listener != NULL && mListener != NULL) {
679 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
680 }
681 mListener = listener;
682
683 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800684}
685
686status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700687 ATRACE_CALL();
688 status_t res;
689 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800690
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700691 while (mResultQueue.empty()) {
692 res = mResultSignal.waitRelative(mOutputLock, timeout);
693 if (res == TIMED_OUT) {
694 return res;
695 } else if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700696 ALOGW("%s: Camera %d: No frame in %lld ns: %s (%d)",
697 __FUNCTION__, mId, timeout, strerror(-res), res);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700698 return res;
699 }
700 }
701 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800702}
703
704status_t Camera3Device::getNextFrame(CameraMetadata *frame) {
705 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700706 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800707
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700708 if (mResultQueue.empty()) {
709 return NOT_ENOUGH_DATA;
710 }
711
712 CameraMetadata &result = *(mResultQueue.begin());
713 frame->acquire(result);
714 mResultQueue.erase(mResultQueue.begin());
715
716 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800717}
718
719status_t Camera3Device::triggerAutofocus(uint32_t id) {
720 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800721
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700722 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
723 // Mix-in this trigger into the next request and only the next request.
724 RequestTrigger trigger[] = {
725 {
726 ANDROID_CONTROL_AF_TRIGGER,
727 ANDROID_CONTROL_AF_TRIGGER_START
728 },
729 {
730 ANDROID_CONTROL_AF_TRIGGER_ID,
731 static_cast<int32_t>(id)
732 },
733 };
734
735 return mRequestThread->queueTrigger(trigger,
736 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800737}
738
739status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
740 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800741
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700742 ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
743 // Mix-in this trigger into the next request and only the next request.
744 RequestTrigger trigger[] = {
745 {
746 ANDROID_CONTROL_AF_TRIGGER,
747 ANDROID_CONTROL_AF_TRIGGER_CANCEL
748 },
749 {
750 ANDROID_CONTROL_AF_TRIGGER_ID,
751 static_cast<int32_t>(id)
752 },
753 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800754
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700755 return mRequestThread->queueTrigger(trigger,
756 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800757}
758
759status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
760 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800761
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700762 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
763 // Mix-in this trigger into the next request and only the next request.
764 RequestTrigger trigger[] = {
765 {
766 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
767 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
768 },
769 {
770 ANDROID_CONTROL_AE_PRECAPTURE_ID,
771 static_cast<int32_t>(id)
772 },
773 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800774
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700775 return mRequestThread->queueTrigger(trigger,
776 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800777}
778
779status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
780 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
781 ATRACE_CALL();
782 (void)reprocessStreamId; (void)buffer; (void)listener;
783
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700784 CLOGE("Unimplemented");
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800785 return INVALID_OPERATION;
786}
787
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800788/**
789 * Camera3Device private methods
790 */
791
792sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
793 const CameraMetadata &request) {
794 ATRACE_CALL();
795 status_t res;
796
797 sp<CaptureRequest> newRequest = new CaptureRequest;
798 newRequest->mSettings = request;
799
800 camera_metadata_entry_t inputStreams =
801 newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
802 if (inputStreams.count > 0) {
803 if (mInputStream == NULL ||
804 mInputStream->getId() != inputStreams.data.u8[0]) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700805 CLOGE("Request references unknown input stream %d",
806 inputStreams.data.u8[0]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800807 return NULL;
808 }
809 // Lazy completion of stream configuration (allocation/registration)
810 // on first use
811 if (mInputStream->isConfiguring()) {
812 res = mInputStream->finishConfiguration(mHal3Device);
813 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700814 SET_ERR_L("Unable to finish configuring input stream %d:"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800815 " %s (%d)",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700816 mInputStream->getId(), strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800817 return NULL;
818 }
819 }
820
821 newRequest->mInputStream = mInputStream;
822 newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
823 }
824
825 camera_metadata_entry_t streams =
826 newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
827 if (streams.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700828 CLOGE("Zero output streams specified!");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800829 return NULL;
830 }
831
832 for (size_t i = 0; i < streams.count; i++) {
833 int idx = mOutputStreams.indexOfKey(streams.data.u8[i]);
834 if (idx == NAME_NOT_FOUND) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700835 CLOGE("Request references unknown stream %d",
836 streams.data.u8[i]);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800837 return NULL;
838 }
839 sp<Camera3OutputStream> stream = mOutputStreams.editValueAt(idx);
840
841 // Lazy completion of stream configuration (allocation/registration)
842 // on first use
843 if (stream->isConfiguring()) {
844 res = stream->finishConfiguration(mHal3Device);
845 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700846 SET_ERR_L("Unable to finish configuring stream %d: %s (%d)",
847 stream->getId(), strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800848 return NULL;
849 }
850 }
851
852 newRequest->mOutputStreams.push(stream);
853 }
854 newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
855
856 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800857}
858
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800859status_t Camera3Device::configureStreamsLocked() {
860 ATRACE_CALL();
861 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800862
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800863 if (mStatus != STATUS_IDLE) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700864 CLOGE("Not idle");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800865 return INVALID_OPERATION;
866 }
867
868 // Start configuring the streams
869
870 camera3_stream_configuration config;
871
872 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
873
874 Vector<camera3_stream_t*> streams;
875 streams.setCapacity(config.num_streams);
876
877 if (mInputStream != NULL) {
878 camera3_stream_t *inputStream;
879 inputStream = mInputStream->startConfiguration();
880 if (inputStream == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700881 SET_ERR_L("Can't start input stream configuration");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800882 return INVALID_OPERATION;
883 }
884 streams.add(inputStream);
885 }
886
887 for (size_t i = 0; i < mOutputStreams.size(); i++) {
888 camera3_stream_t *outputStream;
889 outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
890 if (outputStream == NULL) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700891 SET_ERR_L("Can't start output stream configuration");
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800892 return INVALID_OPERATION;
893 }
894 streams.add(outputStream);
895 }
896
897 config.streams = streams.editArray();
898
899 // Do the HAL configuration; will potentially touch stream
900 // max_buffers, usage, priv fields.
901
902 res = mHal3Device->ops->configure_streams(mHal3Device, &config);
903
904 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700905 SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
906 strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800907 return res;
908 }
909
910 // Request thread needs to know to avoid using repeat-last-settings protocol
911 // across configure_streams() calls
912 mRequestThread->configurationComplete();
913
914 // Finish configuring the streams lazily on first reference
915
916 mStatus = STATUS_ACTIVE;
917
918 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800919}
920
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700921void Camera3Device::setErrorState(const char *fmt, ...) {
922 Mutex::Autolock l(mLock);
923 va_list args;
924 va_start(args, fmt);
925
926 setErrorStateLockedV(fmt, args);
927
928 va_end(args);
929}
930
931void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
932 Mutex::Autolock l(mLock);
933 setErrorStateLockedV(fmt, args);
934}
935
936void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
937 va_list args;
938 va_start(args, fmt);
939
940 setErrorStateLockedV(fmt, args);
941
942 va_end(args);
943}
944
945void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700946 // Print out all error messages to log
947 String8 errorCause = String8::formatV(fmt, args);
948 ALOGE("Camera %d: %s", mId, errorCause.string());
949
950 // But only do error state transition steps for the first error
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700951 if (mStatus == STATUS_ERROR) return;
952
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700953 mErrorCause = errorCause;
954
955 mRequestThread->setPaused(true);
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -0700956 mStatus = STATUS_ERROR;
957}
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800958
959/**
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700960 * In-flight request management
961 */
962
963status_t Camera3Device::registerInFlight(int32_t frameNumber,
964 int32_t numBuffers) {
965 ATRACE_CALL();
966 Mutex::Autolock l(mInFlightLock);
967
968 ssize_t res;
969 res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers));
970 if (res < 0) return res;
971
972 return OK;
973}
974
975/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800976 * Camera HAL device callback methods
977 */
978
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800979void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700980 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800981
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700982 status_t res;
983
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700984 uint32_t frameNumber = result->frame_number;
985 if (result->result == NULL && result->num_output_buffers == 0) {
986 SET_ERR("No result data provided by HAL for frame %d",
987 frameNumber);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700988 return;
989 }
990
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700991 // Get capture timestamp from list of in-flight requests, where it was added
992 // by the shutter notification for this frame. Then update the in-flight
993 // status and remove the in-flight entry if all result data has been
994 // received.
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700995 nsecs_t timestamp = 0;
Eino-Ville Talvala42368d92013-04-09 14:13:50 -0700996 {
997 Mutex::Autolock l(mInFlightLock);
998 ssize_t idx = mInFlightMap.indexOfKey(frameNumber);
999 if (idx == NAME_NOT_FOUND) {
1000 SET_ERR("Unknown frame number for capture result: %d",
1001 frameNumber);
1002 return;
1003 }
1004 InFlightRequest &request = mInFlightMap.editValueAt(idx);
1005 timestamp = request.captureTimestamp;
1006 if (timestamp == 0) {
1007 SET_ERR("Called before shutter notify for frame %d",
1008 frameNumber);
1009 return;
1010 }
1011
1012 if (result->result != NULL) {
1013 if (request.haveResultMetadata) {
1014 SET_ERR("Called multiple times with metadata for frame %d",
1015 frameNumber);
1016 return;
1017 }
1018 request.haveResultMetadata = true;
1019 }
1020
1021 request.numBuffersLeft -= result->num_output_buffers;
1022
1023 if (request.numBuffersLeft < 0) {
1024 SET_ERR("Too many buffers returned for frame %d",
1025 frameNumber);
1026 return;
1027 }
1028
1029 if (request.haveResultMetadata && request.numBuffersLeft == 0) {
1030 mInFlightMap.removeItemsAt(idx, 1);
1031 }
1032
1033 // Sanity check - if we have too many in-flight frames, something has
1034 // likely gone wrong
1035 if (mInFlightMap.size() > kInFlightWarnLimit) {
1036 CLOGE("In-flight list too large: %d", mInFlightMap.size());
1037 }
1038
1039 }
1040
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001041 AlgState cur3aState;
1042 AlgState new3aState;
1043 int32_t aeTriggerId = 0;
1044 int32_t afTriggerId = 0;
1045
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001046 NotificationListener *listener = NULL;
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001047
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001048 // Process the result metadata, if provided
1049 if (result->result != NULL) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001050 Mutex::Autolock l(mOutputLock);
1051
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001052 if (frameNumber != mNextResultFrameNumber) {
1053 SET_ERR("Out-of-order capture result metadata submitted! "
1054 "(got frame number %d, expecting %d)",
1055 frameNumber, mNextResultFrameNumber);
1056 return;
1057 }
1058 mNextResultFrameNumber++;
1059
1060 CameraMetadata &captureResult =
1061 *mResultQueue.insert(mResultQueue.end(), CameraMetadata());
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001062
1063 captureResult = result->result;
Igor Murashkind2c90692013-04-02 12:32:32 -07001064 if (captureResult.update(ANDROID_REQUEST_FRAME_COUNT,
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001065 (int32_t*)&frameNumber, 1) != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001066 SET_ERR("Failed to set frame# in metadata (%d)",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001067 frameNumber);
Igor Murashkind2c90692013-04-02 12:32:32 -07001068 } else {
1069 ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001070 __FUNCTION__, mId, frameNumber);
Igor Murashkind2c90692013-04-02 12:32:32 -07001071 }
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001072
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001073 // Check that there's a timestamp in the result metadata
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001074
1075 camera_metadata_entry entry =
1076 captureResult.find(ANDROID_SENSOR_TIMESTAMP);
1077 if (entry.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001078 SET_ERR("No timestamp provided by HAL for frame %d!",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001079 frameNumber);
1080 }
1081 if (timestamp != entry.data.i64[0]) {
1082 SET_ERR("Timestamp mismatch between shutter notify and result"
1083 " metadata for frame %d (%lld vs %lld respectively)",
1084 frameNumber, timestamp, entry.data.i64[0]);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001085 }
1086
1087 // Get 3A states from result metadata
1088
1089 entry = captureResult.find(ANDROID_CONTROL_AE_STATE);
1090 if (entry.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001091 CLOGE("No AE state provided by HAL for frame %d!",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001092 frameNumber);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001093 } else {
1094 new3aState.aeState =
1095 static_cast<camera_metadata_enum_android_control_ae_state>(
1096 entry.data.u8[0]);
1097 }
1098
1099 entry = captureResult.find(ANDROID_CONTROL_AF_STATE);
1100 if (entry.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001101 CLOGE("No AF state provided by HAL for frame %d!",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001102 frameNumber);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001103 } else {
1104 new3aState.afState =
1105 static_cast<camera_metadata_enum_android_control_af_state>(
1106 entry.data.u8[0]);
1107 }
1108
1109 entry = captureResult.find(ANDROID_CONTROL_AWB_STATE);
1110 if (entry.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001111 CLOGE("No AWB state provided by HAL for frame %d!",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001112 frameNumber);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001113 } else {
1114 new3aState.awbState =
1115 static_cast<camera_metadata_enum_android_control_awb_state>(
1116 entry.data.u8[0]);
1117 }
1118
1119 entry = captureResult.find(ANDROID_CONTROL_AF_TRIGGER_ID);
1120 if (entry.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001121 CLOGE("No AF trigger ID provided by HAL for frame %d!",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001122 frameNumber);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001123 } else {
1124 afTriggerId = entry.data.i32[0];
1125 }
1126
1127 entry = captureResult.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
1128 if (entry.count == 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001129 CLOGE("No AE precapture trigger ID provided by HAL"
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001130 " for frame %d!", frameNumber);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001131 } else {
1132 aeTriggerId = entry.data.i32[0];
1133 }
1134
1135 listener = mListener;
1136 cur3aState = m3AState;
1137
1138 m3AState = new3aState;
1139 } // scope for mOutputLock
1140
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001141 // Return completed buffers to their streams with the timestamp
1142
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001143 for (size_t i = 0; i < result->num_output_buffers; i++) {
1144 Camera3Stream *stream =
1145 Camera3Stream::cast(result->output_buffers[i].stream);
1146 res = stream->returnBuffer(result->output_buffers[i], timestamp);
1147 // Note: stream may be deallocated at this point, if this buffer was the
1148 // last reference to it.
1149 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001150 SET_ERR("Can't return buffer %d for frame %d to its stream: "
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001151 " %s (%d)", i, frameNumber, strerror(-res), res);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001152 }
1153 }
1154
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001155 // Finally, dispatch any 3A change events to listeners if we got metadata
1156
1157 if (result->result != NULL && listener != NULL) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001158 if (new3aState.aeState != cur3aState.aeState) {
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001159 ALOGVV("%s: AE state changed from 0x%x to 0x%x",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001160 __FUNCTION__, cur3aState.aeState, new3aState.aeState);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001161 listener->notifyAutoExposure(new3aState.aeState, aeTriggerId);
1162 }
1163 if (new3aState.afState != cur3aState.afState) {
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001164 ALOGVV("%s: AF state changed from 0x%x to 0x%x",
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001165 __FUNCTION__, cur3aState.afState, new3aState.afState);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001166 listener->notifyAutoFocus(new3aState.afState, afTriggerId);
1167 }
1168 if (new3aState.awbState != cur3aState.awbState) {
1169 listener->notifyAutoWhitebalance(new3aState.awbState, aeTriggerId);
1170 }
1171 }
1172
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001173}
1174
1175void Camera3Device::notify(const camera3_notify_msg *msg) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001176 NotificationListener *listener;
1177 {
1178 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001179 listener = mListener;
1180 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001181
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001182 if (msg == NULL) {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001183 SET_ERR("HAL sent NULL notify message!");
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001184 return;
1185 }
1186
1187 switch (msg->type) {
1188 case CAMERA3_MSG_ERROR: {
1189 int streamId = 0;
1190 if (msg->message.error.error_stream != NULL) {
1191 Camera3Stream *stream =
1192 Camera3Stream::cast(
1193 msg->message.error.error_stream);
1194 streamId = stream->getId();
1195 }
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001196 if (listener != NULL) {
1197 listener->notifyError(msg->message.error.error_code,
1198 msg->message.error.frame_number, streamId);
1199 }
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001200 break;
1201 }
1202 case CAMERA3_MSG_SHUTTER: {
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001203 ssize_t idx;
1204 uint32_t frameNumber = msg->message.shutter.frame_number;
1205 nsecs_t timestamp = msg->message.shutter.timestamp;
1206 // Verify ordering of shutter notifications
1207 {
1208 Mutex::Autolock l(mOutputLock);
1209 if (frameNumber != mNextShutterFrameNumber) {
1210 SET_ERR("Shutter notification out-of-order. Expected "
1211 "notification for frame %d, got frame %d",
1212 mNextShutterFrameNumber, frameNumber);
1213 break;
1214 }
1215 mNextShutterFrameNumber++;
1216 }
1217
1218 // Set timestamp for the request in the in-flight tracking
1219 {
1220 Mutex::Autolock l(mInFlightLock);
1221 idx = mInFlightMap.indexOfKey(frameNumber);
1222 if (idx >= 0) {
1223 mInFlightMap.editValueAt(idx).captureTimestamp = timestamp;
1224 }
1225 }
1226 if (idx < 0) {
1227 SET_ERR("Shutter notification for non-existent frame number %d",
1228 frameNumber);
1229 break;
1230 }
1231
1232 // Call listener, if any
1233 if (listener != NULL) {
1234 listener->notifyShutter(frameNumber, timestamp);
1235 }
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001236 break;
1237 }
1238 default:
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001239 SET_ERR("Unknown notify message from HAL: %d",
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001240 msg->type);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001241 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001242}
1243
1244/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001245 * RequestThread inner class methods
1246 */
1247
1248Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
1249 camera3_device_t *hal3Device) :
1250 Thread(false),
1251 mParent(parent),
1252 mHal3Device(hal3Device),
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001253 mId(getId(parent)),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001254 mReconfigured(false),
1255 mDoPause(false),
1256 mPaused(true),
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001257 mFrameNumber(0),
1258 mLatestRequestId(NAME_NOT_FOUND) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001259}
1260
1261void Camera3Device::RequestThread::configurationComplete() {
1262 Mutex::Autolock l(mRequestLock);
1263 mReconfigured = true;
1264}
1265
1266status_t Camera3Device::RequestThread::queueRequest(
1267 sp<CaptureRequest> request) {
1268 Mutex::Autolock l(mRequestLock);
1269 mRequestQueue.push_back(request);
1270
1271 return OK;
1272}
1273
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001274
1275status_t Camera3Device::RequestThread::queueTrigger(
1276 RequestTrigger trigger[],
1277 size_t count) {
1278
1279 Mutex::Autolock l(mTriggerMutex);
1280 status_t ret;
1281
1282 for (size_t i = 0; i < count; ++i) {
1283 ret = queueTriggerLocked(trigger[i]);
1284
1285 if (ret != OK) {
1286 return ret;
1287 }
1288 }
1289
1290 return OK;
1291}
1292
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001293int Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
1294 sp<Camera3Device> d = device.promote();
1295 if (d != NULL) return d->mId;
1296 return 0;
1297}
1298
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001299status_t Camera3Device::RequestThread::queueTriggerLocked(
1300 RequestTrigger trigger) {
1301
1302 uint32_t tag = trigger.metadataTag;
1303 ssize_t index = mTriggerMap.indexOfKey(tag);
1304
1305 switch (trigger.getTagType()) {
1306 case TYPE_BYTE:
1307 // fall-through
1308 case TYPE_INT32:
1309 break;
1310 default:
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001311 ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
1312 trigger.getTagType());
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001313 return INVALID_OPERATION;
1314 }
1315
1316 /**
1317 * Collect only the latest trigger, since we only have 1 field
1318 * in the request settings per trigger tag, and can't send more than 1
1319 * trigger per request.
1320 */
1321 if (index != NAME_NOT_FOUND) {
1322 mTriggerMap.editValueAt(index) = trigger;
1323 } else {
1324 mTriggerMap.add(tag, trigger);
1325 }
1326
1327 return OK;
1328}
1329
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001330status_t Camera3Device::RequestThread::setRepeatingRequests(
1331 const RequestList &requests) {
1332 Mutex::Autolock l(mRequestLock);
1333 mRepeatingRequests.clear();
1334 mRepeatingRequests.insert(mRepeatingRequests.begin(),
1335 requests.begin(), requests.end());
1336 return OK;
1337}
1338
1339status_t Camera3Device::RequestThread::clearRepeatingRequests() {
1340 Mutex::Autolock l(mRequestLock);
1341 mRepeatingRequests.clear();
1342 return OK;
1343}
1344
1345void Camera3Device::RequestThread::setPaused(bool paused) {
1346 Mutex::Autolock l(mPauseLock);
1347 mDoPause = paused;
1348 mDoPauseSignal.signal();
1349}
1350
1351status_t Camera3Device::RequestThread::waitUntilPaused(nsecs_t timeout) {
1352 status_t res;
1353 Mutex::Autolock l(mPauseLock);
1354 while (!mPaused) {
1355 res = mPausedSignal.waitRelative(mPauseLock, timeout);
1356 if (res == TIMED_OUT) {
1357 return res;
1358 }
1359 }
1360 return OK;
1361}
1362
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001363status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
1364 int32_t requestId, nsecs_t timeout) {
1365 Mutex::Autolock l(mLatestRequestMutex);
1366 status_t res;
1367 while (mLatestRequestId != requestId) {
1368 nsecs_t startTime = systemTime();
1369
1370 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
1371 if (res != OK) return res;
1372
1373 timeout -= (systemTime() - startTime);
1374 }
1375
1376 return OK;
1377}
1378
1379
1380
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001381bool Camera3Device::RequestThread::threadLoop() {
1382
1383 status_t res;
1384
1385 // Handle paused state.
1386 if (waitIfPaused()) {
1387 return true;
1388 }
1389
1390 // Get work to do
1391
1392 sp<CaptureRequest> nextRequest = waitForNextRequest();
1393 if (nextRequest == NULL) {
1394 return true;
1395 }
1396
1397 // Create request to HAL
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001398 camera3_capture_request_t request = camera3_capture_request_t();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001399 Vector<camera3_stream_buffer_t> outputBuffers;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001400
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001401 // Insert any queued triggers (before metadata is locked)
1402 int32_t triggerCount;
1403 res = insertTriggers(nextRequest);
1404 if (res < 0) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001405 SET_ERR("RequestThread: Unable to insert triggers "
1406 "(capture request %d, HAL device: %s (%d)",
1407 (mFrameNumber+1), strerror(-res), res);
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001408 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1409 return false;
1410 }
1411 triggerCount = res;
1412
1413 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
1414
1415 // If the request is the same as last, or we had triggers last time
1416 if (mPrevRequest != nextRequest || triggersMixedIn) {
1417 /**
1418 * The request should be presorted so accesses in HAL
1419 * are O(logn). Sidenote, sorting a sorted metadata is nop.
1420 */
1421 nextRequest->mSettings.sort();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001422 request.settings = nextRequest->mSettings.getAndLock();
1423 mPrevRequest = nextRequest;
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001424 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
1425
1426 IF_ALOGV() {
1427 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
1428 find_camera_metadata_ro_entry(
1429 request.settings,
1430 ANDROID_CONTROL_AF_TRIGGER,
1431 &e
1432 );
1433 if (e.count > 0) {
1434 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
1435 __FUNCTION__,
1436 mFrameNumber+1,
1437 e.data.u8[0]);
1438 }
1439 }
1440 } else {
1441 // leave request.settings NULL to indicate 'reuse latest given'
1442 ALOGVV("%s: Request settings are REUSED",
1443 __FUNCTION__);
1444 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001445
1446 camera3_stream_buffer_t inputBuffer;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001447
1448 // Fill in buffers
1449
1450 if (nextRequest->mInputStream != NULL) {
1451 request.input_buffer = &inputBuffer;
1452 res = nextRequest->mInputStream->getBuffer(&inputBuffer);
1453 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001454 SET_ERR("RequestThread: Can't get input buffer, skipping request:"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001455 " %s (%d)", strerror(-res), res);
1456 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1457 return true;
1458 }
1459 } else {
1460 request.input_buffer = NULL;
1461 }
1462
1463 outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
1464 nextRequest->mOutputStreams.size());
1465 request.output_buffers = outputBuffers.array();
1466 for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
1467 res = nextRequest->mOutputStreams.editItemAt(i)->
1468 getBuffer(&outputBuffers.editItemAt(i));
1469 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001470 SET_ERR("RequestThread: Can't get output buffer, skipping request:"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001471 "%s (%d)", strerror(-res), res);
1472 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1473 return true;
1474 }
1475 request.num_output_buffers++;
1476 }
1477
1478 request.frame_number = mFrameNumber++;
1479
Eino-Ville Talvala42368d92013-04-09 14:13:50 -07001480 // Log request in the in-flight queue
1481 sp<Camera3Device> parent = mParent.promote();
1482 if (parent == NULL) {
1483 CLOGE("RequestThread: Parent is gone");
1484 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1485 return false;
1486 }
1487
1488 res = parent->registerInFlight(request.frame_number,
1489 request.num_output_buffers);
1490 if (res != OK) {
1491 SET_ERR("RequestThread: Unable to register new in-flight request:"
1492 " %s (%d)", strerror(-res), res);
1493 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1494 return false;
1495 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001496
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001497 // Submit request and block until ready for next one
1498
1499 res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
1500 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001501 SET_ERR("RequestThread: Unable to submit capture request %d to HAL"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001502 " device: %s (%d)", request.frame_number, strerror(-res), res);
1503 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1504 return false;
1505 }
1506
1507 if (request.settings != NULL) {
1508 nextRequest->mSettings.unlock(request.settings);
1509 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001510
1511 // Remove any previously queued triggers (after unlock)
1512 res = removeTriggers(mPrevRequest);
1513 if (res != OK) {
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001514 SET_ERR("RequestThread: Unable to remove triggers "
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001515 "(capture request %d, HAL device: %s (%d)",
1516 request.frame_number, strerror(-res), res);
1517 return false;
1518 }
1519 mPrevTriggers = triggerCount;
1520
1521 // Read android.request.id from the request settings metadata
1522 // - inform waitUntilRequestProcessed thread of a new request ID
1523 {
1524 Mutex::Autolock al(mLatestRequestMutex);
1525
1526 camera_metadata_entry_t requestIdEntry =
1527 nextRequest->mSettings.find(ANDROID_REQUEST_ID);
1528 if (requestIdEntry.count > 0) {
1529 mLatestRequestId = requestIdEntry.data.i32[0];
1530 } else {
1531 ALOGW("%s: Did not have android.request.id set in the request",
1532 __FUNCTION__);
1533 mLatestRequestId = NAME_NOT_FOUND;
1534 }
1535
1536 mLatestRequestSignal.signal();
1537 }
1538
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001539 return true;
1540}
1541
1542void Camera3Device::RequestThread::cleanUpFailedRequest(
1543 camera3_capture_request_t &request,
1544 sp<CaptureRequest> &nextRequest,
1545 Vector<camera3_stream_buffer_t> &outputBuffers) {
1546
1547 if (request.settings != NULL) {
1548 nextRequest->mSettings.unlock(request.settings);
1549 }
1550 if (request.input_buffer != NULL) {
1551 request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
1552 nextRequest->mInputStream->returnBuffer(*(request.input_buffer), 0);
1553 }
1554 for (size_t i = 0; i < request.num_output_buffers; i++) {
1555 outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
1556 nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
1557 outputBuffers[i], 0);
1558 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001559}
1560
1561sp<Camera3Device::CaptureRequest>
1562 Camera3Device::RequestThread::waitForNextRequest() {
1563 status_t res;
1564 sp<CaptureRequest> nextRequest;
1565
1566 // Optimized a bit for the simple steady-state case (single repeating
1567 // request), to avoid putting that request in the queue temporarily.
1568 Mutex::Autolock l(mRequestLock);
1569
1570 while (mRequestQueue.empty()) {
1571 if (!mRepeatingRequests.empty()) {
1572 // Always atomically enqueue all requests in a repeating request
1573 // list. Guarantees a complete in-sequence set of captures to
1574 // application.
1575 const RequestList &requests = mRepeatingRequests;
1576 RequestList::const_iterator firstRequest =
1577 requests.begin();
1578 nextRequest = *firstRequest;
1579 mRequestQueue.insert(mRequestQueue.end(),
1580 ++firstRequest,
1581 requests.end());
1582 // No need to wait any longer
1583 break;
1584 }
1585
1586 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
1587
1588 if (res == TIMED_OUT) {
1589 // Signal that we're paused by starvation
1590 Mutex::Autolock pl(mPauseLock);
1591 if (mPaused == false) {
1592 mPaused = true;
1593 mPausedSignal.signal();
1594 }
1595 // Stop waiting for now and let thread management happen
1596 return NULL;
1597 }
1598 }
1599
1600 if (nextRequest == NULL) {
1601 // Don't have a repeating request already in hand, so queue
1602 // must have an entry now.
1603 RequestList::iterator firstRequest =
1604 mRequestQueue.begin();
1605 nextRequest = *firstRequest;
1606 mRequestQueue.erase(firstRequest);
1607 }
1608
1609 // Not paused
1610 Mutex::Autolock pl(mPauseLock);
1611 mPaused = false;
1612
1613 // Check if we've reconfigured since last time, and reset the preview
1614 // request if so. Can't use 'NULL request == repeat' across configure calls.
1615 if (mReconfigured) {
1616 mPrevRequest.clear();
1617 mReconfigured = false;
1618 }
1619
1620 return nextRequest;
1621}
1622
1623bool Camera3Device::RequestThread::waitIfPaused() {
1624 status_t res;
1625 Mutex::Autolock l(mPauseLock);
1626 while (mDoPause) {
1627 // Signal that we're paused by request
1628 if (mPaused == false) {
1629 mPaused = true;
1630 mPausedSignal.signal();
1631 }
1632 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
1633 if (res == TIMED_OUT) {
1634 return true;
1635 }
1636 }
1637 // We don't set mPaused to false here, because waitForNextRequest needs
1638 // to further manage the paused state in case of starvation.
1639 return false;
1640}
1641
Eino-Ville Talvalab2058d12013-04-09 13:49:56 -07001642void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
1643 sp<Camera3Device> parent = mParent.promote();
1644 if (parent != NULL) {
1645 va_list args;
1646 va_start(args, fmt);
1647
1648 parent->setErrorStateV(fmt, args);
1649
1650 va_end(args);
1651 }
1652}
1653
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001654status_t Camera3Device::RequestThread::insertTriggers(
1655 const sp<CaptureRequest> &request) {
1656
1657 Mutex::Autolock al(mTriggerMutex);
1658
1659 CameraMetadata &metadata = request->mSettings;
1660 size_t count = mTriggerMap.size();
1661
1662 for (size_t i = 0; i < count; ++i) {
1663 RequestTrigger trigger = mTriggerMap.valueAt(i);
1664
1665 uint32_t tag = trigger.metadataTag;
1666 camera_metadata_entry entry = metadata.find(tag);
1667
1668 if (entry.count > 0) {
1669 /**
1670 * Already has an entry for this trigger in the request.
1671 * Rewrite it with our requested trigger value.
1672 */
1673 RequestTrigger oldTrigger = trigger;
1674
1675 oldTrigger.entryValue = entry.data.u8[0];
1676
1677 mTriggerReplacedMap.add(tag, oldTrigger);
1678 } else {
1679 /**
1680 * More typical, no trigger entry, so we just add it
1681 */
1682 mTriggerRemovedMap.add(tag, trigger);
1683 }
1684
1685 status_t res;
1686
1687 switch (trigger.getTagType()) {
1688 case TYPE_BYTE: {
1689 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
1690 res = metadata.update(tag,
1691 &entryValue,
1692 /*count*/1);
1693 break;
1694 }
1695 case TYPE_INT32:
1696 res = metadata.update(tag,
1697 &trigger.entryValue,
1698 /*count*/1);
1699 break;
1700 default:
1701 ALOGE("%s: Type not supported: 0x%x",
1702 __FUNCTION__,
1703 trigger.getTagType());
1704 return INVALID_OPERATION;
1705 }
1706
1707 if (res != OK) {
1708 ALOGE("%s: Failed to update request metadata with trigger tag %s"
1709 ", value %d", __FUNCTION__, trigger.getTagName(),
1710 trigger.entryValue);
1711 return res;
1712 }
1713
1714 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
1715 trigger.getTagName(),
1716 trigger.entryValue);
1717 }
1718
1719 mTriggerMap.clear();
1720
1721 return count;
1722}
1723
1724status_t Camera3Device::RequestThread::removeTriggers(
1725 const sp<CaptureRequest> &request) {
1726 Mutex::Autolock al(mTriggerMutex);
1727
1728 CameraMetadata &metadata = request->mSettings;
1729
1730 /**
1731 * Replace all old entries with their old values.
1732 */
1733 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
1734 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
1735
1736 status_t res;
1737
1738 uint32_t tag = trigger.metadataTag;
1739 switch (trigger.getTagType()) {
1740 case TYPE_BYTE: {
1741 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
1742 res = metadata.update(tag,
1743 &entryValue,
1744 /*count*/1);
1745 break;
1746 }
1747 case TYPE_INT32:
1748 res = metadata.update(tag,
1749 &trigger.entryValue,
1750 /*count*/1);
1751 break;
1752 default:
1753 ALOGE("%s: Type not supported: 0x%x",
1754 __FUNCTION__,
1755 trigger.getTagType());
1756 return INVALID_OPERATION;
1757 }
1758
1759 if (res != OK) {
1760 ALOGE("%s: Failed to restore request metadata with trigger tag %s"
1761 ", trigger value %d", __FUNCTION__,
1762 trigger.getTagName(), trigger.entryValue);
1763 return res;
1764 }
1765 }
1766 mTriggerReplacedMap.clear();
1767
1768 /**
1769 * Remove all new entries.
1770 */
1771 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
1772 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
1773 status_t res = metadata.erase(trigger.metadataTag);
1774
1775 if (res != OK) {
1776 ALOGE("%s: Failed to erase metadata with trigger tag %s"
1777 ", trigger value %d", __FUNCTION__,
1778 trigger.getTagName(), trigger.entryValue);
1779 return res;
1780 }
1781 }
1782 mTriggerRemovedMap.clear();
1783
1784 return OK;
1785}
1786
1787
1788
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001789/**
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001790 * Static callback forwarding methods from HAL to instance
1791 */
1792
1793void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
1794 const camera3_capture_result *result) {
1795 Camera3Device *d =
1796 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1797 d->processCaptureResult(result);
1798}
1799
1800void Camera3Device::sNotify(const camera3_callback_ops *cb,
1801 const camera3_notify_msg *msg) {
1802 Camera3Device *d =
1803 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1804 d->notify(msg);
1805}
1806
1807}; // namespace android