blob: f2c8c04ad8ea7e558f2260326355de2324add402 [file] [log] [blame]
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Camera3-Device"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20//#define LOG_NNDEBUG 0 // Per-frame verbose logging
21
22#ifdef LOG_NNDEBUG
23#define ALOGVV(...) ALOGV(__VA_ARGS__)
24#else
25#define ALOGVV(...) ((void)0)
26#endif
27
28#include <utils/Log.h>
29#include <utils/Trace.h>
30#include <utils/Timers.h>
31#include "Camera3Device.h"
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080032#include "camera3/Camera3OutputStream.h"
33
34using namespace android::camera3;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080035
36namespace android {
37
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080038Camera3Device::Camera3Device(int id):
39 mId(id),
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080040 mHal3Device(NULL),
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -070041 mStatus(STATUS_UNINITIALIZED),
42 mListener(NULL)
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080043{
44 ATRACE_CALL();
45 camera3_callback_ops::notify = &sNotify;
46 camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
47 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
48}
49
50Camera3Device::~Camera3Device()
51{
52 ATRACE_CALL();
53 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
54 disconnect();
55}
56
Igor Murashkin71381052013-03-04 14:53:08 -080057int Camera3Device::getId() const {
58 return mId;
59}
60
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080061/**
62 * CameraDeviceBase interface
63 */
64
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080065status_t Camera3Device::initialize(camera_module_t *module)
66{
67 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080068 Mutex::Autolock l(mLock);
69
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080070 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080071 if (mStatus != STATUS_UNINITIALIZED) {
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080072 ALOGE("%s: Already initialized!", __FUNCTION__);
73 return INVALID_OPERATION;
74 }
75
76 /** Open HAL device */
77
78 status_t res;
79 String8 deviceName = String8::format("%d", mId);
80
81 camera3_device_t *device;
82
83 res = module->common.methods->open(&module->common, deviceName.string(),
84 reinterpret_cast<hw_device_t**>(&device));
85
86 if (res != OK) {
87 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
88 mId, strerror(-res), res);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -080089 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -080090 return res;
91 }
92
93 /** Cross-check device version */
94
95 if (device->common.version != CAMERA_DEVICE_API_VERSION_3_0) {
96 ALOGE("%s: Could not open camera %d: "
97 "Camera device is not version %x, reports %x instead",
98 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_3_0,
99 device->common.version);
100 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800101 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800102 return BAD_VALUE;
103 }
104
105 camera_info info;
106 res = module->get_camera_info(mId, &info);
107 if (res != OK) return res;
108
109 if (info.device_version != device->common.version) {
110 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
111 " and device version (%x).", __FUNCTION__,
112 device->common.version, info.device_version);
113 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800114 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800115 return BAD_VALUE;
116 }
117
118 /** Initialize device with callback functions */
119
120 res = device->ops->initialize(device, this);
121 if (res != OK) {
122 ALOGE("%s: Camera %d: Unable to initialize HAL device: %s (%d)",
123 __FUNCTION__, mId, strerror(-res), res);
124 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800125 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800126 return BAD_VALUE;
127 }
128
129 /** Get vendor metadata tags */
130
131 mVendorTagOps.get_camera_vendor_section_name = NULL;
132
133 device->ops->get_metadata_vendor_tag_ops(device, &mVendorTagOps);
134
135 if (mVendorTagOps.get_camera_vendor_section_name != NULL) {
136 res = set_camera_metadata_vendor_tag_ops(&mVendorTagOps);
137 if (res != OK) {
138 ALOGE("%s: Camera %d: Unable to set tag ops: %s (%d)",
139 __FUNCTION__, mId, strerror(-res), res);
140 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800141 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800142 return res;
143 }
144 }
145
146 /** Start up request queue thread */
147
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800148 mRequestThread = new RequestThread(this, device);
149 res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800150 if (res != OK) {
151 ALOGE("%s: Camera %d: Unable to start request queue thread: %s (%d)",
152 __FUNCTION__, mId, strerror(-res), res);
153 device->common.close(&device->common);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800154 mRequestThread.clear();
155 mStatus = STATUS_ERROR;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800156 return res;
157 }
158
159 /** Everything is good to go */
160
161 mDeviceInfo = info.static_camera_characteristics;
162 mHal3Device = device;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800163 mStatus = STATUS_IDLE;
164 mNextStreamId = 0;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800165
166 return OK;
167}
168
169status_t Camera3Device::disconnect() {
170 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800171 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800172
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800173 ALOGV("%s: E", __FUNCTION__);
174
175 status_t res;
176 if (mStatus == STATUS_UNINITIALIZED) return OK;
177
178 if (mStatus == STATUS_ACTIVE ||
179 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
180 res = mRequestThread->clearRepeatingRequests();
181 if (res != OK) {
182 ALOGE("%s: Can't stop streaming", __FUNCTION__);
183 return res;
184 }
185 res = waitUntilDrainedLocked();
186 if (res != OK) {
187 ALOGE("%s: Timeout waiting for HAL to drain", __FUNCTION__);
188 return res;
189 }
190 }
191 assert(mStatus == STATUS_IDLE || mStatus == STATUS_ERROR);
192
193 if (mRequestThread != NULL) {
194 mRequestThread->requestExit();
195 }
196
197 mOutputStreams.clear();
198 mInputStream.clear();
199
200 if (mRequestThread != NULL) {
201 mRequestThread->join();
202 mRequestThread.clear();
203 }
204
205 if (mHal3Device != NULL) {
206 mHal3Device->common.close(&mHal3Device->common);
207 mHal3Device = NULL;
208 }
209
210 mStatus = STATUS_UNINITIALIZED;
211
212 ALOGV("%s: X", __FUNCTION__);
213 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800214}
215
216status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
217 ATRACE_CALL();
218 (void)args;
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800219 String8 lines;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800220
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800221 const char *status =
222 mStatus == STATUS_ERROR ? "ERROR" :
223 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
224 mStatus == STATUS_IDLE ? "IDLE" :
225 mStatus == STATUS_ACTIVE ? "ACTIVE" :
226 "Unknown";
227 lines.appendFormat(" Device status: %s\n", status);
228 lines.appendFormat(" Stream configuration:\n");
229
230 if (mInputStream != NULL) {
231 write(fd, lines.string(), lines.size());
232 mInputStream->dump(fd, args);
233 } else {
234 lines.appendFormat(" No input stream.\n");
235 write(fd, lines.string(), lines.size());
236 }
237 for (size_t i = 0; i < mOutputStreams.size(); i++) {
238 mOutputStreams[i]->dump(fd,args);
239 }
240
241 if (mHal3Device != NULL) {
242 lines = String8(" HAL device dump:\n");
243 write(fd, lines.string(), lines.size());
244 mHal3Device->ops->dump(mHal3Device, fd);
245 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800246
247 return OK;
248}
249
250const CameraMetadata& Camera3Device::info() const {
251 ALOGVV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800252 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
253 mStatus == STATUS_ERROR)) {
254 ALOGE("%s: Access to static info %s!", __FUNCTION__,
255 mStatus == STATUS_ERROR ?
256 "when in error state" : "before init");
257 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800258 return mDeviceInfo;
259}
260
261status_t Camera3Device::capture(CameraMetadata &request) {
262 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800263 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800264
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800265 switch (mStatus) {
266 case STATUS_ERROR:
267 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
268 return INVALID_OPERATION;
269 case STATUS_UNINITIALIZED:
270 ALOGE("%s: Device not initialized", __FUNCTION__);
271 return INVALID_OPERATION;
272 case STATUS_IDLE:
273 case STATUS_ACTIVE:
274 // OK
275 break;
276 default:
277 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
278 return INVALID_OPERATION;
279 }
280
281 sp<CaptureRequest> newRequest = setUpRequestLocked(request);
282 if (newRequest == NULL) {
283 ALOGE("%s: Can't create capture request", __FUNCTION__);
284 return BAD_VALUE;
285 }
286
287 return mRequestThread->queueRequest(newRequest);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800288}
289
290
291status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) {
292 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800293 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800294
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800295 switch (mStatus) {
296 case STATUS_ERROR:
297 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
298 return INVALID_OPERATION;
299 case STATUS_UNINITIALIZED:
300 ALOGE("%s: Device not initialized", __FUNCTION__);
301 return INVALID_OPERATION;
302 case STATUS_IDLE:
303 case STATUS_ACTIVE:
304 // OK
305 break;
306 default:
307 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
308 return INVALID_OPERATION;
309 }
310
311 sp<CaptureRequest> newRepeatingRequest = setUpRequestLocked(request);
312 if (newRepeatingRequest == NULL) {
313 ALOGE("%s: Can't create repeating request", __FUNCTION__);
314 return BAD_VALUE;
315 }
316
317 RequestList newRepeatingRequests;
318 newRepeatingRequests.push_back(newRepeatingRequest);
319
320 return mRequestThread->setRepeatingRequests(newRepeatingRequests);
321}
322
323
324sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
325 const CameraMetadata &request) {
326 status_t res;
327
328 if (mStatus == STATUS_IDLE) {
329 res = configureStreamsLocked();
330 if (res != OK) {
331 ALOGE("%s: Can't set up streams: %s (%d)",
332 __FUNCTION__, strerror(-res), res);
333 return NULL;
334 }
335 }
336
337 sp<CaptureRequest> newRequest = createCaptureRequest(request);
338 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800339}
340
341status_t Camera3Device::clearStreamingRequest() {
342 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800343 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800344
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800345 switch (mStatus) {
346 case STATUS_ERROR:
347 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
348 return INVALID_OPERATION;
349 case STATUS_UNINITIALIZED:
350 ALOGE("%s: Device not initialized", __FUNCTION__);
351 return INVALID_OPERATION;
352 case STATUS_IDLE:
353 case STATUS_ACTIVE:
354 // OK
355 break;
356 default:
357 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
358 return INVALID_OPERATION;
359 }
360
361 return mRequestThread->clearRepeatingRequests();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800362}
363
364status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
365 ATRACE_CALL();
366 (void)requestId; (void)timeout;
367
368 ALOGE("%s: Unimplemented", __FUNCTION__);
369 return INVALID_OPERATION;
370}
371
372status_t Camera3Device::createStream(sp<ANativeWindow> consumer,
373 uint32_t width, uint32_t height, int format, size_t size, int *id) {
374 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800375 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800376
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800377 status_t res;
378 bool wasActive = false;
379
380 switch (mStatus) {
381 case STATUS_ERROR:
382 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
383 return INVALID_OPERATION;
384 case STATUS_UNINITIALIZED:
385 ALOGE("%s: Device not initialized", __FUNCTION__);
386 return INVALID_OPERATION;
387 case STATUS_IDLE:
388 // OK
389 break;
390 case STATUS_ACTIVE:
391 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
392 mRequestThread->setPaused(true);
393 res = waitUntilDrainedLocked();
394 if (res != OK) {
395 ALOGE("%s: Can't pause captures to reconfigure streams!",
396 __FUNCTION__);
397 mStatus = STATUS_ERROR;
398 return res;
399 }
400 wasActive = true;
401 break;
402 default:
403 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
404 return INVALID_OPERATION;
405 }
406 assert(mStatus == STATUS_IDLE);
407
408 sp<Camera3OutputStream> newStream;
409 if (format == HAL_PIXEL_FORMAT_BLOB) {
410 newStream = new Camera3OutputStream(mNextStreamId, consumer,
411 width, height, size, format);
412 } else {
413 newStream = new Camera3OutputStream(mNextStreamId, consumer,
414 width, height, format);
415 }
416
417 res = mOutputStreams.add(mNextStreamId, newStream);
418 if (res < 0) {
419 ALOGE("%s: Can't add new stream to set: %s (%d)",
420 __FUNCTION__, strerror(-res), res);
421 return res;
422 }
423
424 *id = mNextStreamId++;
425
426 // Continue captures if active at start
427 if (wasActive) {
428 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
429 res = configureStreamsLocked();
430 if (res != OK) {
431 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
432 __FUNCTION__, mNextStreamId, strerror(-res), res);
433 return res;
434 }
435 mRequestThread->setPaused(false);
436 }
437
438 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800439}
440
441status_t Camera3Device::createReprocessStreamFromStream(int outputId, int *id) {
442 ATRACE_CALL();
443 (void)outputId; (void)id;
444
445 ALOGE("%s: Unimplemented", __FUNCTION__);
446 return INVALID_OPERATION;
447}
448
449
450status_t Camera3Device::getStreamInfo(int id,
451 uint32_t *width, uint32_t *height, uint32_t *format) {
452 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800453 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800454
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800455 switch (mStatus) {
456 case STATUS_ERROR:
457 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
458 return INVALID_OPERATION;
459 case STATUS_UNINITIALIZED:
460 ALOGE("%s: Device not initialized!", __FUNCTION__);
461 return INVALID_OPERATION;
462 case STATUS_IDLE:
463 case STATUS_ACTIVE:
464 // OK
465 break;
466 default:
467 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
468 return INVALID_OPERATION;
469 }
470
471 ssize_t idx = mOutputStreams.indexOfKey(id);
472 if (idx == NAME_NOT_FOUND) {
473 ALOGE("%s: Stream %d is unknown", __FUNCTION__, id);
474 return idx;
475 }
476
477 if (width) *width = mOutputStreams[idx]->getWidth();
478 if (height) *height = mOutputStreams[idx]->getHeight();
479 if (format) *format = mOutputStreams[idx]->getFormat();
480
481 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800482}
483
484status_t Camera3Device::setStreamTransform(int id,
485 int transform) {
486 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800487 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800488
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800489 switch (mStatus) {
490 case STATUS_ERROR:
491 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
492 return INVALID_OPERATION;
493 case STATUS_UNINITIALIZED:
494 ALOGE("%s: Device not initialized", __FUNCTION__);
495 return INVALID_OPERATION;
496 case STATUS_IDLE:
497 case STATUS_ACTIVE:
498 // OK
499 break;
500 default:
501 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
502 return INVALID_OPERATION;
503 }
504
505 ssize_t idx = mOutputStreams.indexOfKey(id);
506 if (idx == NAME_NOT_FOUND) {
507 ALOGE("%s: Stream %d does not exist",
508 __FUNCTION__, id);
509 return BAD_VALUE;
510 }
511
512 return mOutputStreams.editValueAt(idx)->setTransform(transform);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800513}
514
515status_t Camera3Device::deleteStream(int id) {
516 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800517 Mutex::Autolock l(mLock);
518 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800519
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800520 // CameraDevice semantics require device to already be idle before
521 // deleteStream is called, unlike for createStream.
522 if (mStatus != STATUS_IDLE) {
523 ALOGE("%s: Device not idle", __FUNCTION__);
524 return INVALID_OPERATION;
525 }
526
527 sp<Camera3Stream> deletedStream;
528 if (mInputStream != NULL && id == mInputStream->getId()) {
529 deletedStream = mInputStream;
530 mInputStream.clear();
531 } else {
532 ssize_t idx = mOutputStreams.indexOfKey(id);
533 if (idx == NAME_NOT_FOUND) {
534 ALOGE("%s: Stream %d does not exist",
535 __FUNCTION__, id);
536 return BAD_VALUE;
537 }
538 deletedStream = mOutputStreams.editValueAt(idx);
539 mOutputStreams.removeItem(id);
540 }
541
542 // Free up the stream endpoint so that it can be used by some other stream
543 res = deletedStream->disconnect();
544 if (res != OK) {
545 ALOGE("%s: Can't disconnect deleted stream", __FUNCTION__);
546 // fall through since we want to still list the stream as deleted.
547 }
548 mDeletedStreams.add(deletedStream);
549
550 return res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800551}
552
553status_t Camera3Device::deleteReprocessStream(int id) {
554 ATRACE_CALL();
555 (void)id;
556
557 ALOGE("%s: Unimplemented", __FUNCTION__);
558 return INVALID_OPERATION;
559}
560
561
562status_t Camera3Device::createDefaultRequest(int templateId,
563 CameraMetadata *request) {
564 ATRACE_CALL();
565 ALOGV("%s: E", __FUNCTION__);
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800566 Mutex::Autolock l(mLock);
567
568 switch (mStatus) {
569 case STATUS_ERROR:
570 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
571 return INVALID_OPERATION;
572 case STATUS_UNINITIALIZED:
573 ALOGE("%s: Device is not initialized!", __FUNCTION__);
574 return INVALID_OPERATION;
575 case STATUS_IDLE:
576 case STATUS_ACTIVE:
577 // OK
578 break;
579 default:
580 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
581 return INVALID_OPERATION;
582 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800583
584 const camera_metadata_t *rawRequest;
585 rawRequest = mHal3Device->ops->construct_default_request_settings(
586 mHal3Device, templateId);
587 if (rawRequest == NULL) return DEAD_OBJECT;
588 *request = rawRequest;
589
590 return OK;
591}
592
593status_t Camera3Device::waitUntilDrained() {
594 ATRACE_CALL();
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800595 Mutex::Autolock l(mLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800596
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800597 return waitUntilDrainedLocked();
598}
599
600status_t Camera3Device::waitUntilDrainedLocked() {
601 ATRACE_CALL();
602 status_t res;
603
604 switch (mStatus) {
605 case STATUS_UNINITIALIZED:
606 case STATUS_IDLE:
607 ALOGV("%s: Already idle", __FUNCTION__);
608 return OK;
609 case STATUS_ERROR:
610 case STATUS_ACTIVE:
611 // Need to shut down
612 break;
613 default:
614 ALOGE("%s: Unexpected status: %d", __FUNCTION__, mStatus);
615 return INVALID_OPERATION;
616 }
617
618 if (mRequestThread != NULL) {
619 res = mRequestThread->waitUntilPaused(kShutdownTimeout);
620 if (res != OK) {
621 ALOGE("%s: Can't stop request thread in %f seconds!",
622 __FUNCTION__, kShutdownTimeout/1e9);
623 mStatus = STATUS_ERROR;
624 return res;
625 }
626 }
627 if (mInputStream != NULL) {
628 res = mInputStream->waitUntilIdle(kShutdownTimeout);
629 if (res != OK) {
630 ALOGE("%s: Can't idle input stream %d in %f seconds!",
631 __FUNCTION__, mInputStream->getId(), kShutdownTimeout/1e9);
632 mStatus = STATUS_ERROR;
633 return res;
634 }
635 }
636 for (size_t i = 0; i < mOutputStreams.size(); i++) {
637 res = mOutputStreams.editValueAt(i)->waitUntilIdle(kShutdownTimeout);
638 if (res != OK) {
639 ALOGE("%s: Can't idle output stream %d in %f seconds!",
640 __FUNCTION__, mOutputStreams.keyAt(i),
641 kShutdownTimeout/1e9);
642 mStatus = STATUS_ERROR;
643 return res;
644 }
645 }
646
647 if (mStatus != STATUS_ERROR) {
648 mStatus = STATUS_IDLE;
649 }
650
651 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800652}
653
654status_t Camera3Device::setNotifyCallback(NotificationListener *listener) {
655 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700656 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800657
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700658 if (listener != NULL && mListener != NULL) {
659 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
660 }
661 mListener = listener;
662
663 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800664}
665
666status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700667 ATRACE_CALL();
668 status_t res;
669 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800670
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700671 while (mResultQueue.empty()) {
672 res = mResultSignal.waitRelative(mOutputLock, timeout);
673 if (res == TIMED_OUT) {
674 return res;
675 } else if (res != OK) {
676 ALOGE("%s: Camera %d: Error waiting for frame: %s (%d)",
677 __FUNCTION__, mId, strerror(-res), res);
678 return res;
679 }
680 }
681 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800682}
683
684status_t Camera3Device::getNextFrame(CameraMetadata *frame) {
685 ATRACE_CALL();
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700686 Mutex::Autolock l(mOutputLock);
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800687
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700688 if (mResultQueue.empty()) {
689 return NOT_ENOUGH_DATA;
690 }
691
692 CameraMetadata &result = *(mResultQueue.begin());
693 frame->acquire(result);
694 mResultQueue.erase(mResultQueue.begin());
695
696 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800697}
698
699status_t Camera3Device::triggerAutofocus(uint32_t id) {
700 ATRACE_CALL();
701 (void)id;
702
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800703 ALOGE("%s: Unimplemented", __FUNCTION__);
704 return INVALID_OPERATION;
705}
706
707status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
708 ATRACE_CALL();
709 (void)id;
710
711 ALOGE("%s: Unimplemented", __FUNCTION__);
712 return INVALID_OPERATION;
713
714}
715
716status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
717 ATRACE_CALL();
718 (void)id;
719
720 ALOGE("%s: Unimplemented", __FUNCTION__);
721 return INVALID_OPERATION;
722
723}
724
725status_t Camera3Device::pushReprocessBuffer(int reprocessStreamId,
726 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
727 ATRACE_CALL();
728 (void)reprocessStreamId; (void)buffer; (void)listener;
729
730 ALOGE("%s: Unimplemented", __FUNCTION__);
731 return INVALID_OPERATION;
732}
733
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800734/**
735 * Camera3Device private methods
736 */
737
738sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
739 const CameraMetadata &request) {
740 ATRACE_CALL();
741 status_t res;
742
743 sp<CaptureRequest> newRequest = new CaptureRequest;
744 newRequest->mSettings = request;
745
746 camera_metadata_entry_t inputStreams =
747 newRequest->mSettings.find(ANDROID_REQUEST_INPUT_STREAMS);
748 if (inputStreams.count > 0) {
749 if (mInputStream == NULL ||
750 mInputStream->getId() != inputStreams.data.u8[0]) {
751 ALOGE("%s: Request references unknown input stream %d",
752 __FUNCTION__, inputStreams.data.u8[0]);
753 return NULL;
754 }
755 // Lazy completion of stream configuration (allocation/registration)
756 // on first use
757 if (mInputStream->isConfiguring()) {
758 res = mInputStream->finishConfiguration(mHal3Device);
759 if (res != OK) {
760 ALOGE("%s: Unable to finish configuring input stream %d:"
761 " %s (%d)",
762 __FUNCTION__, mInputStream->getId(),
763 strerror(-res), res);
764 return NULL;
765 }
766 }
767
768 newRequest->mInputStream = mInputStream;
769 newRequest->mSettings.erase(ANDROID_REQUEST_INPUT_STREAMS);
770 }
771
772 camera_metadata_entry_t streams =
773 newRequest->mSettings.find(ANDROID_REQUEST_OUTPUT_STREAMS);
774 if (streams.count == 0) {
775 ALOGE("%s: Zero output streams specified!", __FUNCTION__);
776 return NULL;
777 }
778
779 for (size_t i = 0; i < streams.count; i++) {
780 int idx = mOutputStreams.indexOfKey(streams.data.u8[i]);
781 if (idx == NAME_NOT_FOUND) {
782 ALOGE("%s: Request references unknown stream %d",
783 __FUNCTION__, streams.data.u8[i]);
784 return NULL;
785 }
786 sp<Camera3OutputStream> stream = mOutputStreams.editValueAt(idx);
787
788 // Lazy completion of stream configuration (allocation/registration)
789 // on first use
790 if (stream->isConfiguring()) {
791 res = stream->finishConfiguration(mHal3Device);
792 if (res != OK) {
793 ALOGE("%s: Unable to finish configuring stream %d: %s (%d)",
794 __FUNCTION__, stream->getId(), strerror(-res), res);
795 return NULL;
796 }
797 }
798
799 newRequest->mOutputStreams.push(stream);
800 }
801 newRequest->mSettings.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
802
803 return newRequest;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800804}
805
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800806status_t Camera3Device::configureStreamsLocked() {
807 ATRACE_CALL();
808 status_t res;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800809
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800810 if (mStatus != STATUS_IDLE) {
811 ALOGE("%s: Not idle", __FUNCTION__);
812 return INVALID_OPERATION;
813 }
814
815 // Start configuring the streams
816
817 camera3_stream_configuration config;
818
819 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
820
821 Vector<camera3_stream_t*> streams;
822 streams.setCapacity(config.num_streams);
823
824 if (mInputStream != NULL) {
825 camera3_stream_t *inputStream;
826 inputStream = mInputStream->startConfiguration();
827 if (inputStream == NULL) {
828 ALOGE("%s: Can't start input stream configuration",
829 __FUNCTION__);
830 // TODO: Make sure the error flow here is correct
831 return INVALID_OPERATION;
832 }
833 streams.add(inputStream);
834 }
835
836 for (size_t i = 0; i < mOutputStreams.size(); i++) {
837 camera3_stream_t *outputStream;
838 outputStream = mOutputStreams.editValueAt(i)->startConfiguration();
839 if (outputStream == NULL) {
840 ALOGE("%s: Can't start output stream configuration",
841 __FUNCTION__);
842 // TODO: Make sure the error flow here is correct
843 return INVALID_OPERATION;
844 }
845 streams.add(outputStream);
846 }
847
848 config.streams = streams.editArray();
849
850 // Do the HAL configuration; will potentially touch stream
851 // max_buffers, usage, priv fields.
852
853 res = mHal3Device->ops->configure_streams(mHal3Device, &config);
854
855 if (res != OK) {
856 ALOGE("%s: Unable to configure streams with HAL: %s (%d)",
857 __FUNCTION__, strerror(-res), res);
858 return res;
859 }
860
861 // Request thread needs to know to avoid using repeat-last-settings protocol
862 // across configure_streams() calls
863 mRequestThread->configurationComplete();
864
865 // Finish configuring the streams lazily on first reference
866
867 mStatus = STATUS_ACTIVE;
868
869 return OK;
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800870}
871
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -0800872
873/**
874 * Camera HAL device callback methods
875 */
876
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800877void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700878 ATRACE_CALL();
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -0800879
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700880 status_t res;
881
882 if (result->result == NULL) {
883 // TODO: Report error upstream
884 ALOGW("%s: No metadata for frame %d", __FUNCTION__,
885 result->frame_number);
886 return;
887 }
888
889 nsecs_t timestamp = 0;
890 AlgState cur3aState;
891 AlgState new3aState;
892 int32_t aeTriggerId = 0;
893 int32_t afTriggerId = 0;
894
895 NotificationListener *listener;
896
897 {
898 Mutex::Autolock l(mOutputLock);
899
900 // Push result metadata into queue
901 mResultQueue.push_back(CameraMetadata());
Igor Murashkind2c90692013-04-02 12:32:32 -0700902 // Lets avoid copies! Too bad there's not a #back method
903 CameraMetadata &captureResult = *(--mResultQueue.end());
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700904
905 captureResult = result->result;
Igor Murashkind2c90692013-04-02 12:32:32 -0700906 if (captureResult.update(ANDROID_REQUEST_FRAME_COUNT,
907 (int32_t*)&result->frame_number, 1) != OK) {
908 ALOGE("%s: Camera %d: Failed to set frame# in metadata (%d)",
909 __FUNCTION__, mId, result->frame_number);
910 // TODO: Report error upstream
911 } else {
912 ALOGVV("%s: Camera %d: Set frame# in metadata (%d)",
913 __FUNCTION__, mId, result->frame_number);
914 }
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -0700915
916 // Get timestamp from result metadata
917
918 camera_metadata_entry entry =
919 captureResult.find(ANDROID_SENSOR_TIMESTAMP);
920 if (entry.count == 0) {
921 ALOGE("%s: Camera %d: No timestamp provided by HAL for frame %d!",
922 __FUNCTION__, mId, result->frame_number);
923 // TODO: Report error upstream
924 } else {
925 timestamp = entry.data.i64[0];
926 }
927
928 // Get 3A states from result metadata
929
930 entry = captureResult.find(ANDROID_CONTROL_AE_STATE);
931 if (entry.count == 0) {
932 ALOGE("%s: Camera %d: No AE state provided by HAL for frame %d!",
933 __FUNCTION__, mId, result->frame_number);
934 } else {
935 new3aState.aeState =
936 static_cast<camera_metadata_enum_android_control_ae_state>(
937 entry.data.u8[0]);
938 }
939
940 entry = captureResult.find(ANDROID_CONTROL_AF_STATE);
941 if (entry.count == 0) {
942 ALOGE("%s: Camera %d: No AF state provided by HAL for frame %d!",
943 __FUNCTION__, mId, result->frame_number);
944 } else {
945 new3aState.afState =
946 static_cast<camera_metadata_enum_android_control_af_state>(
947 entry.data.u8[0]);
948 }
949
950 entry = captureResult.find(ANDROID_CONTROL_AWB_STATE);
951 if (entry.count == 0) {
952 ALOGE("%s: Camera %d: No AWB state provided by HAL for frame %d!",
953 __FUNCTION__, mId, result->frame_number);
954 } else {
955 new3aState.awbState =
956 static_cast<camera_metadata_enum_android_control_awb_state>(
957 entry.data.u8[0]);
958 }
959
960 entry = captureResult.find(ANDROID_CONTROL_AF_TRIGGER_ID);
961 if (entry.count == 0) {
962 ALOGE("%s: Camera %d: No AF trigger ID provided by HAL for frame %d!",
963 __FUNCTION__, mId, result->frame_number);
964 } else {
965 afTriggerId = entry.data.i32[0];
966 }
967
968 entry = captureResult.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
969 if (entry.count == 0) {
970 ALOGE("%s: Camera %d: No AE precapture trigger ID provided by HAL"
971 " for frame %d!", __FUNCTION__, mId, result->frame_number);
972 } else {
973 aeTriggerId = entry.data.i32[0];
974 }
975
976 listener = mListener;
977 cur3aState = m3AState;
978
979 m3AState = new3aState;
980 } // scope for mOutputLock
981
982 // Return completed buffers to their streams
983 for (size_t i = 0; i < result->num_output_buffers; i++) {
984 Camera3Stream *stream =
985 Camera3Stream::cast(result->output_buffers[i].stream);
986 res = stream->returnBuffer(result->output_buffers[i], timestamp);
987 // Note: stream may be deallocated at this point, if this buffer was the
988 // last reference to it.
989 if (res != OK) {
990 ALOGE("%s: Camera %d: Can't return buffer %d for frame %d to its"
991 " stream:%s (%d)", __FUNCTION__, mId, i,
992 result->frame_number, strerror(-res), res);
993 // TODO: Report error upstream
994 }
995 }
996
997 // Dispatch any 3A change events to listeners
998 if (listener != NULL) {
999 if (new3aState.aeState != cur3aState.aeState) {
1000 listener->notifyAutoExposure(new3aState.aeState, aeTriggerId);
1001 }
1002 if (new3aState.afState != cur3aState.afState) {
1003 listener->notifyAutoFocus(new3aState.afState, afTriggerId);
1004 }
1005 if (new3aState.awbState != cur3aState.awbState) {
1006 listener->notifyAutoWhitebalance(new3aState.awbState, aeTriggerId);
1007 }
1008 }
1009
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001010}
1011
1012void Camera3Device::notify(const camera3_notify_msg *msg) {
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001013 NotificationListener *listener;
1014 {
1015 Mutex::Autolock l(mOutputLock);
1016 if (mListener == NULL) return;
1017 listener = mListener;
1018 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001019
Eino-Ville Talvala7d346fa2013-03-11 14:13:50 -07001020 if (msg == NULL) {
1021 ALOGE("%s: Camera %d: HAL sent NULL notify message!",
1022 __FUNCTION__, mId);
1023 return;
1024 }
1025
1026 switch (msg->type) {
1027 case CAMERA3_MSG_ERROR: {
1028 int streamId = 0;
1029 if (msg->message.error.error_stream != NULL) {
1030 Camera3Stream *stream =
1031 Camera3Stream::cast(
1032 msg->message.error.error_stream);
1033 streamId = stream->getId();
1034 }
1035 listener->notifyError(msg->message.error.error_code,
1036 msg->message.error.frame_number, streamId);
1037 break;
1038 }
1039 case CAMERA3_MSG_SHUTTER: {
1040 listener->notifyShutter(msg->message.shutter.frame_number,
1041 msg->message.shutter.timestamp);
1042 break;
1043 }
1044 default:
1045 ALOGE("%s: Camera %d: Unknown notify message from HAL: %d",
1046 __FUNCTION__, mId, msg->type);
1047 }
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001048}
1049
1050/**
Eino-Ville Talvalaf76e0272013-02-27 18:02:26 -08001051 * RequestThread inner class methods
1052 */
1053
1054Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
1055 camera3_device_t *hal3Device) :
1056 Thread(false),
1057 mParent(parent),
1058 mHal3Device(hal3Device),
1059 mReconfigured(false),
1060 mDoPause(false),
1061 mPaused(true),
1062 mFrameNumber(0) {
1063}
1064
1065void Camera3Device::RequestThread::configurationComplete() {
1066 Mutex::Autolock l(mRequestLock);
1067 mReconfigured = true;
1068}
1069
1070status_t Camera3Device::RequestThread::queueRequest(
1071 sp<CaptureRequest> request) {
1072 Mutex::Autolock l(mRequestLock);
1073 mRequestQueue.push_back(request);
1074
1075 return OK;
1076}
1077
1078status_t Camera3Device::RequestThread::setRepeatingRequests(
1079 const RequestList &requests) {
1080 Mutex::Autolock l(mRequestLock);
1081 mRepeatingRequests.clear();
1082 mRepeatingRequests.insert(mRepeatingRequests.begin(),
1083 requests.begin(), requests.end());
1084 return OK;
1085}
1086
1087status_t Camera3Device::RequestThread::clearRepeatingRequests() {
1088 Mutex::Autolock l(mRequestLock);
1089 mRepeatingRequests.clear();
1090 return OK;
1091}
1092
1093void Camera3Device::RequestThread::setPaused(bool paused) {
1094 Mutex::Autolock l(mPauseLock);
1095 mDoPause = paused;
1096 mDoPauseSignal.signal();
1097}
1098
1099status_t Camera3Device::RequestThread::waitUntilPaused(nsecs_t timeout) {
1100 status_t res;
1101 Mutex::Autolock l(mPauseLock);
1102 while (!mPaused) {
1103 res = mPausedSignal.waitRelative(mPauseLock, timeout);
1104 if (res == TIMED_OUT) {
1105 return res;
1106 }
1107 }
1108 return OK;
1109}
1110
1111bool Camera3Device::RequestThread::threadLoop() {
1112
1113 status_t res;
1114
1115 // Handle paused state.
1116 if (waitIfPaused()) {
1117 return true;
1118 }
1119
1120 // Get work to do
1121
1122 sp<CaptureRequest> nextRequest = waitForNextRequest();
1123 if (nextRequest == NULL) {
1124 return true;
1125 }
1126
1127 // Create request to HAL
1128
1129 camera3_capture_request_t request = camera3_capture_request_t();
1130
1131 if (mPrevRequest != nextRequest) {
1132 request.settings = nextRequest->mSettings.getAndLock();
1133 mPrevRequest = nextRequest;
1134 } // else leave request.settings NULL to indicate 'reuse latest given'
1135
1136 camera3_stream_buffer_t inputBuffer;
1137 Vector<camera3_stream_buffer_t> outputBuffers;
1138
1139 // Fill in buffers
1140
1141 if (nextRequest->mInputStream != NULL) {
1142 request.input_buffer = &inputBuffer;
1143 res = nextRequest->mInputStream->getBuffer(&inputBuffer);
1144 if (res != OK) {
1145 ALOGE("RequestThread: Can't get input buffer, skipping request:"
1146 " %s (%d)", strerror(-res), res);
1147 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1148 return true;
1149 }
1150 } else {
1151 request.input_buffer = NULL;
1152 }
1153
1154 outputBuffers.insertAt(camera3_stream_buffer_t(), 0,
1155 nextRequest->mOutputStreams.size());
1156 request.output_buffers = outputBuffers.array();
1157 for (size_t i = 0; i < nextRequest->mOutputStreams.size(); i++) {
1158 res = nextRequest->mOutputStreams.editItemAt(i)->
1159 getBuffer(&outputBuffers.editItemAt(i));
1160 if (res != OK) {
1161 ALOGE("RequestThread: Can't get output buffer, skipping request:"
1162 "%s (%d)", strerror(-res), res);
1163 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1164 return true;
1165 }
1166 request.num_output_buffers++;
1167 }
1168
1169 request.frame_number = mFrameNumber++;
1170
1171 // Submit request and block until ready for next one
1172
1173 res = mHal3Device->ops->process_capture_request(mHal3Device, &request);
1174 if (res != OK) {
1175 ALOGE("RequestThread: Unable to submit capture request %d to HAL"
1176 " device: %s (%d)", request.frame_number, strerror(-res), res);
1177 cleanUpFailedRequest(request, nextRequest, outputBuffers);
1178 return false;
1179 }
1180
1181 if (request.settings != NULL) {
1182 nextRequest->mSettings.unlock(request.settings);
1183 }
1184 return true;
1185}
1186
1187void Camera3Device::RequestThread::cleanUpFailedRequest(
1188 camera3_capture_request_t &request,
1189 sp<CaptureRequest> &nextRequest,
1190 Vector<camera3_stream_buffer_t> &outputBuffers) {
1191
1192 if (request.settings != NULL) {
1193 nextRequest->mSettings.unlock(request.settings);
1194 }
1195 if (request.input_buffer != NULL) {
1196 request.input_buffer->status = CAMERA3_BUFFER_STATUS_ERROR;
1197 nextRequest->mInputStream->returnBuffer(*(request.input_buffer), 0);
1198 }
1199 for (size_t i = 0; i < request.num_output_buffers; i++) {
1200 outputBuffers.editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
1201 nextRequest->mOutputStreams.editItemAt(i)->returnBuffer(
1202 outputBuffers[i], 0);
1203 }
1204 // TODO: Report error upstream
1205}
1206
1207sp<Camera3Device::CaptureRequest>
1208 Camera3Device::RequestThread::waitForNextRequest() {
1209 status_t res;
1210 sp<CaptureRequest> nextRequest;
1211
1212 // Optimized a bit for the simple steady-state case (single repeating
1213 // request), to avoid putting that request in the queue temporarily.
1214 Mutex::Autolock l(mRequestLock);
1215
1216 while (mRequestQueue.empty()) {
1217 if (!mRepeatingRequests.empty()) {
1218 // Always atomically enqueue all requests in a repeating request
1219 // list. Guarantees a complete in-sequence set of captures to
1220 // application.
1221 const RequestList &requests = mRepeatingRequests;
1222 RequestList::const_iterator firstRequest =
1223 requests.begin();
1224 nextRequest = *firstRequest;
1225 mRequestQueue.insert(mRequestQueue.end(),
1226 ++firstRequest,
1227 requests.end());
1228 // No need to wait any longer
1229 break;
1230 }
1231
1232 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
1233
1234 if (res == TIMED_OUT) {
1235 // Signal that we're paused by starvation
1236 Mutex::Autolock pl(mPauseLock);
1237 if (mPaused == false) {
1238 mPaused = true;
1239 mPausedSignal.signal();
1240 }
1241 // Stop waiting for now and let thread management happen
1242 return NULL;
1243 }
1244 }
1245
1246 if (nextRequest == NULL) {
1247 // Don't have a repeating request already in hand, so queue
1248 // must have an entry now.
1249 RequestList::iterator firstRequest =
1250 mRequestQueue.begin();
1251 nextRequest = *firstRequest;
1252 mRequestQueue.erase(firstRequest);
1253 }
1254
1255 // Not paused
1256 Mutex::Autolock pl(mPauseLock);
1257 mPaused = false;
1258
1259 // Check if we've reconfigured since last time, and reset the preview
1260 // request if so. Can't use 'NULL request == repeat' across configure calls.
1261 if (mReconfigured) {
1262 mPrevRequest.clear();
1263 mReconfigured = false;
1264 }
1265
1266 return nextRequest;
1267}
1268
1269bool Camera3Device::RequestThread::waitIfPaused() {
1270 status_t res;
1271 Mutex::Autolock l(mPauseLock);
1272 while (mDoPause) {
1273 // Signal that we're paused by request
1274 if (mPaused == false) {
1275 mPaused = true;
1276 mPausedSignal.signal();
1277 }
1278 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
1279 if (res == TIMED_OUT) {
1280 return true;
1281 }
1282 }
1283 // We don't set mPaused to false here, because waitForNextRequest needs
1284 // to further manage the paused state in case of starvation.
1285 return false;
1286}
1287
1288/**
Eino-Ville Talvala7fa43f32013-02-06 17:20:07 -08001289 * Static callback forwarding methods from HAL to instance
1290 */
1291
1292void Camera3Device::sProcessCaptureResult(const camera3_callback_ops *cb,
1293 const camera3_capture_result *result) {
1294 Camera3Device *d =
1295 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1296 d->processCaptureResult(result);
1297}
1298
1299void Camera3Device::sNotify(const camera3_callback_ops *cb,
1300 const camera3_notify_msg *msg) {
1301 Camera3Device *d =
1302 const_cast<Camera3Device*>(static_cast<const Camera3Device*>(cb));
1303 d->notify(msg);
1304}
1305
1306}; // namespace android