blob: 34371300007a7ef56e58e27d4cfb778c3b45057d [file] [log] [blame]
Eino-Ville Talvalab99c5b82013-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 Talvala3b53bc92013-02-27 18:02:26 -080032#include "camera3/Camera3OutputStream.h"
Igor Murashkin0776a142013-04-15 14:59:22 -070033#include "camera3/Camera3InputStream.h"
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080034
35using namespace android::camera3;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080036
37namespace android {
38
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080039Camera3Device::Camera3Device(int id):
40 mId(id),
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080041 mHal3Device(NULL),
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -070042 mStatus(STATUS_UNINITIALIZED),
43 mListener(NULL)
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080044{
45 ATRACE_CALL();
46 camera3_callback_ops::notify = &sNotify;
47 camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
48 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
49}
50
51Camera3Device::~Camera3Device()
52{
53 ATRACE_CALL();
54 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
55 disconnect();
56}
57
Igor Murashkince124da2013-03-04 14:53:08 -080058int Camera3Device::getId() const {
59 return mId;
60}
61
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080062/**
63 * CameraDeviceBase interface
64 */
65
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080066status_t Camera3Device::initialize(camera_module_t *module)
67{
68 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080069 Mutex::Autolock l(mLock);
70
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080071 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080072 if (mStatus != STATUS_UNINITIALIZED) {
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080073 ALOGE("%s: Already initialized!", __FUNCTION__);
74 return INVALID_OPERATION;
75 }
76
77 /** Open HAL device */
78
79 status_t res;
80 String8 deviceName = String8::format("%d", mId);
81
82 camera3_device_t *device;
83
84 res = module->common.methods->open(&module->common, deviceName.string(),
85 reinterpret_cast<hw_device_t**>(&device));
86
87 if (res != OK) {
88 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
89 mId, strerror(-res), res);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080090 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080091 return res;
92 }
93
94 /** Cross-check device version */
95
96 if (device->common.version != CAMERA_DEVICE_API_VERSION_3_0) {
97 ALOGE("%s: Could not open camera %d: "
98 "Camera device is not version %x, reports %x instead",
99 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_3_0,
100 device->common.version);
101 device->common.close(&device->common);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800102 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800103 return BAD_VALUE;
104 }
105
106 camera_info info;
107 res = module->get_camera_info(mId, &info);
108 if (res != OK) return res;
109
110 if (info.device_version != device->common.version) {
111 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
112 " and device version (%x).", __FUNCTION__,
113 device->common.version, info.device_version);
114 device->common.close(&device->common);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800115 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800116 return BAD_VALUE;
117 }
118
119 /** Initialize device with callback functions */
120
121 res = device->ops->initialize(device, this);
122 if (res != OK) {
123 ALOGE("%s: Camera %d: Unable to initialize HAL device: %s (%d)",
124 __FUNCTION__, mId, strerror(-res), res);
125 device->common.close(&device->common);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800126 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800127 return BAD_VALUE;
128 }
129
130 /** Get vendor metadata tags */
131
132 mVendorTagOps.get_camera_vendor_section_name = NULL;
133
134 device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
135
136 if (mVendorTagOps.get_camera_vendor_section_name != NULL) {
137 res = set_camera_metadata_vendor_tag_ops(&mVendorTagOps);
138 if (res != OK) {
139 ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
140 __FUNCTION__, mId, strerror(-res), res);
141 device->common.close(&device->common);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800142 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800143 return res;
144 }
145 }
146
147 /** Start up request queue thread */
148
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800149 mRequestThread = new RequestThread(this, device);
150 res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800151 if (res != OK) {
152 ALOGE("%s: Camera %d: Unable to start request queue thread: %s (%d)",
153 __FUNCTION__, mId, strerror(-res), res);
154 device->common.close(&device->common);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800155 mRequestThread.clear();
156 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800157 return res;
158 }
159
160 /** Everything is good to go */
161
162 mDeviceInfo = info.static_camera_characteristics;
163 mHal3Device = device;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800164 mStatus = STATUS_IDLE;
165 mNextStreamId = 0;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800166
167 return OK;
168}
169
170status_t Camera3Device::disconnect() {
171 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800172 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800173
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800174 ALOGV("%s: E", __FUNCTION__);
175
176 status_t res;
177 if (mStatus == STATUS_UNINITIALIZED) return OK;
178
179 if (mStatus == STATUS_ACTIVE ||
180 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
181 res = mRequestThread->clearRepeatingRequests();
182 if (res != OK) {
183 ALOGE("%s: Can't stop streaming", __FUNCTION__);
184 return res;
185 }
186 res = waitUntilDrainedLocked();
187 if (res != OK) {
188 ALOGE("%s: Timeout waiting for HAL to drain", __FUNCTION__);
189 return res;
190 }
191 }
192 assert(mStatus == STATUS_IDLE || mStatus == STATUS_ERROR);
193
194 if (mRequestThread != NULL) {
195 mRequestThread->requestExit();
196 }
197
198 mOutputStreams.clear();
199 mInputStream.clear();
200
201 if (mRequestThread != NULL) {
202 mRequestThread->join();
203 mRequestThread.clear();
204 }
205
206 if (mHal3Device != NULL) {
207 mHal3Device->common.close(&mHal3Device->common);
208 mHal3Device = NULL;
209 }
210
211 mStatus = STATUS_UNINITIALIZED;
212
213 ALOGV("%s: X", __FUNCTION__);
214 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800215}
216
217status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
218 ATRACE_CALL();
219 (void)args;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800220 String8 lines;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800221
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800222 const char *status =
223 mStatus == STATUS_ERROR ? "ERROR" :
224 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
225 mStatus == STATUS_IDLE ? "IDLE" :
226 mStatus == STATUS_ACTIVE ? "ACTIVE" :
227 "Unknown";
228 lines.appendFormat(" Device status: %s\n", status);
229 lines.appendFormat(" Stream configuration:\n");
230
231 if (mInputStream != NULL) {
232 write(fd, lines.string(), lines.size());
233 mInputStream->dump(fd, args);
234 } else {
235 lines.appendFormat(" No input stream.\n");
236 write(fd, lines.string(), lines.size());
237 }
238 for (size_t i = 0; i < mOutputStreams.size(); i++) {
239 mOutputStreams[i]->dump(fd,args);
240 }
241
242 if (mHal3Device != NULL) {
243 lines = String8(" HAL device dump:\n");
244 write(fd, lines.string(), lines.size());
245 mHal3Device->ops->dump(mHal3Device, fd);
246 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800247
248 return OK;
249}
250
251const CameraMetadata& Camera3Device::info() const {
252 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800253 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
254 mStatus == STATUS_ERROR)) {
255 ALOGE("%s: Access to static info %s!", __FUNCTION__,
256 mStatus == STATUS_ERROR ?
257 "when in error state" : "before init");
258 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800259 return mDeviceInfo;
260}
261
262status_t Camera3Device::capture(CameraMetadata &request) {
263 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800264 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800265
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700266 // TODO: take ownership of the request
267
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800268 switch (mStatus) {
269 case STATUS_ERROR:
270 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
271 return INVALID_OPERATION;
272 case STATUS_UNINITIALIZED:
273 ALOGE("%s: Device not initialized", __FUNCTION__);
274 return INVALID_OPERATION;
275 case STATUS_IDLE:
276 case STATUS_ACTIVE:
277 // OK
278 break;
279 default:
280 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
281 return INVALID_OPERATION;
282 }
283
284 sp<CaptureRequest> newRequest = setUpRequestLocked(request);
285 if (newRequest == NULL) {
286 ALOGE("%s: Can't create capture request", __FUNCTION__);
287 return BAD_VALUE;
288 }
289
290 return mRequestThread->queueRequest(newRequest);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800291}
292
293
294status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) {
295 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800296 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800297
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800298 switch (mStatus) {
299 case STATUS_ERROR:
300 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
301 return INVALID_OPERATION;
302 case STATUS_UNINITIALIZED:
303 ALOGE("%s: Device not initialized", __FUNCTION__);
304 return INVALID_OPERATION;
305 case STATUS_IDLE:
306 case STATUS_ACTIVE:
307 // OK
308 break;
309 default:
310 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
311 return INVALID_OPERATION;
312 }
313
314 sp<CaptureRequest> newRepeatingRequest = setUpRequestLocked(request);
315 if (newRepeatingRequest == NULL) {
316 ALOGE("%s: Can't create repeating request", __FUNCTION__);
317 return BAD_VALUE;
318 }
319
320 RequestList newRepeatingRequests;
321 newRepeatingRequests.push_back(newRepeatingRequest);
322
323 return mRequestThread->setRepeatingRequests(newRepeatingRequests);
324}
325
326
327sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
328 const CameraMetadata &request) {
329 status_t res;
330
331 if (mStatus == STATUS_IDLE) {
332 res = configureStreamsLocked();
333 if (res != OK) {
334 ALOGE("%s: Can't set up streams: %s (%d)",
335 __FUNCTION__, strerror(-res), res);
336 return NULL;
337 }
338 }
339
340 sp<CaptureRequest> newRequest = createCaptureRequest(request);
341 return newRequest;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800342}
343
344status_t Camera3Device::clearStreamingRequest() {
345 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800346 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800347
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800348 switch (mStatus) {
349 case STATUS_ERROR:
350 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
351 return INVALID_OPERATION;
352 case STATUS_UNINITIALIZED:
353 ALOGE("%s: Device not initialized", __FUNCTION__);
354 return INVALID_OPERATION;
355 case STATUS_IDLE:
356 case STATUS_ACTIVE:
357 // OK
358 break;
359 default:
360 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
361 return INVALID_OPERATION;
362 }
363
364 return mRequestThread->clearRepeatingRequests();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800365}
366
367status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
368 ATRACE_CALL();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800369
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700370 return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800371}
372
Igor Murashkin0776a142013-04-15 14:59:22 -0700373status_t Camera3Device::createInputStream(
374 uint32_t width, uint32_t height, int format, int *id) {
375 ATRACE_CALL();
376 Mutex::Autolock l(mLock);
377
378 status_t res;
379 bool wasActive = false;
380
381 switch (mStatus) {
382 case STATUS_ERROR:
383 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
384 return INVALID_OPERATION;
385 case STATUS_UNINITIALIZED:
386 ALOGE("%s: Device not initialized", __FUNCTION__);
387 return INVALID_OPERATION;
388 case STATUS_IDLE:
389 // OK
390 break;
391 case STATUS_ACTIVE:
392 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
393 mRequestThread->setPaused(true);
394 res = waitUntilDrainedLocked();
395 if (res != OK) {
396 ALOGE("%s: Can't pause captures to reconfigure streams!",
397 __FUNCTION__);
398 mStatus = STATUS_ERROR;
399 return res;
400 }
401 wasActive = true;
402 break;
403 default:
404 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
405 return INVALID_OPERATION;
406 }
407 assert(mStatus == STATUS_IDLE);
408
409 if (mInputStream != 0) {
410 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
411 return INVALID_OPERATION;
412 }
413
414 sp<Camera3InputStream> newStream = new Camera3InputStream(mNextStreamId,
415 width, height, format);
416
417 mInputStream = newStream;
418
419 *id = mNextStreamId++;
420
421 // Continue captures if active at start
422 if (wasActive) {
423 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
424 res = configureStreamsLocked();
425 if (res != OK) {
426 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
427 __FUNCTION__, mNextStreamId, strerror(-res), res);
428 return res;
429 }
430 mRequestThread->setPaused(false);
431 }
432
433 return OK;
434}
435
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800436status_t Camera3Device::createStream(sp<ANativeWindow> consumer,
437 uint32_t width, uint32_t height, int format, size_t size, int *id) {
438 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800439 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800440
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800441 status_t res;
442 bool wasActive = false;
443
444 switch (mStatus) {
445 case STATUS_ERROR:
446 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
447 return INVALID_OPERATION;
448 case STATUS_UNINITIALIZED:
449 ALOGE("%s: Device not initialized", __FUNCTION__);
450 return INVALID_OPERATION;
451 case STATUS_IDLE:
452 // OK
453 break;
454 case STATUS_ACTIVE:
455 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
456 mRequestThread->setPaused(true);
457 res = waitUntilDrainedLocked();
458 if (res != OK) {
459 ALOGE("%s: Can't pause captures to reconfigure streams!",
460 __FUNCTION__);
461 mStatus = STATUS_ERROR;
462 return res;
463 }
464 wasActive = true;
465 break;
466 default:
467 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
468 return INVALID_OPERATION;
469 }
470 assert(mStatus == STATUS_IDLE);
471
472 sp<Camera3OutputStream> newStream;
473 if (format == HAL_PIXEL_FORMAT_BLOB) {
474 newStream = new Camera3OutputStream(mNextStreamId, consumer,
475 width, height, size, format);
476 } else {
477 newStream = new Camera3OutputStream(mNextStreamId, consumer,
478 width, height, format);
479 }
480
481 res = mOutputStreams.add(mNextStreamId, newStream);
482 if (res < 0) {
483 ALOGE("%s: Can't add new stream to set: %s (%d)",
484 __FUNCTION__, strerror(-res), res);
485 return res;
486 }
487
488 *id = mNextStreamId++;
489
490 // Continue captures if active at start
491 if (wasActive) {
492 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
493 res = configureStreamsLocked();
494 if (res != OK) {
495 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
496 __FUNCTION__, mNextStreamId, strerror(-res), res);
497 return res;
498 }
499 mRequestThread->setPaused(false);
500 }
501
502 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800503}
504
505status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
506 ATRACE_CALL();
507 (void)outputId; (void)id;
508
509 ALOGE("%s: Unimplemented", __FUNCTION__);
510 return INVALID_OPERATION;
511}
512
513
514status_t Camera3Device::getStreamInfo(int id,
515 uint32_t *width, uint32_t *height, uint32_t *format) {
516 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800517 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800518
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800519 switch (mStatus) {
520 case STATUS_ERROR:
521 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
522 return INVALID_OPERATION;
523 case STATUS_UNINITIALIZED:
524 ALOGE("%s: Device not initialized!", __FUNCTION__);
525 return INVALID_OPERATION;
526 case STATUS_IDLE:
527 case STATUS_ACTIVE:
528 // OK
529 break;
530 default:
531 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
532 return INVALID_OPERATION;
533 }
534
535 ssize_t idx = mOutputStreams.indexOfKey(id);
536 if (idx == NAME_NOT_FOUND) {
537 ALOGE("%s: Stream %d is unknown", __FUNCTION__, id);
538 return idx;
539 }
540
541 if (width) *width = mOutputStreams[idx]->getWidth();
542 if (height) *height = mOutputStreams[idx]->getHeight();
543 if (format) *format = mOutputStreams[idx]->getFormat();
544
545 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800546}
547
548status_t Camera3Device::setStreamTransform(int id,
549 int transform) {
550 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800551 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800552
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800553 switch (mStatus) {
554 case STATUS_ERROR:
555 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
556 return INVALID_OPERATION;
557 case STATUS_UNINITIALIZED:
558 ALOGE("%s: Device not initialized", __FUNCTION__);
559 return INVALID_OPERATION;
560 case STATUS_IDLE:
561 case STATUS_ACTIVE:
562 // OK
563 break;
564 default:
565 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
566 return INVALID_OPERATION;
567 }
568
569 ssize_t idx = mOutputStreams.indexOfKey(id);
570 if (idx == NAME_NOT_FOUND) {
571 ALOGE("%s: Stream %d does not exist",
572 __FUNCTION__, id);
573 return BAD_VALUE;
574 }
575
576 return mOutputStreams.editValueAt(idx)->setTransform(transform);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800577}
578
579status_t Camera3Device::deleteStream(int id) {
580 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800581 Mutex::Autolock l(mLock);
582 status_t res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800583
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800584 // CameraDevice semantics require device to already be idle before
585 // deleteStream is called, unlike for createStream.
586 if (mStatus != STATUS_IDLE) {
587 ALOGE("%s: Device not idle", __FUNCTION__);
588 return INVALID_OPERATION;
589 }
590
591 sp<Camera3Stream> deletedStream;
592 if (mInputStream != NULL && id == mInputStream->getId()) {
593 deletedStream = mInputStream;
594 mInputStream.clear();
595 } else {
596 ssize_t idx = mOutputStreams.indexOfKey(id);
597 if (idx == NAME_NOT_FOUND) {
598 ALOGE("%s: Stream %d does not exist",
599 __FUNCTION__, id);
600 return BAD_VALUE;
601 }
602 deletedStream = mOutputStreams.editValueAt(idx);
603 mOutputStreams.removeItem(id);
604 }
605
606 // Free up the stream endpoint so that it can be used by some other stream
607 res = deletedStream->disconnect();
608 if (res != OK) {
609 ALOGE("%s: Can't disconnect deleted stream", __FUNCTION__);
610 // fall through since we want to still list the stream as deleted.
611 }
612 mDeletedStreams.add(deletedStream);
613
614 return res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800615}
616
617status_t Camera3Device::deleteReprocessStream(int id) {
618 ATRACE_CALL();
619 (void)id;
620
621 ALOGE("%s: Unimplemented", __FUNCTION__);
622 return INVALID_OPERATION;
623}
624
625
626status_t Camera3Device::createDefaultRequest(int templateId,
627 CameraMetadata *request) {
628 ATRACE_CALL();
629 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800630 Mutex::Autolock l(mLock);
631
632 switch (mStatus) {
633 case STATUS_ERROR:
634 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
635 return INVALID_OPERATION;
636 case STATUS_UNINITIALIZED:
637 ALOGE("%s: Device is not initialized!", __FUNCTION__);
638 return INVALID_OPERATION;
639 case STATUS_IDLE:
640 case STATUS_ACTIVE:
641 // OK
642 break;
643 default:
644 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
645 return INVALID_OPERATION;
646 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800647
648 const camera_metadata_t *rawRequest;
649 rawRequest = mHal3Device->ops->construct_default_request_settings(
650 mHal3Device, templateId);
651 if (rawRequest == NULL) return DEAD_OBJECT;
652 *request = rawRequest;
653
654 return OK;
655}
656
657status_t Camera3Device::waitUntilDrained() {
658 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800659 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800660
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800661 return waitUntilDrainedLocked();
662}
663
664status_t Camera3Device::waitUntilDrainedLocked() {
665 ATRACE_CALL();
666 status_t res;
667
668 switch (mStatus) {
669 case STATUS_UNINITIALIZED:
670 case STATUS_IDLE:
671 ALOGV("%s: Already idle", __FUNCTION__);
672 return OK;
673 case STATUS_ERROR:
674 case STATUS_ACTIVE:
675 // Need to shut down
676 break;
677 default:
678 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
679 return INVALID_OPERATION;
680 }
681
682 if (mRequestThread != NULL) {
683 res = mRequestThread->waitUntilPaused(kShutdownTimeout);
684 if (res != OK) {
685 ALOGE("%s: Can't stop request thread in %f seconds!",
686 __FUNCTION__, kShutdownTimeout/1e9);
687 mStatus = STATUS_ERROR;
688 return res;
689 }
690 }
691 if (mInputStream != NULL) {
692 res = mInputStream->waitUntilIdle(kShutdownTimeout);
693 if (res != OK) {
694 ALOGE("%s: Can't idle input stream %d in %f seconds!",
695 __FUNCTION__, mInputStream->getId(), kShutdownTimeout/1e9);
696 mStatus = STATUS_ERROR;
697 return res;
698 }
699 }
700 for (size_t i = 0; i < mOutputStreams.size(); i++) {
701 res = mOutputStreams.editValueAt(i)->waitUntilIdle(kShutdownTimeout);
702 if (res != OK) {
703 ALOGE("%s: Can't idle output stream %d in %f seconds!",
704 __FUNCTION__, mOutputStreams.keyAt(i),
705 kShutdownTimeout/1e9);
706 mStatus = STATUS_ERROR;
707 return res;
708 }
709 }
710
711 if (mStatus != STATUS_ERROR) {
712 mStatus = STATUS_IDLE;
713 }
714
715 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800716}
717
718status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
719 ATRACE_CALL();
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700720 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800721
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700722 if (listener != NULL && mListener != NULL) {
723 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
724 }
725 mListener = listener;
726
727 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800728}
729
730status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700731 ATRACE_CALL();
732 status_t res;
733 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800734
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700735 while (mResultQueue.empty()) {
736 res = mResultSignal.waitRelative(mOutputLock, timeout);
737 if (res == TIMED_OUT) {
738 return res;
739 } else if (res != OK) {
740 ALOGE("%s: Camera %d: Error waiting for frame: %s (%d)",
741 __FUNCTION__, mId, strerror(-res), res);
742 return res;
743 }
744 }
745 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800746}
747
748status_t Camera3Device::getNextFrame(CameraMetadata *frame) {
749 ATRACE_CALL();
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700750 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800751
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700752 if (mResultQueue.empty()) {
753 return NOT_ENOUGH_DATA;
754 }
755
756 CameraMetadata &result = *(mResultQueue.begin());
757 frame->acquire(result);
758 mResultQueue.erase(mResultQueue.begin());
759
760 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800761}
762
763status_t Camera3Device::triggerAutofocus(uint32_t id) {
764 ATRACE_CALL();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800765
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700766 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
767 // Mix-in this trigger into the next request and only the next request.
768 RequestTrigger trigger[] = {
769 {
770 ANDROID_CONTROL_AF_TRIGGER,
771 ANDROID_CONTROL_AF_TRIGGER_START
772 },
773 {
774 ANDROID_CONTROL_AF_TRIGGER_ID,
775 static_cast<int32_t>(id)
776 },
777 };
778
779 return mRequestThread->queueTrigger(trigger,
780 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800781}
782
783status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
784 ATRACE_CALL();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800785
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700786 ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
787 // Mix-in this trigger into the next request and only the next request.
788 RequestTrigger trigger[] = {
789 {
790 ANDROID_CONTROL_AF_TRIGGER,
791 ANDROID_CONTROL_AF_TRIGGER_CANCEL
792 },
793 {
794 ANDROID_CONTROL_AF_TRIGGER_ID,
795 static_cast<int32_t>(id)
796 },
797 };
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800798
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700799 return mRequestThread->queueTrigger(trigger,
800 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800801}
802
803status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
804 ATRACE_CALL();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800805
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700806 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
807 // Mix-in this trigger into the next request and only the next request.
808 RequestTrigger trigger[] = {
809 {
810 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
811 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
812 },
813 {
814 ANDROID_CONTROL_AE_PRECAPTURE_ID,
815 static_cast<int32_t>(id)
816 },
817 };
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800818
Igor Murashkinb3a95a52013-04-01 17:29:07 -0700819 return mRequestThread->queueTrigger(trigger,
820 sizeof(trigger)/sizeof(trigger[0]));
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800821}
822
823status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
824 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
825 ATRACE_CALL();
826 (void)reprocessStreamId; (void)buffer; (void)listener;
827
828 ALOGE("%s: Unimplemented", __FUNCTION__);
829 return INVALID_OPERATION;
830}
831
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800832/**
833 * Camera3Device private methods
834 */
835
836sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
837 const CameraMetadata &request) {
838 ATRACE_CALL();
839 status_t res;
840
841 sp<CaptureRequest> newRequest = new CaptureRequest;
842 newRequest->mSettings = request;
843
844 camera_metadata_entry_t inputStreams =
845 newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
846 if (inputStreams.count > 0) {
847 if (mInputStream == NULL ||
848 mInputStream->getId() != inputStreams.data.u8[0]) {
849 ALOGE("%s: Request references unknown input stream %d",
850 __FUNCTION__, inputStreams.data.u8[0]);
851 return NULL;
852 }
853 // Lazy completion of stream configuration (allocation/registration)
854 // on first use
855 if (mInputStream->isConfiguring()) {
856 res = mInputStream->finishConfiguration(mHal3Device);
857 if (res != OK) {
858 ALOGE("%s: Unable to finish configuring input stream %d:"
859 " %s (%d)",
860 __FUNCTION__, mInputStream->getId(),
861 strerror(-res), res);
862 return NULL;
863 }
864 }
865
866 newRequest->mInputStream = mInputStream;
867 newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
868 }
869
870 camera_metadata_entry_t streams =
871 newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
872 if (streams.count == 0) {
873 ALOGE("%s: Zero output streams specified!", __FUNCTION__);
874 return NULL;
875 }
876
877 for (size_t i = 0; i < streams.count; i++) {
878 int idx = mOutputStreams.indexOfKey(streams.data.u8[i]);
879 if (idx == NAME_NOT_FOUND) {
880 ALOGE("%s: Request references unknown stream %d",
881 __FUNCTION__, streams.data.u8[i]);
882 return NULL;
883 }
884 sp<Camera3OutputStream> stream = mOutputStreams.editValueAt(idx);
885
886 // Lazy completion of stream configuration (allocation/registration)
887 // on first use
888 if (stream->isConfiguring()) {
889 res = stream->finishConfiguration(mHal3Device);
890 if (res != OK) {
891 ALOGE("%s: Unable to finish configuring stream %d: %s (%d)",
892 __FUNCTION__, stream->getId(), strerror(-res), res);
893 return NULL;
894 }
895 }
896
897 newRequest->mOutputStreams.push(stream);
898 }
899 newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
900
901 return newRequest;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800902}
903
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800904status_t Camera3Device::configureStreamsLocked() {
905 ATRACE_CALL();
906 status_t res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800907
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800908 if (mStatus != STATUS_IDLE) {
909 ALOGE("%s: Not idle", __FUNCTION__);
910 return INVALID_OPERATION;
911 }
912
913 // Start configuring the streams
914
915 camera3_stream_configuration config;
916
917 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
918
919 Vector<camera3_stream_t*> streams;
920 streams.setCapacity(config.num_streams);
921
922 if (mInputStream != NULL) {
923 camera3_stream_t *inputStream;
924 inputStream = mInputStream->startConfiguration();
925 if (inputStream == NULL) {
926 ALOGE("%s: Can't start input stream configuration",
927 __FUNCTION__);
928 // TODO: Make sure the error flow here is correct
929 return INVALID_OPERATION;
930 }
931 streams.add(inputStream);
932 }
933
934 for (size_t i = 0; i < mOutputStreams.size(); i++) {
935 camera3_stream_t *outputStream;
936 outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
937 if (outputStream == NULL) {
938 ALOGE("%s: Can't start output stream configuration",
939 __FUNCTION__);
940 // TODO: Make sure the error flow here is correct
941 return INVALID_OPERATION;
942 }
943 streams.add(outputStream);
944 }
945
946 config.streams = streams.editArray();
947
948 // Do the HAL configuration; will potentially touch stream
949 // max_buffers, usage, priv fields.
950
951 res = mHal3Device->ops->configure_streams(mHal3Device, &config);
952
953 if (res != OK) {
954 ALOGE("%s: Unable to configure streams with HAL: %s (%d)",
955 __FUNCTION__, strerror(-res), res);
956 return res;
957 }
958
959 // Request thread needs to know to avoid using repeat-last-settings protocol
960 // across configure_streams() calls
961 mRequestThread->configurationComplete();
962
963 // Finish configuring the streams lazily on first reference
964
965 mStatus = STATUS_ACTIVE;
966
967 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800968}
969
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800970
971/**
972 * Camera HAL device callback methods
973 */
974
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800975void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700976 ATRACE_CALL();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800977
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -0700978 status_t res;
979
980 if (result->result == NULL) {
981 // TODO: Report error upstream
982 ALOGW("%s: No metadata for frame %d", __FUNCTION__,
983 result->frame_number);
984 return;
985 }
986
987 nsecs_t timestamp = 0;
988 AlgState cur3aState;
989 AlgState new3aState;
990 int32_t aeTriggerId = 0;
991 int32_t afTriggerId = 0;
992
993 NotificationListener *listener;
994
995 {
996 Mutex::Autolock l(mOutputLock);
997
998 // Push result metadata into queue
999 mResultQueue.push_back(CameraMetadata());
Igor Murashkinb7c9d612013-04-02 12:32:32 -07001000 // Lets avoid copies! Too bad there's not a #back method
1001 CameraMetadata &captureResult = *(--mResultQueue.end());
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001002
1003 captureResult = result->result;
Igor Murashkinb7c9d612013-04-02 12:32:32 -07001004 if (captureResult.update(ANDROID_REQUEST_FRAME_COUNT,
1005 (int32_t*)&result->frame_number, 1) != OK) {
1006 ALOGE("%s: Camera %d: Failed to set frame# in metadata (%d)",
1007 __FUNCTION__, mId, result->frame_number);
1008 // TODO: Report error upstream
1009 } else {
1010 ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
1011 __FUNCTION__, mId, result->frame_number);
1012 }
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001013
1014 // Get timestamp from result metadata
1015
1016 camera_metadata_entry entry =
1017 captureResult.find(ANDROID_SENSOR_TIMESTAMP);
1018 if (entry.count == 0) {
1019 ALOGE("%s: Camera %d: No timestamp provided by HAL for frame %d!",
1020 __FUNCTION__, mId, result->frame_number);
1021 // TODO: Report error upstream
1022 } else {
1023 timestamp = entry.data.i64[0];
1024 }
1025
1026 // Get 3A states from result metadata
1027
1028 entry = captureResult.find(ANDROID_CONTROL_AE_STATE);
1029 if (entry.count == 0) {
1030 ALOGE("%s: Camera %d: No AE state provided by HAL for frame %d!",
1031 __FUNCTION__, mId, result->frame_number);
1032 } else {
1033 new3aState.aeState =
1034 static_cast<camera_metadata_enum_android_control_ae_state>(
1035 entry.data.u8[0]);
1036 }
1037
1038 entry = captureResult.find(ANDROID_CONTROL_AF_STATE);
1039 if (entry.count == 0) {
1040 ALOGE("%s: Camera %d: No AF state provided by HAL for frame %d!",
1041 __FUNCTION__, mId, result->frame_number);
1042 } else {
1043 new3aState.afState =
1044 static_cast<camera_metadata_enum_android_control_af_state>(
1045 entry.data.u8[0]);
1046 }
1047
1048 entry = captureResult.find(ANDROID_CONTROL_AWB_STATE);
1049 if (entry.count == 0) {
1050 ALOGE("%s: Camera %d: No AWB state provided by HAL for frame %d!",
1051 __FUNCTION__, mId, result->frame_number);
1052 } else {
1053 new3aState.awbState =
1054 static_cast<camera_metadata_enum_android_control_awb_state>(
1055 entry.data.u8[0]);
1056 }
1057
1058 entry = captureResult.find(ANDROID_CONTROL_AF_TRIGGER_ID);
1059 if (entry.count == 0) {
1060 ALOGE("%s: Camera %d: No AF trigger ID provided by HAL for frame %d!",
1061 __FUNCTION__, mId, result->frame_number);
1062 } else {
1063 afTriggerId = entry.data.i32[0];
1064 }
1065
1066 entry = captureResult.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
1067 if (entry.count == 0) {
1068 ALOGE("%s: Camera %d: No AE precapture trigger ID provided by HAL"
1069 " for frame %d!", __FUNCTION__, mId, result->frame_number);
1070 } else {
1071 aeTriggerId = entry.data.i32[0];
1072 }
1073
1074 listener = mListener;
1075 cur3aState = m3AState;
1076
1077 m3AState = new3aState;
1078 } // scope for mOutputLock
1079
1080 // Return completed buffers to their streams
1081 for (size_t i = 0; i < result->num_output_buffers; i++) {
1082 Camera3Stream *stream =
1083 Camera3Stream::cast(result->output_buffers[i].stream);
1084 res = stream->returnBuffer(result->output_buffers[i], timestamp);
1085 // Note: stream may be deallocated at this point, if this buffer was the
1086 // last reference to it.
1087 if (res != OK) {
1088 ALOGE("%s: Camera %d: Can't return buffer %d for frame %d to its"
1089 " stream:%s (%d)", __FUNCTION__, mId, i,
1090 result->frame_number, strerror(-res), res);
1091 // TODO: Report error upstream
1092 }
1093 }
1094
1095 // Dispatch any 3A change events to listeners
1096 if (listener != NULL) {
1097 if (new3aState.aeState != cur3aState.aeState) {
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001098 ALOGVV("%s: AE state changed from 0x%x to 0x%x",
1099 __FUNCTION__, cur3aState.aeState, new3aState.aeState);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001100 listener->notifyAutoExposure(new3aState.aeState, aeTriggerId);
1101 }
1102 if (new3aState.afState != cur3aState.afState) {
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001103 ALOGVV("%s: AF state changed from 0x%x to 0x%x",
1104 __FUNCTION__, cur3aState.afState, new3aState.afState);
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001105 listener->notifyAutoFocus(new3aState.afState, afTriggerId);
1106 }
1107 if (new3aState.awbState != cur3aState.awbState) {
1108 listener->notifyAutoWhitebalance(new3aState.awbState, aeTriggerId);
1109 }
1110 }
1111
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001112}
1113
1114void Camera3Device::notify(const camera3_notify_msg *msg) {
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001115 NotificationListener *listener;
1116 {
1117 Mutex::Autolock l(mOutputLock);
1118 if (mListener == NULL) return;
1119 listener = mListener;
1120 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001121
Eino-Ville Talvalad0158c32013-03-11 14:13:50 -07001122 if (msg == NULL) {
1123 ALOGE("%s: Camera %d: HAL sent NULL notify message!",
1124 __FUNCTION__, mId);
1125 return;
1126 }
1127
1128 switch (msg->type) {
1129 case CAMERA3_MSG_ERROR: {
1130 int streamId = 0;
1131 if (msg->message.error.error_stream != NULL) {
1132 Camera3Stream *stream =
1133 Camera3Stream::cast(
1134 msg->message.error.error_stream);
1135 streamId = stream->getId();
1136 }
1137 listener->notifyError(msg->message.error.error_code,
1138 msg->message.error.frame_number, streamId);
1139 break;
1140 }
1141 case CAMERA3_MSG_SHUTTER: {
1142 listener->notifyShutter(msg->message.shutter.frame_number,
1143 msg->message.shutter.timestamp);
1144 break;
1145 }
1146 default:
1147 ALOGE("%s: Camera %d: Unknown notify message from HAL: %d",
1148 __FUNCTION__, mId, msg->type);
1149 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001150}
1151
1152/**
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001153 * RequestThread inner class methods
1154 */
1155
1156Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
1157 camera3_device_t *hal3Device) :
1158 Thread(false),
1159 mParent(parent),
1160 mHal3Device(hal3Device),
1161 mReconfigured(false),
1162 mDoPause(false),
1163 mPaused(true),
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001164 mFrameNumber(0),
1165 mLatestRequestId(NAME_NOT_FOUND) {
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001166}
1167
1168void Camera3Device::RequestThread::configurationComplete() {
1169 Mutex::Autolock l(mRequestLock);
1170 mReconfigured = true;
1171}
1172
1173status_t Camera3Device::RequestThread::queueRequest(
1174 sp<CaptureRequest> request) {
1175 Mutex::Autolock l(mRequestLock);
1176 mRequestQueue.push_back(request);
1177
1178 return OK;
1179}
1180
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001181
1182status_t Camera3Device::RequestThread::queueTrigger(
1183 RequestTrigger trigger[],
1184 size_t count) {
1185
1186 Mutex::Autolock l(mTriggerMutex);
1187 status_t ret;
1188
1189 for (size_t i = 0; i < count; ++i) {
1190 ret = queueTriggerLocked(trigger[i]);
1191
1192 if (ret != OK) {
1193 return ret;
1194 }
1195 }
1196
1197 return OK;
1198}
1199
1200status_t Camera3Device::RequestThread::queueTriggerLocked(
1201 RequestTrigger trigger) {
1202
1203 uint32_t tag = trigger.metadataTag;
1204 ssize_t index = mTriggerMap.indexOfKey(tag);
1205
1206 switch (trigger.getTagType()) {
1207 case TYPE_BYTE:
1208 // fall-through
1209 case TYPE_INT32:
1210 break;
1211 default:
1212 ALOGE("%s: Type not supported: 0x%x",
1213 __FUNCTION__,
1214 trigger.getTagType());
1215 return INVALID_OPERATION;
1216 }
1217
1218 /**
1219 * Collect only the latest trigger, since we only have 1 field
1220 * in the request settings per trigger tag, and can't send more than 1
1221 * trigger per request.
1222 */
1223 if (index != NAME_NOT_FOUND) {
1224 mTriggerMap.editValueAt(index) = trigger;
1225 } else {
1226 mTriggerMap.add(tag, trigger);
1227 }
1228
1229 return OK;
1230}
1231
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001232status_t Camera3Device::RequestThread::setRepeatingRequests(
1233 const RequestList &requests) {
1234 Mutex::Autolock l(mRequestLock);
1235 mRepeatingRequests.clear();
1236 mRepeatingRequests.insert(mRepeatingRequests.begin(),
1237 requests.begin(), requests.end());
1238 return OK;
1239}
1240
1241status_t Camera3Device::RequestThread::clearRepeatingRequests() {
1242 Mutex::Autolock l(mRequestLock);
1243 mRepeatingRequests.clear();
1244 return OK;
1245}
1246
1247void Camera3Device::RequestThread::setPaused(bool paused) {
1248 Mutex::Autolock l(mPauseLock);
1249 mDoPause = paused;
1250 mDoPauseSignal.signal();
1251}
1252
1253status_t Camera3Device::RequestThread::waitUntilPaused(nsecs_t timeout) {
1254 status_t res;
1255 Mutex::Autolock l(mPauseLock);
1256 while (!mPaused) {
1257 res = mPausedSignal.waitRelative(mPauseLock, timeout);
1258 if (res == TIMED_OUT) {
1259 return res;
1260 }
1261 }
1262 return OK;
1263}
1264
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001265status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
1266 int32_t requestId, nsecs_t timeout) {
1267 Mutex::Autolock l(mLatestRequestMutex);
1268 status_t res;
1269 while (mLatestRequestId != requestId) {
1270 nsecs_t startTime = systemTime();
1271
1272 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
1273 if (res != OK) return res;
1274
1275 timeout -= (systemTime() - startTime);
1276 }
1277
1278 return OK;
1279}
1280
1281
1282
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001283bool Camera3Device::RequestThread::threadLoop() {
1284
1285 status_t res;
1286
1287 // Handle paused state.
1288 if (waitIfPaused()) {
1289 return true;
1290 }
1291
1292 // Get work to do
1293
1294 sp<CaptureRequest> nextRequest = waitForNextRequest();
1295 if (nextRequest == NULL) {
1296 return true;
1297 }
1298
1299 // Create request to HAL
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001300 camera3_capture_request_t request = camera3_capture_request_t();
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001301 Vector<camera3_stream_buffer_t> outputBuffers;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001302
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001303 // Insert any queued triggers (before metadata is locked)
1304 int32_t triggerCount;
1305 res = insertTriggers(nextRequest);
1306 if (res < 0) {
1307 ALOGE("RequestThread: Unable to insert triggers "
1308 "(capture request %d, HAL device: %s (%d)",
1309 (mFrameNumber+1), strerror(-res), res);
1310 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1311 return false;
1312 }
1313 triggerCount = res;
1314
1315 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
1316
1317 // If the request is the same as last, or we had triggers last time
1318 if (mPrevRequest != nextRequest || triggersMixedIn) {
1319 /**
1320 * The request should be presorted so accesses in HAL
1321 * are O(logn). Sidenote, sorting a sorted metadata is nop.
1322 */
1323 nextRequest->mSettings.sort();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001324 request.settings = nextRequest->mSettings.getAndLock();
1325 mPrevRequest = nextRequest;
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001326 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
1327
1328 IF_ALOGV() {
1329 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
1330 find_camera_metadata_ro_entry(
1331 request.settings,
1332 ANDROID_CONTROL_AF_TRIGGER,
1333 &e
1334 );
1335 if (e.count > 0) {
1336 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
1337 __FUNCTION__,
1338 mFrameNumber+1,
1339 e.data.u8[0]);
1340 }
1341 }
1342 } else {
1343 // leave request.settings NULL to indicate 'reuse latest given'
1344 ALOGVV("%s: Request settings are REUSED",
1345 __FUNCTION__);
1346 }
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001347
1348 camera3_stream_buffer_t inputBuffer;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001349
1350 // Fill in buffers
1351
1352 if (nextRequest->mInputStream != NULL) {
1353 request.input_buffer = &inputBuffer;
Igor Murashkin0776a142013-04-15 14:59:22 -07001354 res = nextRequest->mInputStream->getInputBuffer(&inputBuffer);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001355 if (res != OK) {
1356 ALOGE("RequestThread: Can't get input buffer, skipping request:"
1357 " %s (%d)", strerror(-res), res);
1358 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1359 return true;
1360 }
1361 } else {
1362 request.input_buffer = NULL;
1363 }
1364
1365 outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
1366 nextRequest->mOutputStreams.size());
1367 request.output_buffers = outputBuffers.array();
1368 for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
1369 res = nextRequest->mOutputStreams.editItemAt(i)->
1370 getBuffer(&outputBuffers.editItemAt(i));
1371 if (res != OK) {
1372 ALOGE("RequestThread: Can't get output buffer, skipping request:"
1373 "%s (%d)", strerror(-res), res);
1374 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1375 return true;
1376 }
1377 request.num_output_buffers++;
1378 }
1379
1380 request.frame_number = mFrameNumber++;
1381
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001382
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001383 // Submit request and block until ready for next one
1384
1385 res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
1386 if (res != OK) {
1387 ALOGE("RequestThread: Unable to submit capture request %d to HAL"
1388 " device: %s (%d)", request.frame_number, strerror(-res), res);
1389 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1390 return false;
1391 }
1392
1393 if (request.settings != NULL) {
1394 nextRequest->mSettings.unlock(request.settings);
1395 }
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001396
1397 // Remove any previously queued triggers (after unlock)
1398 res = removeTriggers(mPrevRequest);
1399 if (res != OK) {
1400 ALOGE("RequestThread: Unable to remove triggers "
1401 "(capture request %d, HAL device: %s (%d)",
1402 request.frame_number, strerror(-res), res);
1403 return false;
1404 }
1405 mPrevTriggers = triggerCount;
1406
1407 // Read android.request.id from the request settings metadata
1408 // - inform waitUntilRequestProcessed thread of a new request ID
1409 {
1410 Mutex::Autolock al(mLatestRequestMutex);
1411
1412 camera_metadata_entry_t requestIdEntry =
1413 nextRequest->mSettings.find(ANDROID_REQUEST_ID);
1414 if (requestIdEntry.count > 0) {
1415 mLatestRequestId = requestIdEntry.data.i32[0];
1416 } else {
1417 ALOGW("%s: Did not have android.request.id set in the request",
1418 __FUNCTION__);
1419 mLatestRequestId = NAME_NOT_FOUND;
1420 }
1421
1422 mLatestRequestSignal.signal();
1423 }
1424
Igor Murashkin0776a142013-04-15 14:59:22 -07001425 // Return input buffer back to framework
1426 if (request.input_buffer != NULL) {
1427 Camera3Stream *stream =
1428 Camera3Stream::cast(request.input_buffer->stream);
1429 res = stream->returnInputBuffer(*(request.input_buffer));
1430 // Note: stream may be deallocated at this point, if this buffer was the
1431 // last reference to it.
1432 if (res != OK) {
1433 ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
1434 " its stream:%s (%d)", __FUNCTION__,
1435 request.frame_number, strerror(-res), res);
1436 // TODO: Report error upstream
1437 }
1438 }
1439
1440
1441
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001442 return true;
1443}
1444
1445void Camera3Device::RequestThread::cleanUpFailedRequest(
1446 camera3_capture_request_t &request,
1447 sp<CaptureRequest> &nextRequest,
1448 Vector<camera3_stream_buffer_t> &outputBuffers) {
1449
1450 if (request.settings != NULL) {
1451 nextRequest->mSettings.unlock(request.settings);
1452 }
1453 if (request.input_buffer != NULL) {
1454 request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
Igor Murashkin0776a142013-04-15 14:59:22 -07001455 nextRequest->mInputStream->returnInputBuffer(*(request.input_buffer));
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001456 }
1457 for (size_t i = 0; i < request.num_output_buffers; i++) {
1458 outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
1459 nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
1460 outputBuffers[i], 0);
1461 }
1462 // TODO: Report error upstream
1463}
1464
1465sp<Camera3Device::CaptureRequest>
1466 Camera3Device::RequestThread::waitForNextRequest() {
1467 status_t res;
1468 sp<CaptureRequest> nextRequest;
1469
1470 // Optimized a bit for the simple steady-state case (single repeating
1471 // request), to avoid putting that request in the queue temporarily.
1472 Mutex::Autolock l(mRequestLock);
1473
1474 while (mRequestQueue.empty()) {
1475 if (!mRepeatingRequests.empty()) {
1476 // Always atomically enqueue all requests in a repeating request
1477 // list. Guarantees a complete in-sequence set of captures to
1478 // application.
1479 const RequestList &requests = mRepeatingRequests;
1480 RequestList::const_iterator firstRequest =
1481 requests.begin();
1482 nextRequest = *firstRequest;
1483 mRequestQueue.insert(mRequestQueue.end(),
1484 ++firstRequest,
1485 requests.end());
1486 // No need to wait any longer
1487 break;
1488 }
1489
1490 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
1491
1492 if (res == TIMED_OUT) {
1493 // Signal that we're paused by starvation
1494 Mutex::Autolock pl(mPauseLock);
1495 if (mPaused == false) {
1496 mPaused = true;
1497 mPausedSignal.signal();
1498 }
1499 // Stop waiting for now and let thread management happen
1500 return NULL;
1501 }
1502 }
1503
1504 if (nextRequest == NULL) {
1505 // Don't have a repeating request already in hand, so queue
1506 // must have an entry now.
1507 RequestList::iterator firstRequest =
1508 mRequestQueue.begin();
1509 nextRequest = *firstRequest;
1510 mRequestQueue.erase(firstRequest);
1511 }
1512
1513 // Not paused
1514 Mutex::Autolock pl(mPauseLock);
1515 mPaused = false;
1516
1517 // Check if we've reconfigured since last time, and reset the preview
1518 // request if so. Can't use 'NULL request == repeat' across configure calls.
1519 if (mReconfigured) {
1520 mPrevRequest.clear();
1521 mReconfigured = false;
1522 }
1523
1524 return nextRequest;
1525}
1526
1527bool Camera3Device::RequestThread::waitIfPaused() {
1528 status_t res;
1529 Mutex::Autolock l(mPauseLock);
1530 while (mDoPause) {
1531 // Signal that we're paused by request
1532 if (mPaused == false) {
1533 mPaused = true;
1534 mPausedSignal.signal();
1535 }
1536 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
1537 if (res == TIMED_OUT) {
1538 return true;
1539 }
1540 }
1541 // We don't set mPaused to false here, because waitForNextRequest needs
1542 // to further manage the paused state in case of starvation.
1543 return false;
1544}
1545
Igor Murashkinb3a95a52013-04-01 17:29:07 -07001546status_t Camera3Device::RequestThread::insertTriggers(
1547 const sp<CaptureRequest> &request) {
1548
1549 Mutex::Autolock al(mTriggerMutex);
1550
1551 CameraMetadata &metadata = request->mSettings;
1552 size_t count = mTriggerMap.size();
1553
1554 for (size_t i = 0; i < count; ++i) {
1555 RequestTrigger trigger = mTriggerMap.valueAt(i);
1556
1557 uint32_t tag = trigger.metadataTag;
1558 camera_metadata_entry entry = metadata.find(tag);
1559
1560 if (entry.count > 0) {
1561 /**
1562 * Already has an entry for this trigger in the request.
1563 * Rewrite it with our requested trigger value.
1564 */
1565 RequestTrigger oldTrigger = trigger;
1566
1567 oldTrigger.entryValue = entry.data.u8[0];
1568
1569 mTriggerReplacedMap.add(tag, oldTrigger);
1570 } else {
1571 /**
1572 * More typical, no trigger entry, so we just add it
1573 */
1574 mTriggerRemovedMap.add(tag, trigger);
1575 }
1576
1577 status_t res;
1578
1579 switch (trigger.getTagType()) {
1580 case TYPE_BYTE: {
1581 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
1582 res = metadata.update(tag,
1583 &entryValue,
1584 /*count*/1);
1585 break;
1586 }
1587 case TYPE_INT32:
1588 res = metadata.update(tag,
1589 &trigger.entryValue,
1590 /*count*/1);
1591 break;
1592 default:
1593 ALOGE("%s: Type not supported: 0x%x",
1594 __FUNCTION__,
1595 trigger.getTagType());
1596 return INVALID_OPERATION;
1597 }
1598
1599 if (res != OK) {
1600 ALOGE("%s: Failed to update request metadata with trigger tag %s"
1601 ", value %d", __FUNCTION__, trigger.getTagName(),
1602 trigger.entryValue);
1603 return res;
1604 }
1605
1606 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
1607 trigger.getTagName(),
1608 trigger.entryValue);
1609 }
1610
1611 mTriggerMap.clear();
1612
1613 return count;
1614}
1615
1616status_t Camera3Device::RequestThread::removeTriggers(
1617 const sp<CaptureRequest> &request) {
1618 Mutex::Autolock al(mTriggerMutex);
1619
1620 CameraMetadata &metadata = request->mSettings;
1621
1622 /**
1623 * Replace all old entries with their old values.
1624 */
1625 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
1626 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
1627
1628 status_t res;
1629
1630 uint32_t tag = trigger.metadataTag;
1631 switch (trigger.getTagType()) {
1632 case TYPE_BYTE: {
1633 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
1634 res = metadata.update(tag,
1635 &entryValue,
1636 /*count*/1);
1637 break;
1638 }
1639 case TYPE_INT32:
1640 res = metadata.update(tag,
1641 &trigger.entryValue,
1642 /*count*/1);
1643 break;
1644 default:
1645 ALOGE("%s: Type not supported: 0x%x",
1646 __FUNCTION__,
1647 trigger.getTagType());
1648 return INVALID_OPERATION;
1649 }
1650
1651 if (res != OK) {
1652 ALOGE("%s: Failed to restore request metadata with trigger tag %s"
1653 ", trigger value %d", __FUNCTION__,
1654 trigger.getTagName(), trigger.entryValue);
1655 return res;
1656 }
1657 }
1658 mTriggerReplacedMap.clear();
1659
1660 /**
1661 * Remove all new entries.
1662 */
1663 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
1664 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
1665 status_t res = metadata.erase(trigger.metadataTag);
1666
1667 if (res != OK) {
1668 ALOGE("%s: Failed to erase metadata with trigger tag %s"
1669 ", trigger value %d", __FUNCTION__,
1670 trigger.getTagName(), trigger.entryValue);
1671 return res;
1672 }
1673 }
1674 mTriggerRemovedMap.clear();
1675
1676 return OK;
1677}
1678
1679
1680
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -08001681/**
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001682 * Static callback forwarding methods from HAL to instance
1683 */
1684
1685void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
1686 const camera3_capture_result *result) {
1687 Camera3Device *d =
1688 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1689 d->processCaptureResult(result);
1690}
1691
1692void Camera3Device::sNotify(const camera3_callback_ops *cb,
1693 const camera3_notify_msg *msg) {
1694 Camera3Device *d =
1695 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1696 d->notify(msg);
1697}
1698
1699}; // namespace android