blob: e6fb33e52319ccb190d126a702ba390aa6a7c69d [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"
33
34using namespace android::camera3;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080035
36namespace android {
37
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080038Camera3Device::Camera3Device(int id):
39 mId(id),
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080040 mHal3Device(NULL),
41 mStatus(STATUS_UNINITIALIZED)
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080042{
43 ATRACE_CALL();
44 camera3_callback_ops::notify = &sNotify;
45 camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
46 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
47}
48
49Camera3Device::~Camera3Device()
50{
51 ATRACE_CALL();
52 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
53 disconnect();
54}
55
Igor Murashkince124da2013-03-04 14:53:08 -080056int Camera3Device::getId() const {
57 return mId;
58}
59
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080060/**
61 * CameraDeviceBase interface
62 */
63
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080064status_t Camera3Device::initialize(camera_module_t *module)
65{
66 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080067 Mutex::Autolock l(mLock);
68
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080069 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080070 if (mStatus != STATUS_UNINITIALIZED) {
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080071 ALOGE("%s: Already initialized!", __FUNCTION__);
72 return INVALID_OPERATION;
73 }
74
75 /** Open HAL device */
76
77 status_t res;
78 String8 deviceName = String8::format("%d", mId);
79
80 camera3_device_t *device;
81
82 res = module->common.methods->open(&module->common, deviceName.string(),
83 reinterpret_cast<hw_device_t**>(&device));
84
85 if (res != OK) {
86 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
87 mId, strerror(-res), res);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -080088 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -080089 return res;
90 }
91
92 /** Cross-check device version */
93
94 if (device->common.version != CAMERA_DEVICE_API_VERSION_3_0) {
95 ALOGE("%s: Could not open camera %d: "
96 "Camera device is not version %x, reports %x instead",
97 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_3_0,
98 device->common.version);
99 device->common.close(&device->common);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800100 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800101 return BAD_VALUE;
102 }
103
104 camera_info info;
105 res = module->get_camera_info(mId, &info);
106 if (res != OK) return res;
107
108 if (info.device_version != device->common.version) {
109 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
110 " and device version (%x).", __FUNCTION__,
111 device->common.version, info.device_version);
112 device->common.close(&device->common);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800113 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800114 return BAD_VALUE;
115 }
116
117 /** Initialize device with callback functions */
118
119 res = device->ops->initialize(device, this);
120 if (res != OK) {
121 ALOGE("%s: Camera %d: Unable to initialize HAL device: %s (%d)",
122 __FUNCTION__, mId, strerror(-res), res);
123 device->common.close(&device->common);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800124 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800125 return BAD_VALUE;
126 }
127
128 /** Get vendor metadata tags */
129
130 mVendorTagOps.get_camera_vendor_section_name = NULL;
131
132 device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
133
134 if (mVendorTagOps.get_camera_vendor_section_name != NULL) {
135 res = set_camera_metadata_vendor_tag_ops(&mVendorTagOps);
136 if (res != OK) {
137 ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
138 __FUNCTION__, mId, strerror(-res), res);
139 device->common.close(&device->common);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800140 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800141 return res;
142 }
143 }
144
145 /** Start up request queue thread */
146
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800147 mRequestThread = new RequestThread(this, device);
148 res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800149 if (res != OK) {
150 ALOGE("%s: Camera %d: Unable to start request queue thread: %s (%d)",
151 __FUNCTION__, mId, strerror(-res), res);
152 device->common.close(&device->common);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800153 mRequestThread.clear();
154 mStatus = STATUS_ERROR;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800155 return res;
156 }
157
158 /** Everything is good to go */
159
160 mDeviceInfo = info.static_camera_characteristics;
161 mHal3Device = device;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800162 mStatus = STATUS_IDLE;
163 mNextStreamId = 0;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800164
165 return OK;
166}
167
168status_t Camera3Device::disconnect() {
169 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800170 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800171
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800172 ALOGV("%s: E", __FUNCTION__);
173
174 status_t res;
175 if (mStatus == STATUS_UNINITIALIZED) return OK;
176
177 if (mStatus == STATUS_ACTIVE ||
178 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
179 res = mRequestThread->clearRepeatingRequests();
180 if (res != OK) {
181 ALOGE("%s: Can't stop streaming", __FUNCTION__);
182 return res;
183 }
184 res = waitUntilDrainedLocked();
185 if (res != OK) {
186 ALOGE("%s: Timeout waiting for HAL to drain", __FUNCTION__);
187 return res;
188 }
189 }
190 assert(mStatus == STATUS_IDLE || mStatus == STATUS_ERROR);
191
192 if (mRequestThread != NULL) {
193 mRequestThread->requestExit();
194 }
195
196 mOutputStreams.clear();
197 mInputStream.clear();
198
199 if (mRequestThread != NULL) {
200 mRequestThread->join();
201 mRequestThread.clear();
202 }
203
204 if (mHal3Device != NULL) {
205 mHal3Device->common.close(&mHal3Device->common);
206 mHal3Device = NULL;
207 }
208
209 mStatus = STATUS_UNINITIALIZED;
210
211 ALOGV("%s: X", __FUNCTION__);
212 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800213}
214
215status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
216 ATRACE_CALL();
217 (void)args;
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800218 String8 lines;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800219
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800220 const char *status =
221 mStatus == STATUS_ERROR ? "ERROR" :
222 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
223 mStatus == STATUS_IDLE ? "IDLE" :
224 mStatus == STATUS_ACTIVE ? "ACTIVE" :
225 "Unknown";
226 lines.appendFormat(" Device status: %s\n", status);
227 lines.appendFormat(" Stream configuration:\n");
228
229 if (mInputStream != NULL) {
230 write(fd, lines.string(), lines.size());
231 mInputStream->dump(fd, args);
232 } else {
233 lines.appendFormat(" No input stream.\n");
234 write(fd, lines.string(), lines.size());
235 }
236 for (size_t i = 0; i < mOutputStreams.size(); i++) {
237 mOutputStreams[i]->dump(fd,args);
238 }
239
240 if (mHal3Device != NULL) {
241 lines = String8(" HAL device dump:\n");
242 write(fd, lines.string(), lines.size());
243 mHal3Device->ops->dump(mHal3Device, fd);
244 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800245
246 return OK;
247}
248
249const CameraMetadata& Camera3Device::info() const {
250 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800251 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
252 mStatus == STATUS_ERROR)) {
253 ALOGE("%s: Access to static info %s!", __FUNCTION__,
254 mStatus == STATUS_ERROR ?
255 "when in error state" : "before init");
256 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800257 return mDeviceInfo;
258}
259
260status_t Camera3Device::capture(CameraMetadata &request) {
261 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800262 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800263
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800264 switch (mStatus) {
265 case STATUS_ERROR:
266 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
267 return INVALID_OPERATION;
268 case STATUS_UNINITIALIZED:
269 ALOGE("%s: Device not initialized", __FUNCTION__);
270 return INVALID_OPERATION;
271 case STATUS_IDLE:
272 case STATUS_ACTIVE:
273 // OK
274 break;
275 default:
276 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
277 return INVALID_OPERATION;
278 }
279
280 sp<CaptureRequest> newRequest = setUpRequestLocked(request);
281 if (newRequest == NULL) {
282 ALOGE("%s: Can't create capture request", __FUNCTION__);
283 return BAD_VALUE;
284 }
285
286 return mRequestThread->queueRequest(newRequest);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800287}
288
289
290status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) {
291 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800292 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800293
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800294 switch (mStatus) {
295 case STATUS_ERROR:
296 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
297 return INVALID_OPERATION;
298 case STATUS_UNINITIALIZED:
299 ALOGE("%s: Device not initialized", __FUNCTION__);
300 return INVALID_OPERATION;
301 case STATUS_IDLE:
302 case STATUS_ACTIVE:
303 // OK
304 break;
305 default:
306 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
307 return INVALID_OPERATION;
308 }
309
310 sp<CaptureRequest> newRepeatingRequest = setUpRequestLocked(request);
311 if (newRepeatingRequest == NULL) {
312 ALOGE("%s: Can't create repeating request", __FUNCTION__);
313 return BAD_VALUE;
314 }
315
316 RequestList newRepeatingRequests;
317 newRepeatingRequests.push_back(newRepeatingRequest);
318
319 return mRequestThread->setRepeatingRequests(newRepeatingRequests);
320}
321
322
323sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
324 const CameraMetadata &request) {
325 status_t res;
326
327 if (mStatus == STATUS_IDLE) {
328 res = configureStreamsLocked();
329 if (res != OK) {
330 ALOGE("%s: Can't set up streams: %s (%d)",
331 __FUNCTION__, strerror(-res), res);
332 return NULL;
333 }
334 }
335
336 sp<CaptureRequest> newRequest = createCaptureRequest(request);
337 return newRequest;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800338}
339
340status_t Camera3Device::clearStreamingRequest() {
341 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800342 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800343
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800344 switch (mStatus) {
345 case STATUS_ERROR:
346 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
347 return INVALID_OPERATION;
348 case STATUS_UNINITIALIZED:
349 ALOGE("%s: Device not initialized", __FUNCTION__);
350 return INVALID_OPERATION;
351 case STATUS_IDLE:
352 case STATUS_ACTIVE:
353 // OK
354 break;
355 default:
356 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
357 return INVALID_OPERATION;
358 }
359
360 return mRequestThread->clearRepeatingRequests();
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800361}
362
363status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
364 ATRACE_CALL();
365 (void)requestId; (void)timeout;
366
367 ALOGE("%s: Unimplemented", __FUNCTION__);
368 return INVALID_OPERATION;
369}
370
371status_t Camera3Device::createStream(sp<ANativeWindow> consumer,
372 uint32_t width, uint32_t height, int format, size_t size, int *id) {
373 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800374 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800375
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800376 status_t res;
377 bool wasActive = false;
378
379 switch (mStatus) {
380 case STATUS_ERROR:
381 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
382 return INVALID_OPERATION;
383 case STATUS_UNINITIALIZED:
384 ALOGE("%s: Device not initialized", __FUNCTION__);
385 return INVALID_OPERATION;
386 case STATUS_IDLE:
387 // OK
388 break;
389 case STATUS_ACTIVE:
390 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
391 mRequestThread->setPaused(true);
392 res = waitUntilDrainedLocked();
393 if (res != OK) {
394 ALOGE("%s: Can't pause captures to reconfigure streams!",
395 __FUNCTION__);
396 mStatus = STATUS_ERROR;
397 return res;
398 }
399 wasActive = true;
400 break;
401 default:
402 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
403 return INVALID_OPERATION;
404 }
405 assert(mStatus == STATUS_IDLE);
406
407 sp<Camera3OutputStream> newStream;
408 if (format == HAL_PIXEL_FORMAT_BLOB) {
409 newStream = new Camera3OutputStream(mNextStreamId, consumer,
410 width, height, size, format);
411 } else {
412 newStream = new Camera3OutputStream(mNextStreamId, consumer,
413 width, height, format);
414 }
415
416 res = mOutputStreams.add(mNextStreamId, newStream);
417 if (res < 0) {
418 ALOGE("%s: Can't add new stream to set: %s (%d)",
419 __FUNCTION__, strerror(-res), res);
420 return res;
421 }
422
423 *id = mNextStreamId++;
424
425 // Continue captures if active at start
426 if (wasActive) {
427 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
428 res = configureStreamsLocked();
429 if (res != OK) {
430 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
431 __FUNCTION__, mNextStreamId, strerror(-res), res);
432 return res;
433 }
434 mRequestThread->setPaused(false);
435 }
436
437 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800438}
439
440status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
441 ATRACE_CALL();
442 (void)outputId; (void)id;
443
444 ALOGE("%s: Unimplemented", __FUNCTION__);
445 return INVALID_OPERATION;
446}
447
448
449status_t Camera3Device::getStreamInfo(int id,
450 uint32_t *width, uint32_t *height, uint32_t *format) {
451 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800452 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800453
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800454 switch (mStatus) {
455 case STATUS_ERROR:
456 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
457 return INVALID_OPERATION;
458 case STATUS_UNINITIALIZED:
459 ALOGE("%s: Device not initialized!", __FUNCTION__);
460 return INVALID_OPERATION;
461 case STATUS_IDLE:
462 case STATUS_ACTIVE:
463 // OK
464 break;
465 default:
466 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
467 return INVALID_OPERATION;
468 }
469
470 ssize_t idx = mOutputStreams.indexOfKey(id);
471 if (idx == NAME_NOT_FOUND) {
472 ALOGE("%s: Stream %d is unknown", __FUNCTION__, id);
473 return idx;
474 }
475
476 if (width) *width = mOutputStreams[idx]->getWidth();
477 if (height) *height = mOutputStreams[idx]->getHeight();
478 if (format) *format = mOutputStreams[idx]->getFormat();
479
480 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800481}
482
483status_t Camera3Device::setStreamTransform(int id,
484 int transform) {
485 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800486 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800487
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800488 switch (mStatus) {
489 case STATUS_ERROR:
490 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
491 return INVALID_OPERATION;
492 case STATUS_UNINITIALIZED:
493 ALOGE("%s: Device not initialized", __FUNCTION__);
494 return INVALID_OPERATION;
495 case STATUS_IDLE:
496 case STATUS_ACTIVE:
497 // OK
498 break;
499 default:
500 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
501 return INVALID_OPERATION;
502 }
503
504 ssize_t idx = mOutputStreams.indexOfKey(id);
505 if (idx == NAME_NOT_FOUND) {
506 ALOGE("%s: Stream %d does not exist",
507 __FUNCTION__, id);
508 return BAD_VALUE;
509 }
510
511 return mOutputStreams.editValueAt(idx)->setTransform(transform);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800512}
513
514status_t Camera3Device::deleteStream(int id) {
515 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800516 Mutex::Autolock l(mLock);
517 status_t res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800518
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800519 // CameraDevice semantics require device to already be idle before
520 // deleteStream is called, unlike for createStream.
521 if (mStatus != STATUS_IDLE) {
522 ALOGE("%s: Device not idle", __FUNCTION__);
523 return INVALID_OPERATION;
524 }
525
526 sp<Camera3Stream> deletedStream;
527 if (mInputStream != NULL && id == mInputStream->getId()) {
528 deletedStream = mInputStream;
529 mInputStream.clear();
530 } else {
531 ssize_t idx = mOutputStreams.indexOfKey(id);
532 if (idx == NAME_NOT_FOUND) {
533 ALOGE("%s: Stream %d does not exist",
534 __FUNCTION__, id);
535 return BAD_VALUE;
536 }
537 deletedStream = mOutputStreams.editValueAt(idx);
538 mOutputStreams.removeItem(id);
539 }
540
541 // Free up the stream endpoint so that it can be used by some other stream
542 res = deletedStream->disconnect();
543 if (res != OK) {
544 ALOGE("%s: Can't disconnect deleted stream", __FUNCTION__);
545 // fall through since we want to still list the stream as deleted.
546 }
547 mDeletedStreams.add(deletedStream);
548
549 return res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800550}
551
552status_t Camera3Device::deleteReprocessStream(int id) {
553 ATRACE_CALL();
554 (void)id;
555
556 ALOGE("%s: Unimplemented", __FUNCTION__);
557 return INVALID_OPERATION;
558}
559
560
561status_t Camera3Device::createDefaultRequest(int templateId,
562 CameraMetadata *request) {
563 ATRACE_CALL();
564 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800565 Mutex::Autolock l(mLock);
566
567 switch (mStatus) {
568 case STATUS_ERROR:
569 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
570 return INVALID_OPERATION;
571 case STATUS_UNINITIALIZED:
572 ALOGE("%s: Device is not initialized!", __FUNCTION__);
573 return INVALID_OPERATION;
574 case STATUS_IDLE:
575 case STATUS_ACTIVE:
576 // OK
577 break;
578 default:
579 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
580 return INVALID_OPERATION;
581 }
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800582
583 const camera_metadata_t *rawRequest;
584 rawRequest = mHal3Device->ops->construct_default_request_settings(
585 mHal3Device, templateId);
586 if (rawRequest == NULL) return DEAD_OBJECT;
587 *request = rawRequest;
588
589 return OK;
590}
591
592status_t Camera3Device::waitUntilDrained() {
593 ATRACE_CALL();
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800594 Mutex::Autolock l(mLock);
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800595
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800596 return waitUntilDrainedLocked();
597}
598
599status_t Camera3Device::waitUntilDrainedLocked() {
600 ATRACE_CALL();
601 status_t res;
602
603 switch (mStatus) {
604 case STATUS_UNINITIALIZED:
605 case STATUS_IDLE:
606 ALOGV("%s: Already idle", __FUNCTION__);
607 return OK;
608 case STATUS_ERROR:
609 case STATUS_ACTIVE:
610 // Need to shut down
611 break;
612 default:
613 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
614 return INVALID_OPERATION;
615 }
616
617 if (mRequestThread != NULL) {
618 res = mRequestThread->waitUntilPaused(kShutdownTimeout);
619 if (res != OK) {
620 ALOGE("%s: Can't stop request thread in %f seconds!",
621 __FUNCTION__, kShutdownTimeout/1e9);
622 mStatus = STATUS_ERROR;
623 return res;
624 }
625 }
626 if (mInputStream != NULL) {
627 res = mInputStream->waitUntilIdle(kShutdownTimeout);
628 if (res != OK) {
629 ALOGE("%s: Can't idle input stream %d in %f seconds!",
630 __FUNCTION__, mInputStream->getId(), kShutdownTimeout/1e9);
631 mStatus = STATUS_ERROR;
632 return res;
633 }
634 }
635 for (size_t i = 0; i < mOutputStreams.size(); i++) {
636 res = mOutputStreams.editValueAt(i)->waitUntilIdle(kShutdownTimeout);
637 if (res != OK) {
638 ALOGE("%s: Can't idle output stream %d in %f seconds!",
639 __FUNCTION__, mOutputStreams.keyAt(i),
640 kShutdownTimeout/1e9);
641 mStatus = STATUS_ERROR;
642 return res;
643 }
644 }
645
646 if (mStatus != STATUS_ERROR) {
647 mStatus = STATUS_IDLE;
648 }
649
650 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800651}
652
653status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
654 ATRACE_CALL();
655 (void)listener;
656
657 ALOGE("%s: Unimplemented", __FUNCTION__);
658 return INVALID_OPERATION;
659}
660
661status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
662 (void)timeout;
663
664 ALOGE("%s: Unimplemented", __FUNCTION__);
665 return INVALID_OPERATION;
666}
667
668status_t Camera3Device::getNextFrame(CameraMetadata *frame) {
669 ATRACE_CALL();
670 (void)frame;
671
672 ALOGE("%s: Unimplemented", __FUNCTION__);
673 return INVALID_OPERATION;
674}
675
676status_t Camera3Device::triggerAutofocus(uint32_t id) {
677 ATRACE_CALL();
678 (void)id;
679
680
681 ALOGE("%s: Unimplemented", __FUNCTION__);
682 return INVALID_OPERATION;
683}
684
685status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
686 ATRACE_CALL();
687 (void)id;
688
689 ALOGE("%s: Unimplemented", __FUNCTION__);
690 return INVALID_OPERATION;
691
692}
693
694status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
695 ATRACE_CALL();
696 (void)id;
697
698 ALOGE("%s: Unimplemented", __FUNCTION__);
699 return INVALID_OPERATION;
700
701}
702
703status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
704 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
705 ATRACE_CALL();
706 (void)reprocessStreamId; (void)buffer; (void)listener;
707
708 ALOGE("%s: Unimplemented", __FUNCTION__);
709 return INVALID_OPERATION;
710}
711
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800712/**
713 * Camera3Device private methods
714 */
715
716sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
717 const CameraMetadata &request) {
718 ATRACE_CALL();
719 status_t res;
720
721 sp<CaptureRequest> newRequest = new CaptureRequest;
722 newRequest->mSettings = request;
723
724 camera_metadata_entry_t inputStreams =
725 newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
726 if (inputStreams.count > 0) {
727 if (mInputStream == NULL ||
728 mInputStream->getId() != inputStreams.data.u8[0]) {
729 ALOGE("%s: Request references unknown input stream %d",
730 __FUNCTION__, inputStreams.data.u8[0]);
731 return NULL;
732 }
733 // Lazy completion of stream configuration (allocation/registration)
734 // on first use
735 if (mInputStream->isConfiguring()) {
736 res = mInputStream->finishConfiguration(mHal3Device);
737 if (res != OK) {
738 ALOGE("%s: Unable to finish configuring input stream %d:"
739 " %s (%d)",
740 __FUNCTION__, mInputStream->getId(),
741 strerror(-res), res);
742 return NULL;
743 }
744 }
745
746 newRequest->mInputStream = mInputStream;
747 newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
748 }
749
750 camera_metadata_entry_t streams =
751 newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
752 if (streams.count == 0) {
753 ALOGE("%s: Zero output streams specified!", __FUNCTION__);
754 return NULL;
755 }
756
757 for (size_t i = 0; i < streams.count; i++) {
758 int idx = mOutputStreams.indexOfKey(streams.data.u8[i]);
759 if (idx == NAME_NOT_FOUND) {
760 ALOGE("%s: Request references unknown stream %d",
761 __FUNCTION__, streams.data.u8[i]);
762 return NULL;
763 }
764 sp<Camera3OutputStream> stream = mOutputStreams.editValueAt(idx);
765
766 // Lazy completion of stream configuration (allocation/registration)
767 // on first use
768 if (stream->isConfiguring()) {
769 res = stream->finishConfiguration(mHal3Device);
770 if (res != OK) {
771 ALOGE("%s: Unable to finish configuring stream %d: %s (%d)",
772 __FUNCTION__, stream->getId(), strerror(-res), res);
773 return NULL;
774 }
775 }
776
777 newRequest->mOutputStreams.push(stream);
778 }
779 newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
780
781 return newRequest;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800782}
783
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800784status_t Camera3Device::configureStreamsLocked() {
785 ATRACE_CALL();
786 status_t res;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800787
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800788 if (mStatus != STATUS_IDLE) {
789 ALOGE("%s: Not idle", __FUNCTION__);
790 return INVALID_OPERATION;
791 }
792
793 // Start configuring the streams
794
795 camera3_stream_configuration config;
796
797 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
798
799 Vector<camera3_stream_t*> streams;
800 streams.setCapacity(config.num_streams);
801
802 if (mInputStream != NULL) {
803 camera3_stream_t *inputStream;
804 inputStream = mInputStream->startConfiguration();
805 if (inputStream == NULL) {
806 ALOGE("%s: Can't start input stream configuration",
807 __FUNCTION__);
808 // TODO: Make sure the error flow here is correct
809 return INVALID_OPERATION;
810 }
811 streams.add(inputStream);
812 }
813
814 for (size_t i = 0; i < mOutputStreams.size(); i++) {
815 camera3_stream_t *outputStream;
816 outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
817 if (outputStream == NULL) {
818 ALOGE("%s: Can't start output stream configuration",
819 __FUNCTION__);
820 // TODO: Make sure the error flow here is correct
821 return INVALID_OPERATION;
822 }
823 streams.add(outputStream);
824 }
825
826 config.streams = streams.editArray();
827
828 // Do the HAL configuration; will potentially touch stream
829 // max_buffers, usage, priv fields.
830
831 res = mHal3Device->ops->configure_streams(mHal3Device, &config);
832
833 if (res != OK) {
834 ALOGE("%s: Unable to configure streams with HAL: %s (%d)",
835 __FUNCTION__, strerror(-res), res);
836 return res;
837 }
838
839 // Request thread needs to know to avoid using repeat-last-settings protocol
840 // across configure_streams() calls
841 mRequestThread->configurationComplete();
842
843 // Finish configuring the streams lazily on first reference
844
845 mStatus = STATUS_ACTIVE;
846
847 return OK;
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800848}
849
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800850
851/**
852 * Camera HAL device callback methods
853 */
854
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -0800855void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
856 (void)result;
857
858 ALOGE("%s: Unimplemented", __FUNCTION__);
859}
860
861void Camera3Device::notify(const camera3_notify_msg *msg) {
862 (void)msg;
863
864 ALOGE("%s: Unimplemented", __FUNCTION__);
865}
866
867/**
Eino-Ville Talvala3b53bc92013-02-27 18:02:26 -0800868 * RequestThread inner class methods
869 */
870
871Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
872 camera3_device_t *hal3Device) :
873 Thread(false),
874 mParent(parent),
875 mHal3Device(hal3Device),
876 mReconfigured(false),
877 mDoPause(false),
878 mPaused(true),
879 mFrameNumber(0) {
880}
881
882void Camera3Device::RequestThread::configurationComplete() {
883 Mutex::Autolock l(mRequestLock);
884 mReconfigured = true;
885}
886
887status_t Camera3Device::RequestThread::queueRequest(
888 sp<CaptureRequest> request) {
889 Mutex::Autolock l(mRequestLock);
890 mRequestQueue.push_back(request);
891
892 return OK;
893}
894
895status_t Camera3Device::RequestThread::setRepeatingRequests(
896 const RequestList &requests) {
897 Mutex::Autolock l(mRequestLock);
898 mRepeatingRequests.clear();
899 mRepeatingRequests.insert(mRepeatingRequests.begin(),
900 requests.begin(), requests.end());
901 return OK;
902}
903
904status_t Camera3Device::RequestThread::clearRepeatingRequests() {
905 Mutex::Autolock l(mRequestLock);
906 mRepeatingRequests.clear();
907 return OK;
908}
909
910void Camera3Device::RequestThread::setPaused(bool paused) {
911 Mutex::Autolock l(mPauseLock);
912 mDoPause = paused;
913 mDoPauseSignal.signal();
914}
915
916status_t Camera3Device::RequestThread::waitUntilPaused(nsecs_t timeout) {
917 status_t res;
918 Mutex::Autolock l(mPauseLock);
919 while (!mPaused) {
920 res = mPausedSignal.waitRelative(mPauseLock, timeout);
921 if (res == TIMED_OUT) {
922 return res;
923 }
924 }
925 return OK;
926}
927
928bool Camera3Device::RequestThread::threadLoop() {
929
930 status_t res;
931
932 // Handle paused state.
933 if (waitIfPaused()) {
934 return true;
935 }
936
937 // Get work to do
938
939 sp<CaptureRequest> nextRequest = waitForNextRequest();
940 if (nextRequest == NULL) {
941 return true;
942 }
943
944 // Create request to HAL
945
946 camera3_capture_request_t request = camera3_capture_request_t();
947
948 if (mPrevRequest != nextRequest) {
949 request.settings = nextRequest->mSettings.getAndLock();
950 mPrevRequest = nextRequest;
951 } // else leave request.settings NULL to indicate 'reuse latest given'
952
953 camera3_stream_buffer_t inputBuffer;
954 Vector<camera3_stream_buffer_t> outputBuffers;
955
956 // Fill in buffers
957
958 if (nextRequest->mInputStream != NULL) {
959 request.input_buffer = &inputBuffer;
960 res = nextRequest->mInputStream->getBuffer(&inputBuffer);
961 if (res != OK) {
962 ALOGE("RequestThread: Can't get input buffer, skipping request:"
963 " %s (%d)", strerror(-res), res);
964 cleanUpFailedRequest(request, nextRequest, outputBuffers);
965 return true;
966 }
967 } else {
968 request.input_buffer = NULL;
969 }
970
971 outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
972 nextRequest->mOutputStreams.size());
973 request.output_buffers = outputBuffers.array();
974 for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
975 res = nextRequest->mOutputStreams.editItemAt(i)->
976 getBuffer(&outputBuffers.editItemAt(i));
977 if (res != OK) {
978 ALOGE("RequestThread: Can't get output buffer, skipping request:"
979 "%s (%d)", strerror(-res), res);
980 cleanUpFailedRequest(request, nextRequest, outputBuffers);
981 return true;
982 }
983 request.num_output_buffers++;
984 }
985
986 request.frame_number = mFrameNumber++;
987
988 // Submit request and block until ready for next one
989
990 res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
991 if (res != OK) {
992 ALOGE("RequestThread: Unable to submit capture request %d to HAL"
993 " device: %s (%d)", request.frame_number, strerror(-res), res);
994 cleanUpFailedRequest(request, nextRequest, outputBuffers);
995 return false;
996 }
997
998 if (request.settings != NULL) {
999 nextRequest->mSettings.unlock(request.settings);
1000 }
1001 return true;
1002}
1003
1004void Camera3Device::RequestThread::cleanUpFailedRequest(
1005 camera3_capture_request_t &request,
1006 sp<CaptureRequest> &nextRequest,
1007 Vector<camera3_stream_buffer_t> &outputBuffers) {
1008
1009 if (request.settings != NULL) {
1010 nextRequest->mSettings.unlock(request.settings);
1011 }
1012 if (request.input_buffer != NULL) {
1013 request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
1014 nextRequest->mInputStream->returnBuffer(*(request.input_buffer), 0);
1015 }
1016 for (size_t i = 0; i < request.num_output_buffers; i++) {
1017 outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
1018 nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
1019 outputBuffers[i], 0);
1020 }
1021 // TODO: Report error upstream
1022}
1023
1024sp<Camera3Device::CaptureRequest>
1025 Camera3Device::RequestThread::waitForNextRequest() {
1026 status_t res;
1027 sp<CaptureRequest> nextRequest;
1028
1029 // Optimized a bit for the simple steady-state case (single repeating
1030 // request), to avoid putting that request in the queue temporarily.
1031 Mutex::Autolock l(mRequestLock);
1032
1033 while (mRequestQueue.empty()) {
1034 if (!mRepeatingRequests.empty()) {
1035 // Always atomically enqueue all requests in a repeating request
1036 // list. Guarantees a complete in-sequence set of captures to
1037 // application.
1038 const RequestList &requests = mRepeatingRequests;
1039 RequestList::const_iterator firstRequest =
1040 requests.begin();
1041 nextRequest = *firstRequest;
1042 mRequestQueue.insert(mRequestQueue.end(),
1043 ++firstRequest,
1044 requests.end());
1045 // No need to wait any longer
1046 break;
1047 }
1048
1049 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
1050
1051 if (res == TIMED_OUT) {
1052 // Signal that we're paused by starvation
1053 Mutex::Autolock pl(mPauseLock);
1054 if (mPaused == false) {
1055 mPaused = true;
1056 mPausedSignal.signal();
1057 }
1058 // Stop waiting for now and let thread management happen
1059 return NULL;
1060 }
1061 }
1062
1063 if (nextRequest == NULL) {
1064 // Don't have a repeating request already in hand, so queue
1065 // must have an entry now.
1066 RequestList::iterator firstRequest =
1067 mRequestQueue.begin();
1068 nextRequest = *firstRequest;
1069 mRequestQueue.erase(firstRequest);
1070 }
1071
1072 // Not paused
1073 Mutex::Autolock pl(mPauseLock);
1074 mPaused = false;
1075
1076 // Check if we've reconfigured since last time, and reset the preview
1077 // request if so. Can't use 'NULL request == repeat' across configure calls.
1078 if (mReconfigured) {
1079 mPrevRequest.clear();
1080 mReconfigured = false;
1081 }
1082
1083 return nextRequest;
1084}
1085
1086bool Camera3Device::RequestThread::waitIfPaused() {
1087 status_t res;
1088 Mutex::Autolock l(mPauseLock);
1089 while (mDoPause) {
1090 // Signal that we're paused by request
1091 if (mPaused == false) {
1092 mPaused = true;
1093 mPausedSignal.signal();
1094 }
1095 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
1096 if (res == TIMED_OUT) {
1097 return true;
1098 }
1099 }
1100 // We don't set mPaused to false here, because waitForNextRequest needs
1101 // to further manage the paused state in case of starvation.
1102 return false;
1103}
1104
1105/**
Eino-Ville Talvalab99c5b82013-02-06 17:20:07 -08001106 * Static callback forwarding methods from HAL to instance
1107 */
1108
1109void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
1110 const camera3_capture_result *result) {
1111 Camera3Device *d =
1112 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1113 d->processCaptureResult(result);
1114}
1115
1116void Camera3Device::sNotify(const camera3_callback_ops *cb,
1117 const camera3_notify_msg *msg) {
1118 Camera3Device *d =
1119 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1120 d->notify(msg);
1121}
1122
1123}; // namespace android