blob: e53dbb5a34572619a30cf2687f4eb940eaae17f4 [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
28#include <utils/Log.h>
29#include <utils/Trace.h>
30#include <utils/Timers.h>
31#include "Camera3Device.h"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080032#include "camera3/Camera3OutputStream.h"
33
34using namespace android::camera3;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080035
36namespace android {
37
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080038Camera3Device::Camera3Device(int id):
39 mId(id),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080040 mHal3Device(NULL),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070041 mStatus(STATUS_UNINITIALIZED),
42 mListener(NULL)
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080043{
44 ATRACE_CALL();
45 camera3_callback_ops::notify = &sNotify;
46 camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
47 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
48}
49
50Camera3Device::~Camera3Device()
51{
52 ATRACE_CALL();
53 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
54 disconnect();
55}
56
Igor Murashkin71381052013-03-04 14:53:08 -080057int Camera3Device::getId() const {
58 return mId;
59}
60
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080061/**
62 * CameraDeviceBase interface
63 */
64
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080065status_t Camera3Device::initialize(camera_module_t *module)
66{
67 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080068 Mutex::Autolock l(mLock);
69
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080070 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080071 if (mStatus != STATUS_UNINITIALIZED) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080072 ALOGE("%s: Already initialized!", __FUNCTION__);
73 return INVALID_OPERATION;
74 }
75
76 /** Open HAL device */
77
78 status_t res;
79 String8 deviceName = String8::format("%d", mId);
80
81 camera3_device_t *device;
82
83 res = module->common.methods->open(&module->common, deviceName.string(),
84 reinterpret_cast<hw_device_t**>(&device));
85
86 if (res != OK) {
87 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
88 mId, strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080089 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080090 return res;
91 }
92
93 /** Cross-check device version */
94
95 if (device->common.version != CAMERA_DEVICE_API_VERSION_3_0) {
96 ALOGE("%s: Could not open camera %d: "
97 "Camera device is not version %x, reports %x instead",
98 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_3_0,
99 device->common.version);
100 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800101 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800102 return BAD_VALUE;
103 }
104
105 camera_info info;
106 res = module->get_camera_info(mId, &info);
107 if (res != OK) return res;
108
109 if (info.device_version != device->common.version) {
110 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
111 " and device version (%x).", __FUNCTION__,
112 device->common.version, info.device_version);
113 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800114 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800115 return BAD_VALUE;
116 }
117
118 /** Initialize device with callback functions */
119
120 res = device->ops->initialize(device, this);
121 if (res != OK) {
122 ALOGE("%s: Camera %d: Unable to initialize HAL device: %s (%d)",
123 __FUNCTION__, mId, strerror(-res), res);
124 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800125 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800126 return BAD_VALUE;
127 }
128
129 /** Get vendor metadata tags */
130
131 mVendorTagOps.get_camera_vendor_section_name = NULL;
132
133 device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
134
135 if (mVendorTagOps.get_camera_vendor_section_name != NULL) {
136 res = set_camera_metadata_vendor_tag_ops(&mVendorTagOps);
137 if (res != OK) {
138 ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
139 __FUNCTION__, mId, strerror(-res), res);
140 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800141 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800142 return res;
143 }
144 }
145
146 /** Start up request queue thread */
147
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800148 mRequestThread = new RequestThread(this, device);
149 res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800150 if (res != OK) {
151 ALOGE("%s: Camera %d: Unable to start request queue thread: %s (%d)",
152 __FUNCTION__, mId, strerror(-res), res);
153 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800154 mRequestThread.clear();
155 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800156 return res;
157 }
158
159 /** Everything is good to go */
160
161 mDeviceInfo = info.static_camera_characteristics;
162 mHal3Device = device;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800163 mStatus = STATUS_IDLE;
164 mNextStreamId = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800165
166 return OK;
167}
168
169status_t Camera3Device::disconnect() {
170 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800171 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800172
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800173 ALOGV("%s: E", __FUNCTION__);
174
175 status_t res;
176 if (mStatus == STATUS_UNINITIALIZED) return OK;
177
178 if (mStatus == STATUS_ACTIVE ||
179 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
180 res = mRequestThread->clearRepeatingRequests();
181 if (res != OK) {
182 ALOGE("%s: Can't stop streaming", __FUNCTION__);
183 return res;
184 }
185 res = waitUntilDrainedLocked();
186 if (res != OK) {
187 ALOGE("%s: Timeout waiting for HAL to drain", __FUNCTION__);
188 return res;
189 }
190 }
191 assert(mStatus == STATUS_IDLE || mStatus == STATUS_ERROR);
192
193 if (mRequestThread != NULL) {
194 mRequestThread->requestExit();
195 }
196
197 mOutputStreams.clear();
198 mInputStream.clear();
199
200 if (mRequestThread != NULL) {
201 mRequestThread->join();
202 mRequestThread.clear();
203 }
204
205 if (mHal3Device != NULL) {
206 mHal3Device->common.close(&mHal3Device->common);
207 mHal3Device = NULL;
208 }
209
210 mStatus = STATUS_UNINITIALIZED;
211
212 ALOGV("%s: X", __FUNCTION__);
213 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800214}
215
216status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
217 ATRACE_CALL();
218 (void)args;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800219 String8 lines;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800220
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800221 const char *status =
222 mStatus == STATUS_ERROR ? "ERROR" :
223 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
224 mStatus == STATUS_IDLE ? "IDLE" :
225 mStatus == STATUS_ACTIVE ? "ACTIVE" :
226 "Unknown";
227 lines.appendFormat(" Device status: %s\n", status);
228 lines.appendFormat(" Stream configuration:\n");
229
230 if (mInputStream != NULL) {
231 write(fd, lines.string(), lines.size());
232 mInputStream->dump(fd, args);
233 } else {
234 lines.appendFormat(" No input stream.\n");
235 write(fd, lines.string(), lines.size());
236 }
237 for (size_t i = 0; i < mOutputStreams.size(); i++) {
238 mOutputStreams[i]->dump(fd,args);
239 }
240
241 if (mHal3Device != NULL) {
242 lines = String8(" HAL device dump:\n");
243 write(fd, lines.string(), lines.size());
244 mHal3Device->ops->dump(mHal3Device, fd);
245 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800246
247 return OK;
248}
249
250const CameraMetadata& Camera3Device::info() const {
251 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800252 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
253 mStatus == STATUS_ERROR)) {
254 ALOGE("%s: Access to static info %s!", __FUNCTION__,
255 mStatus == STATUS_ERROR ?
256 "when in error state" : "before init");
257 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800258 return mDeviceInfo;
259}
260
261status_t Camera3Device::capture(CameraMetadata &request) {
262 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800263 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800264
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700265 // TODO: take ownership of the request
266
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800267 switch (mStatus) {
268 case STATUS_ERROR:
269 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
270 return INVALID_OPERATION;
271 case STATUS_UNINITIALIZED:
272 ALOGE("%s: Device not initialized", __FUNCTION__);
273 return INVALID_OPERATION;
274 case STATUS_IDLE:
275 case STATUS_ACTIVE:
276 // OK
277 break;
278 default:
279 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
280 return INVALID_OPERATION;
281 }
282
283 sp<CaptureRequest> newRequest = setUpRequestLocked(request);
284 if (newRequest == NULL) {
285 ALOGE("%s: Can't create capture request", __FUNCTION__);
286 return BAD_VALUE;
287 }
288
289 return mRequestThread->queueRequest(newRequest);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800290}
291
292
293status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) {
294 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800295 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800296
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800297 switch (mStatus) {
298 case STATUS_ERROR:
299 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
300 return INVALID_OPERATION;
301 case STATUS_UNINITIALIZED:
302 ALOGE("%s: Device not initialized", __FUNCTION__);
303 return INVALID_OPERATION;
304 case STATUS_IDLE:
305 case STATUS_ACTIVE:
306 // OK
307 break;
308 default:
309 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
310 return INVALID_OPERATION;
311 }
312
313 sp<CaptureRequest> newRepeatingRequest = setUpRequestLocked(request);
314 if (newRepeatingRequest == NULL) {
315 ALOGE("%s: Can't create repeating request", __FUNCTION__);
316 return BAD_VALUE;
317 }
318
319 RequestList newRepeatingRequests;
320 newRepeatingRequests.push_back(newRepeatingRequest);
321
322 return mRequestThread->setRepeatingRequests(newRepeatingRequests);
323}
324
325
326sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
327 const CameraMetadata &request) {
328 status_t res;
329
330 if (mStatus == STATUS_IDLE) {
331 res = configureStreamsLocked();
332 if (res != OK) {
333 ALOGE("%s: Can't set up streams: %s (%d)",
334 __FUNCTION__, strerror(-res), res);
335 return NULL;
336 }
337 }
338
339 sp<CaptureRequest> newRequest = createCaptureRequest(request);
340 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800341}
342
343status_t Camera3Device::clearStreamingRequest() {
344 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800345 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800346
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800347 switch (mStatus) {
348 case STATUS_ERROR:
349 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
350 return INVALID_OPERATION;
351 case STATUS_UNINITIALIZED:
352 ALOGE("%s: Device not initialized", __FUNCTION__);
353 return INVALID_OPERATION;
354 case STATUS_IDLE:
355 case STATUS_ACTIVE:
356 // OK
357 break;
358 default:
359 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
360 return INVALID_OPERATION;
361 }
362
363 return mRequestThread->clearRepeatingRequests();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800364}
365
366status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
367 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800368
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700369 return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800370}
371
372status_t Camera3Device::createStream(sp<ANativeWindow> consumer,
373 uint32_t width, uint32_t height, int format, size_t size, int *id) {
374 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800375 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800376
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800377 status_t res;
378 bool wasActive = false;
379
380 switch (mStatus) {
381 case STATUS_ERROR:
382 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
383 return INVALID_OPERATION;
384 case STATUS_UNINITIALIZED:
385 ALOGE("%s: Device not initialized", __FUNCTION__);
386 return INVALID_OPERATION;
387 case STATUS_IDLE:
388 // OK
389 break;
390 case STATUS_ACTIVE:
391 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
392 mRequestThread->setPaused(true);
393 res = waitUntilDrainedLocked();
394 if (res != OK) {
395 ALOGE("%s: Can't pause captures to reconfigure streams!",
396 __FUNCTION__);
397 mStatus = STATUS_ERROR;
398 return res;
399 }
400 wasActive = true;
401 break;
402 default:
403 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
404 return INVALID_OPERATION;
405 }
406 assert(mStatus == STATUS_IDLE);
407
408 sp<Camera3OutputStream> newStream;
409 if (format == HAL_PIXEL_FORMAT_BLOB) {
410 newStream = new Camera3OutputStream(mNextStreamId, consumer,
411 width, height, size, format);
412 } else {
413 newStream = new Camera3OutputStream(mNextStreamId, consumer,
414 width, height, format);
415 }
416
417 res = mOutputStreams.add(mNextStreamId, newStream);
418 if (res < 0) {
419 ALOGE("%s: Can't add new stream to set: %s (%d)",
420 __FUNCTION__, strerror(-res), res);
421 return res;
422 }
423
424 *id = mNextStreamId++;
425
426 // Continue captures if active at start
427 if (wasActive) {
428 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
429 res = configureStreamsLocked();
430 if (res != OK) {
431 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
432 __FUNCTION__, mNextStreamId, strerror(-res), res);
433 return res;
434 }
435 mRequestThread->setPaused(false);
436 }
437
438 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800439}
440
441status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
442 ATRACE_CALL();
443 (void)outputId; (void)id;
444
445 ALOGE("%s: Unimplemented", __FUNCTION__);
446 return INVALID_OPERATION;
447}
448
449
450status_t Camera3Device::getStreamInfo(int id,
451 uint32_t *width, uint32_t *height, uint32_t *format) {
452 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800453 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800454
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800455 switch (mStatus) {
456 case STATUS_ERROR:
457 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
458 return INVALID_OPERATION;
459 case STATUS_UNINITIALIZED:
460 ALOGE("%s: Device not initialized!", __FUNCTION__);
461 return INVALID_OPERATION;
462 case STATUS_IDLE:
463 case STATUS_ACTIVE:
464 // OK
465 break;
466 default:
467 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
468 return INVALID_OPERATION;
469 }
470
471 ssize_t idx = mOutputStreams.indexOfKey(id);
472 if (idx == NAME_NOT_FOUND) {
473 ALOGE("%s: Stream %d is unknown", __FUNCTION__, id);
474 return idx;
475 }
476
477 if (width) *width = mOutputStreams[idx]->getWidth();
478 if (height) *height = mOutputStreams[idx]->getHeight();
479 if (format) *format = mOutputStreams[idx]->getFormat();
480
481 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800482}
483
484status_t Camera3Device::setStreamTransform(int id,
485 int transform) {
486 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800487 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800488
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800489 switch (mStatus) {
490 case STATUS_ERROR:
491 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
492 return INVALID_OPERATION;
493 case STATUS_UNINITIALIZED:
494 ALOGE("%s: Device not initialized", __FUNCTION__);
495 return INVALID_OPERATION;
496 case STATUS_IDLE:
497 case STATUS_ACTIVE:
498 // OK
499 break;
500 default:
501 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
502 return INVALID_OPERATION;
503 }
504
505 ssize_t idx = mOutputStreams.indexOfKey(id);
506 if (idx == NAME_NOT_FOUND) {
507 ALOGE("%s: Stream %d does not exist",
508 __FUNCTION__, id);
509 return BAD_VALUE;
510 }
511
512 return mOutputStreams.editValueAt(idx)->setTransform(transform);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800513}
514
515status_t Camera3Device::deleteStream(int id) {
516 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800517 Mutex::Autolock l(mLock);
518 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800519
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800520 // CameraDevice semantics require device to already be idle before
521 // deleteStream is called, unlike for createStream.
522 if (mStatus != STATUS_IDLE) {
523 ALOGE("%s: Device not idle", __FUNCTION__);
524 return INVALID_OPERATION;
525 }
526
527 sp<Camera3Stream> deletedStream;
528 if (mInputStream != NULL && id == mInputStream->getId()) {
529 deletedStream = mInputStream;
530 mInputStream.clear();
531 } else {
532 ssize_t idx = mOutputStreams.indexOfKey(id);
533 if (idx == NAME_NOT_FOUND) {
534 ALOGE("%s: Stream %d does not exist",
535 __FUNCTION__, id);
536 return BAD_VALUE;
537 }
538 deletedStream = mOutputStreams.editValueAt(idx);
539 mOutputStreams.removeItem(id);
540 }
541
542 // Free up the stream endpoint so that it can be used by some other stream
543 res = deletedStream->disconnect();
544 if (res != OK) {
545 ALOGE("%s: Can't disconnect deleted stream", __FUNCTION__);
546 // fall through since we want to still list the stream as deleted.
547 }
548 mDeletedStreams.add(deletedStream);
549
550 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800551}
552
553status_t Camera3Device::deleteReprocessStream(int id) {
554 ATRACE_CALL();
555 (void)id;
556
557 ALOGE("%s: Unimplemented", __FUNCTION__);
558 return INVALID_OPERATION;
559}
560
561
562status_t Camera3Device::createDefaultRequest(int templateId,
563 CameraMetadata *request) {
564 ATRACE_CALL();
565 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800566 Mutex::Autolock l(mLock);
567
568 switch (mStatus) {
569 case STATUS_ERROR:
570 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
571 return INVALID_OPERATION;
572 case STATUS_UNINITIALIZED:
573 ALOGE("%s: Device is not initialized!", __FUNCTION__);
574 return INVALID_OPERATION;
575 case STATUS_IDLE:
576 case STATUS_ACTIVE:
577 // OK
578 break;
579 default:
580 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
581 return INVALID_OPERATION;
582 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800583
584 const camera_metadata_t *rawRequest;
585 rawRequest = mHal3Device->ops->construct_default_request_settings(
586 mHal3Device, templateId);
587 if (rawRequest == NULL) return DEAD_OBJECT;
588 *request = rawRequest;
589
590 return OK;
591}
592
593status_t Camera3Device::waitUntilDrained() {
594 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800595 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800596
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800597 return waitUntilDrainedLocked();
598}
599
600status_t Camera3Device::waitUntilDrainedLocked() {
601 ATRACE_CALL();
602 status_t res;
603
604 switch (mStatus) {
605 case STATUS_UNINITIALIZED:
606 case STATUS_IDLE:
607 ALOGV("%s: Already idle", __FUNCTION__);
608 return OK;
609 case STATUS_ERROR:
610 case STATUS_ACTIVE:
611 // Need to shut down
612 break;
613 default:
614 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
615 return INVALID_OPERATION;
616 }
617
618 if (mRequestThread != NULL) {
619 res = mRequestThread->waitUntilPaused(kShutdownTimeout);
620 if (res != OK) {
621 ALOGE("%s: Can't stop request thread in %f seconds!",
622 __FUNCTION__, kShutdownTimeout/1e9);
623 mStatus = STATUS_ERROR;
624 return res;
625 }
626 }
627 if (mInputStream != NULL) {
628 res = mInputStream->waitUntilIdle(kShutdownTimeout);
629 if (res != OK) {
630 ALOGE("%s: Can't idle input stream %d in %f seconds!",
631 __FUNCTION__, mInputStream->getId(), kShutdownTimeout/1e9);
632 mStatus = STATUS_ERROR;
633 return res;
634 }
635 }
636 for (size_t i = 0; i < mOutputStreams.size(); i++) {
637 res = mOutputStreams.editValueAt(i)->waitUntilIdle(kShutdownTimeout);
638 if (res != OK) {
639 ALOGE("%s: Can't idle output stream %d in %f seconds!",
640 __FUNCTION__, mOutputStreams.keyAt(i),
641 kShutdownTimeout/1e9);
642 mStatus = STATUS_ERROR;
643 return res;
644 }
645 }
646
647 if (mStatus != STATUS_ERROR) {
648 mStatus = STATUS_IDLE;
649 }
650
651 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800652}
653
654status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
655 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700656 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800657
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700658 if (listener != NULL && mListener != NULL) {
659 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
660 }
661 mListener = listener;
662
663 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800664}
665
666status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700667 ATRACE_CALL();
668 status_t res;
669 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800670
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700671 while (mResultQueue.empty()) {
672 res = mResultSignal.waitRelative(mOutputLock, timeout);
673 if (res == TIMED_OUT) {
674 return res;
675 } else if (res != OK) {
676 ALOGE("%s: Camera %d: Error waiting for frame: %s (%d)",
677 __FUNCTION__, mId, strerror(-res), res);
678 return res;
679 }
680 }
681 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800682}
683
684status_t Camera3Device::getNextFrame(CameraMetadata *frame) {
685 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700686 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800687
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700688 if (mResultQueue.empty()) {
689 return NOT_ENOUGH_DATA;
690 }
691
692 CameraMetadata &result = *(mResultQueue.begin());
693 frame->acquire(result);
694 mResultQueue.erase(mResultQueue.begin());
695
696 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800697}
698
699status_t Camera3Device::triggerAutofocus(uint32_t id) {
700 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800701
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700702 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
703 // Mix-in this trigger into the next request and only the next request.
704 RequestTrigger trigger[] = {
705 {
706 ANDROID_CONTROL_AF_TRIGGER,
707 ANDROID_CONTROL_AF_TRIGGER_START
708 },
709 {
710 ANDROID_CONTROL_AF_TRIGGER_ID,
711 static_cast<int32_t>(id)
712 },
713 };
714
715 return mRequestThread->queueTrigger(trigger,
716 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800717}
718
719status_t Camera3Device::triggerCancelAutofocus(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 cancel 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_CANCEL
728 },
729 {
730 ANDROID_CONTROL_AF_TRIGGER_ID,
731 static_cast<int32_t>(id)
732 },
733 };
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800734
Igor Murashkin4d2f2e82013-04-01 17:29:07 -0700735 return mRequestThread->queueTrigger(trigger,
736 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800737}
738
739status_t Camera3Device::triggerPrecaptureMetering(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 precapture metering, 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_AE_PRECAPTURE_TRIGGER,
747 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
748 },
749 {
750 ANDROID_CONTROL_AE_PRECAPTURE_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::pushReprocessBuffer(int reprocessStreamId,
760 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
761 ATRACE_CALL();
762 (void)reprocessStreamId; (void)buffer; (void)listener;
763
764 ALOGE("%s: Unimplemented", __FUNCTION__);
765 return INVALID_OPERATION;
766}
767
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800768/**
769 * Camera3Device private methods
770 */
771
772sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
773 const CameraMetadata &request) {
774 ATRACE_CALL();
775 status_t res;
776
777 sp<CaptureRequest> newRequest = new CaptureRequest;
778 newRequest->mSettings = request;
779
780 camera_metadata_entry_t inputStreams =
781 newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
782 if (inputStreams.count > 0) {
783 if (mInputStream == NULL ||
784 mInputStream->getId() != inputStreams.data.u8[0]) {
785 ALOGE("%s: Request references unknown input stream %d",
786 __FUNCTION__, inputStreams.data.u8[0]);
787 return NULL;
788 }
789 // Lazy completion of stream configuration (allocation/registration)
790 // on first use
791 if (mInputStream->isConfiguring()) {
792 res = mInputStream->finishConfiguration(mHal3Device);
793 if (res != OK) {
794 ALOGE("%s: Unable to finish configuring input stream %d:"
795 " %s (%d)",
796 __FUNCTION__, mInputStream->getId(),
797 strerror(-res), res);
798 return NULL;
799 }
800 }
801
802 newRequest->mInputStream = mInputStream;
803 newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
804 }
805
806 camera_metadata_entry_t streams =
807 newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
808 if (streams.count == 0) {
809 ALOGE("%s: Zero output streams specified!", __FUNCTION__);
810 return NULL;
811 }
812
813 for (size_t i = 0; i < streams.count; i++) {
814 int idx = mOutputStreams.indexOfKey(streams.data.u8[i]);
815 if (idx == NAME_NOT_FOUND) {
816 ALOGE("%s: Request references unknown stream %d",
817 __FUNCTION__, streams.data.u8[i]);
818 return NULL;
819 }
820 sp<Camera3OutputStream> stream = mOutputStreams.editValueAt(idx);
821
822 // Lazy completion of stream configuration (allocation/registration)
823 // on first use
824 if (stream->isConfiguring()) {
825 res = stream->finishConfiguration(mHal3Device);
826 if (res != OK) {
827 ALOGE("%s: Unable to finish configuring stream %d: %s (%d)",
828 __FUNCTION__, stream->getId(), strerror(-res), res);
829 return NULL;
830 }
831 }
832
833 newRequest->mOutputStreams.push(stream);
834 }
835 newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
836
837 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800838}
839
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800840status_t Camera3Device::configureStreamsLocked() {
841 ATRACE_CALL();
842 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800843
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800844 if (mStatus != STATUS_IDLE) {
845 ALOGE("%s: Not idle", __FUNCTION__);
846 return INVALID_OPERATION;
847 }
848
849 // Start configuring the streams
850
851 camera3_stream_configuration config;
852
853 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
854
855 Vector<camera3_stream_t*> streams;
856 streams.setCapacity(config.num_streams);
857
858 if (mInputStream != NULL) {
859 camera3_stream_t *inputStream;
860 inputStream = mInputStream->startConfiguration();
861 if (inputStream == NULL) {
862 ALOGE("%s: Can't start input stream configuration",
863 __FUNCTION__);
864 // TODO: Make sure the error flow here is correct
865 return INVALID_OPERATION;
866 }
867 streams.add(inputStream);
868 }
869
870 for (size_t i = 0; i < mOutputStreams.size(); i++) {
871 camera3_stream_t *outputStream;
872 outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
873 if (outputStream == NULL) {
874 ALOGE("%s: Can't start output stream configuration",
875 __FUNCTION__);
876 // TODO: Make sure the error flow here is correct
877 return INVALID_OPERATION;
878 }
879 streams.add(outputStream);
880 }
881
882 config.streams = streams.editArray();
883
884 // Do the HAL configuration; will potentially touch stream
885 // max_buffers, usage, priv fields.
886
887 res = mHal3Device->ops->configure_streams(mHal3Device, &config);
888
889 if (res != OK) {
890 ALOGE("%s: Unable to configure streams with HAL: %s (%d)",
891 __FUNCTION__, strerror(-res), res);
892 return res;
893 }
894
895 // Request thread needs to know to avoid using repeat-last-settings protocol
896 // across configure_streams() calls
897 mRequestThread->configurationComplete();
898
899 // Finish configuring the streams lazily on first reference
900
901 mStatus = STATUS_ACTIVE;
902
903 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800904}
905
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800906
907/**
908 * Camera HAL device callback methods
909 */
910
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800911void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700912 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800913
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700914 status_t res;
915
916 if (result->result == NULL) {
917 // TODO: Report error upstream
918 ALOGW("%s: No metadata for frame %d", __FUNCTION__,
919 result->frame_number);
920 return;
921 }
922
923 nsecs_t timestamp = 0;
924 AlgState cur3aState;
925 AlgState new3aState;
926 int32_t aeTriggerId = 0;
927 int32_t afTriggerId = 0;
928
929 NotificationListener *listener;
930
931 {
932 Mutex::Autolock l(mOutputLock);
933
934 // Push result metadata into queue
935 mResultQueue.push_back(CameraMetadata());
Igor Murashkind2c90692013-04-02 12:32:32 -0700936 // Lets avoid copies! Too bad there's not a #back method
937 CameraMetadata &captureResult = *(--mResultQueue.end());
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700938
939 captureResult = result->result;
Igor Murashkind2c90692013-04-02 12:32:32 -0700940 if (captureResult.update(ANDROID_REQUEST_FRAME_COUNT,
941 (int32_t*)&result->frame_number, 1) != OK) {
942 ALOGE("%s: Camera %d: Failed to set frame# in metadata (%d)",
943 __FUNCTION__, mId, result->frame_number);
944 // TODO: Report error upstream
945 } else {
946 ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
947 __FUNCTION__, mId, result->frame_number);
948 }
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700949
950 // Get timestamp from result metadata
951
952 camera_metadata_entry entry =
953 captureResult.find(ANDROID_SENSOR_TIMESTAMP);
954 if (entry.count == 0) {
955 ALOGE("%s: Camera %d: No timestamp provided by HAL for frame %d!",
956 __FUNCTION__, mId, result->frame_number);
957 // TODO: Report error upstream
958 } else {
959 timestamp = entry.data.i64[0];
960 }
961
962 // Get 3A states from result metadata
963
964 entry = captureResult.find(ANDROID_CONTROL_AE_STATE);
965 if (entry.count == 0) {
966 ALOGE("%s: Camera %d: No AE state provided by HAL for frame %d!",
967 __FUNCTION__, mId, result->frame_number);
968 } else {
969 new3aState.aeState =
970 static_cast<camera_metadata_enum_android_control_ae_state>(
971 entry.data.u8[0]);
972 }
973
974 entry = captureResult.find(ANDROID_CONTROL_AF_STATE);
975 if (entry.count == 0) {
976 ALOGE("%s: Camera %d: No AF state provided by HAL for frame %d!",
977 __FUNCTION__, mId, result->frame_number);
978 } else {
979 new3aState.afState =
980 static_cast<camera_metadata_enum_android_control_af_state>(
981 entry.data.u8[0]);
982 }
983
984 entry = captureResult.find(ANDROID_CONTROL_AWB_STATE);
985 if (entry.count == 0) {
986 ALOGE("%s: Camera %d: No AWB state provided by HAL for frame %d!",
987 __FUNCTION__, mId, result->frame_number);
988 } else {
989 new3aState.awbState =
990 static_cast<camera_metadata_enum_android_control_awb_state>(
991 entry.data.u8[0]);
992 }
993
994 entry = captureResult.find(ANDROID_CONTROL_AF_TRIGGER_ID);
995 if (entry.count == 0) {
996 ALOGE("%s: Camera %d: No AF trigger ID provided by HAL for frame %d!",
997 __FUNCTION__, mId, result->frame_number);
998 } else {
999 afTriggerId = entry.data.i32[0];
1000 }
1001
1002 entry = captureResult.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
1003 if (entry.count == 0) {
1004 ALOGE("%s: Camera %d: No AE precapture trigger ID provided by HAL"
1005 " for frame %d!", __FUNCTION__, mId, result->frame_number);
1006 } else {
1007 aeTriggerId = entry.data.i32[0];
1008 }
1009
1010 listener = mListener;
1011 cur3aState = m3AState;
1012
1013 m3AState = new3aState;
1014 } // scope for mOutputLock
1015
1016 // Return completed buffers to their streams
1017 for (size_t i = 0; i < result->num_output_buffers; i++) {
1018 Camera3Stream *stream =
1019 Camera3Stream::cast(result->output_buffers[i].stream);
1020 res = stream->returnBuffer(result->output_buffers[i], timestamp);
1021 // Note: stream may be deallocated at this point, if this buffer was the
1022 // last reference to it.
1023 if (res != OK) {
1024 ALOGE("%s: Camera %d: Can't return buffer %d for frame %d to its"
1025 " stream:%s (%d)", __FUNCTION__, mId, i,
1026 result->frame_number, strerror(-res), res);
1027 // TODO: Report error upstream
1028 }
1029 }
1030
1031 // Dispatch any 3A change events to listeners
1032 if (listener != NULL) {
1033 if (new3aState.aeState != cur3aState.aeState) {
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001034 ALOGVV("%s: AE state changed from 0x%x to 0x%x",
1035 __FUNCTION__, cur3aState.aeState, new3aState.aeState);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001036 listener->notifyAutoExposure(new3aState.aeState, aeTriggerId);
1037 }
1038 if (new3aState.afState != cur3aState.afState) {
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001039 ALOGVV("%s: AF state changed from 0x%x to 0x%x",
1040 __FUNCTION__, cur3aState.afState, new3aState.afState);
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001041 listener->notifyAutoFocus(new3aState.afState, afTriggerId);
1042 }
1043 if (new3aState.awbState != cur3aState.awbState) {
1044 listener->notifyAutoWhitebalance(new3aState.awbState, aeTriggerId);
1045 }
1046 }
1047
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001048}
1049
1050void Camera3Device::notify(const camera3_notify_msg *msg) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001051 NotificationListener *listener;
1052 {
1053 Mutex::Autolock l(mOutputLock);
1054 if (mListener == NULL) return;
1055 listener = mListener;
1056 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001057
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001058 if (msg == NULL) {
1059 ALOGE("%s: Camera %d: HAL sent NULL notify message!",
1060 __FUNCTION__, mId);
1061 return;
1062 }
1063
1064 switch (msg->type) {
1065 case CAMERA3_MSG_ERROR: {
1066 int streamId = 0;
1067 if (msg->message.error.error_stream != NULL) {
1068 Camera3Stream *stream =
1069 Camera3Stream::cast(
1070 msg->message.error.error_stream);
1071 streamId = stream->getId();
1072 }
1073 listener->notifyError(msg->message.error.error_code,
1074 msg->message.error.frame_number, streamId);
1075 break;
1076 }
1077 case CAMERA3_MSG_SHUTTER: {
1078 listener->notifyShutter(msg->message.shutter.frame_number,
1079 msg->message.shutter.timestamp);
1080 break;
1081 }
1082 default:
1083 ALOGE("%s: Camera %d: Unknown notify message from HAL: %d",
1084 __FUNCTION__, mId, msg->type);
1085 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001086}
1087
1088/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001089 * RequestThread inner class methods
1090 */
1091
1092Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
1093 camera3_device_t *hal3Device) :
1094 Thread(false),
1095 mParent(parent),
1096 mHal3Device(hal3Device),
1097 mReconfigured(false),
1098 mDoPause(false),
1099 mPaused(true),
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001100 mFrameNumber(0),
1101 mLatestRequestId(NAME_NOT_FOUND) {
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001102}
1103
1104void Camera3Device::RequestThread::configurationComplete() {
1105 Mutex::Autolock l(mRequestLock);
1106 mReconfigured = true;
1107}
1108
1109status_t Camera3Device::RequestThread::queueRequest(
1110 sp<CaptureRequest> request) {
1111 Mutex::Autolock l(mRequestLock);
1112 mRequestQueue.push_back(request);
1113
1114 return OK;
1115}
1116
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001117
1118status_t Camera3Device::RequestThread::queueTrigger(
1119 RequestTrigger trigger[],
1120 size_t count) {
1121
1122 Mutex::Autolock l(mTriggerMutex);
1123 status_t ret;
1124
1125 for (size_t i = 0; i < count; ++i) {
1126 ret = queueTriggerLocked(trigger[i]);
1127
1128 if (ret != OK) {
1129 return ret;
1130 }
1131 }
1132
1133 return OK;
1134}
1135
1136status_t Camera3Device::RequestThread::queueTriggerLocked(
1137 RequestTrigger trigger) {
1138
1139 uint32_t tag = trigger.metadataTag;
1140 ssize_t index = mTriggerMap.indexOfKey(tag);
1141
1142 switch (trigger.getTagType()) {
1143 case TYPE_BYTE:
1144 // fall-through
1145 case TYPE_INT32:
1146 break;
1147 default:
1148 ALOGE("%s: Type not supported: 0x%x",
1149 __FUNCTION__,
1150 trigger.getTagType());
1151 return INVALID_OPERATION;
1152 }
1153
1154 /**
1155 * Collect only the latest trigger, since we only have 1 field
1156 * in the request settings per trigger tag, and can't send more than 1
1157 * trigger per request.
1158 */
1159 if (index != NAME_NOT_FOUND) {
1160 mTriggerMap.editValueAt(index) = trigger;
1161 } else {
1162 mTriggerMap.add(tag, trigger);
1163 }
1164
1165 return OK;
1166}
1167
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001168status_t Camera3Device::RequestThread::setRepeatingRequests(
1169 const RequestList &requests) {
1170 Mutex::Autolock l(mRequestLock);
1171 mRepeatingRequests.clear();
1172 mRepeatingRequests.insert(mRepeatingRequests.begin(),
1173 requests.begin(), requests.end());
1174 return OK;
1175}
1176
1177status_t Camera3Device::RequestThread::clearRepeatingRequests() {
1178 Mutex::Autolock l(mRequestLock);
1179 mRepeatingRequests.clear();
1180 return OK;
1181}
1182
1183void Camera3Device::RequestThread::setPaused(bool paused) {
1184 Mutex::Autolock l(mPauseLock);
1185 mDoPause = paused;
1186 mDoPauseSignal.signal();
1187}
1188
1189status_t Camera3Device::RequestThread::waitUntilPaused(nsecs_t timeout) {
1190 status_t res;
1191 Mutex::Autolock l(mPauseLock);
1192 while (!mPaused) {
1193 res = mPausedSignal.waitRelative(mPauseLock, timeout);
1194 if (res == TIMED_OUT) {
1195 return res;
1196 }
1197 }
1198 return OK;
1199}
1200
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001201status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
1202 int32_t requestId, nsecs_t timeout) {
1203 Mutex::Autolock l(mLatestRequestMutex);
1204 status_t res;
1205 while (mLatestRequestId != requestId) {
1206 nsecs_t startTime = systemTime();
1207
1208 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
1209 if (res != OK) return res;
1210
1211 timeout -= (systemTime() - startTime);
1212 }
1213
1214 return OK;
1215}
1216
1217
1218
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001219bool Camera3Device::RequestThread::threadLoop() {
1220
1221 status_t res;
1222
1223 // Handle paused state.
1224 if (waitIfPaused()) {
1225 return true;
1226 }
1227
1228 // Get work to do
1229
1230 sp<CaptureRequest> nextRequest = waitForNextRequest();
1231 if (nextRequest == NULL) {
1232 return true;
1233 }
1234
1235 // Create request to HAL
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001236 camera3_capture_request_t request = camera3_capture_request_t();
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001237 Vector<camera3_stream_buffer_t> outputBuffers;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001238
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001239 // Insert any queued triggers (before metadata is locked)
1240 int32_t triggerCount;
1241 res = insertTriggers(nextRequest);
1242 if (res < 0) {
1243 ALOGE("RequestThread: Unable to insert triggers "
1244 "(capture request %d, HAL device: %s (%d)",
1245 (mFrameNumber+1), strerror(-res), res);
1246 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1247 return false;
1248 }
1249 triggerCount = res;
1250
1251 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
1252
1253 // If the request is the same as last, or we had triggers last time
1254 if (mPrevRequest != nextRequest || triggersMixedIn) {
1255 /**
1256 * The request should be presorted so accesses in HAL
1257 * are O(logn). Sidenote, sorting a sorted metadata is nop.
1258 */
1259 nextRequest->mSettings.sort();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001260 request.settings = nextRequest->mSettings.getAndLock();
1261 mPrevRequest = nextRequest;
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001262 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
1263
1264 IF_ALOGV() {
1265 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
1266 find_camera_metadata_ro_entry(
1267 request.settings,
1268 ANDROID_CONTROL_AF_TRIGGER,
1269 &e
1270 );
1271 if (e.count > 0) {
1272 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
1273 __FUNCTION__,
1274 mFrameNumber+1,
1275 e.data.u8[0]);
1276 }
1277 }
1278 } else {
1279 // leave request.settings NULL to indicate 'reuse latest given'
1280 ALOGVV("%s: Request settings are REUSED",
1281 __FUNCTION__);
1282 }
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001283
1284 camera3_stream_buffer_t inputBuffer;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001285
1286 // Fill in buffers
1287
1288 if (nextRequest->mInputStream != NULL) {
1289 request.input_buffer = &inputBuffer;
1290 res = nextRequest->mInputStream->getBuffer(&inputBuffer);
1291 if (res != OK) {
1292 ALOGE("RequestThread: Can't get input buffer, skipping request:"
1293 " %s (%d)", strerror(-res), res);
1294 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1295 return true;
1296 }
1297 } else {
1298 request.input_buffer = NULL;
1299 }
1300
1301 outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
1302 nextRequest->mOutputStreams.size());
1303 request.output_buffers = outputBuffers.array();
1304 for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
1305 res = nextRequest->mOutputStreams.editItemAt(i)->
1306 getBuffer(&outputBuffers.editItemAt(i));
1307 if (res != OK) {
1308 ALOGE("RequestThread: Can't get output buffer, skipping request:"
1309 "%s (%d)", strerror(-res), res);
1310 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1311 return true;
1312 }
1313 request.num_output_buffers++;
1314 }
1315
1316 request.frame_number = mFrameNumber++;
1317
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001318
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001319 // Submit request and block until ready for next one
1320
1321 res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
1322 if (res != OK) {
1323 ALOGE("RequestThread: Unable to submit capture request %d to HAL"
1324 " device: %s (%d)", request.frame_number, strerror(-res), res);
1325 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1326 return false;
1327 }
1328
1329 if (request.settings != NULL) {
1330 nextRequest->mSettings.unlock(request.settings);
1331 }
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001332
1333 // Remove any previously queued triggers (after unlock)
1334 res = removeTriggers(mPrevRequest);
1335 if (res != OK) {
1336 ALOGE("RequestThread: Unable to remove triggers "
1337 "(capture request %d, HAL device: %s (%d)",
1338 request.frame_number, strerror(-res), res);
1339 return false;
1340 }
1341 mPrevTriggers = triggerCount;
1342
1343 // Read android.request.id from the request settings metadata
1344 // - inform waitUntilRequestProcessed thread of a new request ID
1345 {
1346 Mutex::Autolock al(mLatestRequestMutex);
1347
1348 camera_metadata_entry_t requestIdEntry =
1349 nextRequest->mSettings.find(ANDROID_REQUEST_ID);
1350 if (requestIdEntry.count > 0) {
1351 mLatestRequestId = requestIdEntry.data.i32[0];
1352 } else {
1353 ALOGW("%s: Did not have android.request.id set in the request",
1354 __FUNCTION__);
1355 mLatestRequestId = NAME_NOT_FOUND;
1356 }
1357
1358 mLatestRequestSignal.signal();
1359 }
1360
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001361 return true;
1362}
1363
1364void Camera3Device::RequestThread::cleanUpFailedRequest(
1365 camera3_capture_request_t &request,
1366 sp<CaptureRequest> &nextRequest,
1367 Vector<camera3_stream_buffer_t> &outputBuffers) {
1368
1369 if (request.settings != NULL) {
1370 nextRequest->mSettings.unlock(request.settings);
1371 }
1372 if (request.input_buffer != NULL) {
1373 request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
1374 nextRequest->mInputStream->returnBuffer(*(request.input_buffer), 0);
1375 }
1376 for (size_t i = 0; i < request.num_output_buffers; i++) {
1377 outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
1378 nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
1379 outputBuffers[i], 0);
1380 }
1381 // TODO: Report error upstream
1382}
1383
1384sp<Camera3Device::CaptureRequest>
1385 Camera3Device::RequestThread::waitForNextRequest() {
1386 status_t res;
1387 sp<CaptureRequest> nextRequest;
1388
1389 // Optimized a bit for the simple steady-state case (single repeating
1390 // request), to avoid putting that request in the queue temporarily.
1391 Mutex::Autolock l(mRequestLock);
1392
1393 while (mRequestQueue.empty()) {
1394 if (!mRepeatingRequests.empty()) {
1395 // Always atomically enqueue all requests in a repeating request
1396 // list. Guarantees a complete in-sequence set of captures to
1397 // application.
1398 const RequestList &requests = mRepeatingRequests;
1399 RequestList::const_iterator firstRequest =
1400 requests.begin();
1401 nextRequest = *firstRequest;
1402 mRequestQueue.insert(mRequestQueue.end(),
1403 ++firstRequest,
1404 requests.end());
1405 // No need to wait any longer
1406 break;
1407 }
1408
1409 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
1410
1411 if (res == TIMED_OUT) {
1412 // Signal that we're paused by starvation
1413 Mutex::Autolock pl(mPauseLock);
1414 if (mPaused == false) {
1415 mPaused = true;
1416 mPausedSignal.signal();
1417 }
1418 // Stop waiting for now and let thread management happen
1419 return NULL;
1420 }
1421 }
1422
1423 if (nextRequest == NULL) {
1424 // Don't have a repeating request already in hand, so queue
1425 // must have an entry now.
1426 RequestList::iterator firstRequest =
1427 mRequestQueue.begin();
1428 nextRequest = *firstRequest;
1429 mRequestQueue.erase(firstRequest);
1430 }
1431
1432 // Not paused
1433 Mutex::Autolock pl(mPauseLock);
1434 mPaused = false;
1435
1436 // Check if we've reconfigured since last time, and reset the preview
1437 // request if so. Can't use 'NULL request == repeat' across configure calls.
1438 if (mReconfigured) {
1439 mPrevRequest.clear();
1440 mReconfigured = false;
1441 }
1442
1443 return nextRequest;
1444}
1445
1446bool Camera3Device::RequestThread::waitIfPaused() {
1447 status_t res;
1448 Mutex::Autolock l(mPauseLock);
1449 while (mDoPause) {
1450 // Signal that we're paused by request
1451 if (mPaused == false) {
1452 mPaused = true;
1453 mPausedSignal.signal();
1454 }
1455 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
1456 if (res == TIMED_OUT) {
1457 return true;
1458 }
1459 }
1460 // We don't set mPaused to false here, because waitForNextRequest needs
1461 // to further manage the paused state in case of starvation.
1462 return false;
1463}
1464
Igor Murashkin4d2f2e82013-04-01 17:29:07 -07001465status_t Camera3Device::RequestThread::insertTriggers(
1466 const sp<CaptureRequest> &request) {
1467
1468 Mutex::Autolock al(mTriggerMutex);
1469
1470 CameraMetadata &metadata = request->mSettings;
1471 size_t count = mTriggerMap.size();
1472
1473 for (size_t i = 0; i < count; ++i) {
1474 RequestTrigger trigger = mTriggerMap.valueAt(i);
1475
1476 uint32_t tag = trigger.metadataTag;
1477 camera_metadata_entry entry = metadata.find(tag);
1478
1479 if (entry.count > 0) {
1480 /**
1481 * Already has an entry for this trigger in the request.
1482 * Rewrite it with our requested trigger value.
1483 */
1484 RequestTrigger oldTrigger = trigger;
1485
1486 oldTrigger.entryValue = entry.data.u8[0];
1487
1488 mTriggerReplacedMap.add(tag, oldTrigger);
1489 } else {
1490 /**
1491 * More typical, no trigger entry, so we just add it
1492 */
1493 mTriggerRemovedMap.add(tag, trigger);
1494 }
1495
1496 status_t res;
1497
1498 switch (trigger.getTagType()) {
1499 case TYPE_BYTE: {
1500 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
1501 res = metadata.update(tag,
1502 &entryValue,
1503 /*count*/1);
1504 break;
1505 }
1506 case TYPE_INT32:
1507 res = metadata.update(tag,
1508 &trigger.entryValue,
1509 /*count*/1);
1510 break;
1511 default:
1512 ALOGE("%s: Type not supported: 0x%x",
1513 __FUNCTION__,
1514 trigger.getTagType());
1515 return INVALID_OPERATION;
1516 }
1517
1518 if (res != OK) {
1519 ALOGE("%s: Failed to update request metadata with trigger tag %s"
1520 ", value %d", __FUNCTION__, trigger.getTagName(),
1521 trigger.entryValue);
1522 return res;
1523 }
1524
1525 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
1526 trigger.getTagName(),
1527 trigger.entryValue);
1528 }
1529
1530 mTriggerMap.clear();
1531
1532 return count;
1533}
1534
1535status_t Camera3Device::RequestThread::removeTriggers(
1536 const sp<CaptureRequest> &request) {
1537 Mutex::Autolock al(mTriggerMutex);
1538
1539 CameraMetadata &metadata = request->mSettings;
1540
1541 /**
1542 * Replace all old entries with their old values.
1543 */
1544 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
1545 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
1546
1547 status_t res;
1548
1549 uint32_t tag = trigger.metadataTag;
1550 switch (trigger.getTagType()) {
1551 case TYPE_BYTE: {
1552 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
1553 res = metadata.update(tag,
1554 &entryValue,
1555 /*count*/1);
1556 break;
1557 }
1558 case TYPE_INT32:
1559 res = metadata.update(tag,
1560 &trigger.entryValue,
1561 /*count*/1);
1562 break;
1563 default:
1564 ALOGE("%s: Type not supported: 0x%x",
1565 __FUNCTION__,
1566 trigger.getTagType());
1567 return INVALID_OPERATION;
1568 }
1569
1570 if (res != OK) {
1571 ALOGE("%s: Failed to restore request metadata with trigger tag %s"
1572 ", trigger value %d", __FUNCTION__,
1573 trigger.getTagName(), trigger.entryValue);
1574 return res;
1575 }
1576 }
1577 mTriggerReplacedMap.clear();
1578
1579 /**
1580 * Remove all new entries.
1581 */
1582 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
1583 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
1584 status_t res = metadata.erase(trigger.metadataTag);
1585
1586 if (res != OK) {
1587 ALOGE("%s: Failed to erase metadata with trigger tag %s"
1588 ", trigger value %d", __FUNCTION__,
1589 trigger.getTagName(), trigger.entryValue);
1590 return res;
1591 }
1592 }
1593 mTriggerRemovedMap.clear();
1594
1595 return OK;
1596}
1597
1598
1599
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001600/**
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001601 * Static callback forwarding methods from HAL to instance
1602 */
1603
1604void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
1605 const camera3_capture_result *result) {
1606 Camera3Device *d =
1607 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1608 d->processCaptureResult(result);
1609}
1610
1611void Camera3Device::sNotify(const camera3_callback_ops *cb,
1612 const camera3_notify_msg *msg) {
1613 Camera3Device *d =
1614 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1615 d->notify(msg);
1616}
1617
1618}; // namespace android