1 /*
2 * Copyright (C) 2012 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 "Camera2-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 <inttypes.h>
29 #include <utils/Log.h>
30 #include <utils/Trace.h>
31 #include <utils/Timers.h>
32 #include "Camera2Device.h"
33 #include "CameraService.h"
34
35 namespace android {
36
Camera2Device(int id)37 Camera2Device::Camera2Device(int id):
38 mId(id),
39 mHal2Device(NULL)
40 {
41 ATRACE_CALL();
42 ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
43 }
44
~Camera2Device()45 Camera2Device::~Camera2Device()
46 {
47 ATRACE_CALL();
48 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
49 disconnect();
50 }
51
getId() const52 int Camera2Device::getId() const {
53 return mId;
54 }
55
initialize(camera_module_t * module)56 status_t Camera2Device::initialize(camera_module_t *module)
57 {
58 ATRACE_CALL();
59 ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
60 if (mHal2Device != NULL) {
61 ALOGE("%s: Already initialized!", __FUNCTION__);
62 return INVALID_OPERATION;
63 }
64
65 status_t res;
66 char name[10];
67 snprintf(name, sizeof(name), "%d", mId);
68
69 camera2_device_t *device;
70
71 res = CameraService::filterOpenErrorCode(module->common.methods->open(
72 &module->common, name, reinterpret_cast<hw_device_t**>(&device)));
73
74 if (res != OK) {
75 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
76 mId, strerror(-res), res);
77 return res;
78 }
79
80 if (device->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
81 ALOGE("%s: Could not open camera %d: "
82 "Camera device is not version %x, reports %x instead",
83 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
84 device->common.version);
85 device->common.close(&device->common);
86 return BAD_VALUE;
87 }
88
89 camera_info info;
90 res = module->get_camera_info(mId, &info);
91 if (res != OK ) return res;
92
93 if (info.device_version != device->common.version) {
94 ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
95 " and device version (%x).", __FUNCTION__,
96 device->common.version, info.device_version);
97 device->common.close(&device->common);
98 return BAD_VALUE;
99 }
100
101 res = mRequestQueue.setConsumerDevice(device);
102 if (res != OK) {
103 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
104 __FUNCTION__, mId, strerror(-res), res);
105 device->common.close(&device->common);
106 return res;
107 }
108 res = mFrameQueue.setProducerDevice(device);
109 if (res != OK) {
110 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
111 __FUNCTION__, mId, strerror(-res), res);
112 device->common.close(&device->common);
113 return res;
114 }
115
116 res = device->ops->set_notify_callback(device, notificationCallback,
117 NULL);
118 if (res != OK) {
119 ALOGE("%s: Camera %d: Unable to initialize notification callback!",
120 __FUNCTION__, mId);
121 device->common.close(&device->common);
122 return res;
123 }
124
125 mDeviceInfo = info.static_camera_characteristics;
126 mHal2Device = device;
127 mDeviceVersion = device->common.version;
128
129 return OK;
130 }
131
disconnect()132 status_t Camera2Device::disconnect() {
133 ATRACE_CALL();
134 status_t res = OK;
135 if (mHal2Device) {
136 ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId);
137
138 int inProgressCount = mHal2Device->ops->get_in_progress_count(mHal2Device);
139 if (inProgressCount > 0) {
140 ALOGW("%s: Closing camera device %d with %d requests in flight!",
141 __FUNCTION__, mId, inProgressCount);
142 }
143 mReprocessStreams.clear();
144 mStreams.clear();
145 res = mHal2Device->common.close(&mHal2Device->common);
146 if (res != OK) {
147 ALOGE("%s: Could not close camera %d: %s (%d)",
148 __FUNCTION__,
149 mId, strerror(-res), res);
150 }
151 mHal2Device = NULL;
152 ALOGV("%s: Shutdown complete", __FUNCTION__);
153 }
154 return res;
155 }
156
dump(int fd,const Vector<String16> & args)157 status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
158 ATRACE_CALL();
159 String8 result;
160 int detailLevel = 0;
161 int n = args.size();
162 String16 detailOption("-d");
163 for (int i = 0; i + 1 < n; i++) {
164 if (args[i] == detailOption) {
165 String8 levelStr(args[i+1]);
166 detailLevel = atoi(levelStr.string());
167 }
168 }
169
170 result.appendFormat(" Camera2Device[%d] dump (detail level %d):\n",
171 mId, detailLevel);
172
173 if (detailLevel > 0) {
174 result = " Request queue contents:\n";
175 write(fd, result.string(), result.size());
176 mRequestQueue.dump(fd, args);
177
178 result = " Frame queue contents:\n";
179 write(fd, result.string(), result.size());
180 mFrameQueue.dump(fd, args);
181 }
182
183 result = " Active streams:\n";
184 write(fd, result.string(), result.size());
185 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
186 (*s)->dump(fd, args);
187 }
188
189 result = " HAL device dump:\n";
190 write(fd, result.string(), result.size());
191
192 status_t res;
193 res = mHal2Device->ops->dump(mHal2Device, fd);
194
195 return res;
196 }
197
info() const198 const CameraMetadata& Camera2Device::info() const {
199 ALOGVV("%s: E", __FUNCTION__);
200
201 return mDeviceInfo;
202 }
203
capture(CameraMetadata & request,int64_t *)204 status_t Camera2Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
205 ATRACE_CALL();
206 ALOGV("%s: E", __FUNCTION__);
207
208 mRequestQueue.enqueue(request.release());
209 return OK;
210 }
211
captureList(const List<const CameraMetadata> & requests,int64_t *)212 status_t Camera2Device::captureList(const List<const CameraMetadata> &requests,
213 int64_t* /*lastFrameNumber*/) {
214 ATRACE_CALL();
215 ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__);
216 return INVALID_OPERATION;
217 }
218
setStreamingRequest(const CameraMetadata & request,int64_t *)219 status_t Camera2Device::setStreamingRequest(const CameraMetadata &request,
220 int64_t* /*lastFrameNumber*/) {
221 ATRACE_CALL();
222 ALOGV("%s: E", __FUNCTION__);
223 CameraMetadata streamRequest(request);
224 return mRequestQueue.setStreamSlot(streamRequest.release());
225 }
226
setStreamingRequestList(const List<const CameraMetadata> & requests,int64_t *)227 status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests,
228 int64_t* /*lastFrameNumber*/) {
229 ATRACE_CALL();
230 ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__);
231 return INVALID_OPERATION;
232 }
233
clearStreamingRequest(int64_t *)234 status_t Camera2Device::clearStreamingRequest(int64_t* /*lastFrameNumber*/) {
235 ATRACE_CALL();
236 return mRequestQueue.setStreamSlot(NULL);
237 }
238
waitUntilRequestReceived(int32_t requestId,nsecs_t timeout)239 status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
240 ATRACE_CALL();
241 return mRequestQueue.waitForDequeue(requestId, timeout);
242 }
243
createStream(sp<ANativeWindow> consumer,uint32_t width,uint32_t height,int format,int * id)244 status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
245 uint32_t width, uint32_t height, int format, int *id) {
246 ATRACE_CALL();
247 status_t res;
248 ALOGV("%s: E", __FUNCTION__);
249
250 sp<StreamAdapter> stream = new StreamAdapter(mHal2Device);
251 size_t size = 0;
252 if (format == HAL_PIXEL_FORMAT_BLOB) {
253 size = getJpegBufferSize(width, height);
254 }
255 res = stream->connectToDevice(consumer, width, height, format, size);
256 if (res != OK) {
257 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
258 "%s (%d)",
259 __FUNCTION__, mId, width, height, format, strerror(-res), res);
260 return res;
261 }
262
263 *id = stream->getId();
264
265 mStreams.push_back(stream);
266 return OK;
267 }
268
getJpegBufferSize(uint32_t width,uint32_t height) const269 ssize_t Camera2Device::getJpegBufferSize(uint32_t width, uint32_t height) const {
270 // Always give the max jpeg buffer size regardless of the actual jpeg resolution.
271 camera_metadata_ro_entry jpegBufMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE);
272 if (jpegBufMaxSize.count == 0) {
273 ALOGE("%s: Camera %d: Can't find maximum JPEG size in static metadata!", __FUNCTION__, mId);
274 return BAD_VALUE;
275 }
276
277 return jpegBufMaxSize.data.i32[0];
278 }
279
createReprocessStreamFromStream(int outputId,int * id)280 status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
281 ATRACE_CALL();
282 status_t res;
283 ALOGV("%s: E", __FUNCTION__);
284
285 bool found = false;
286 StreamList::iterator streamI;
287 for (streamI = mStreams.begin();
288 streamI != mStreams.end(); streamI++) {
289 if ((*streamI)->getId() == outputId) {
290 found = true;
291 break;
292 }
293 }
294 if (!found) {
295 ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
296 "reprocess stream from it!", __FUNCTION__, mId, outputId);
297 return BAD_VALUE;
298 }
299
300 sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device);
301
302 res = stream->connectToDevice((*streamI));
303 if (res != OK) {
304 ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
305 "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
306 strerror(-res), res);
307 return res;
308 }
309
310 *id = stream->getId();
311
312 mReprocessStreams.push_back(stream);
313 return OK;
314 }
315
316
getStreamInfo(int id,uint32_t * width,uint32_t * height,uint32_t * format)317 status_t Camera2Device::getStreamInfo(int id,
318 uint32_t *width, uint32_t *height, uint32_t *format) {
319 ATRACE_CALL();
320 ALOGV("%s: E", __FUNCTION__);
321 bool found = false;
322 StreamList::iterator streamI;
323 for (streamI = mStreams.begin();
324 streamI != mStreams.end(); streamI++) {
325 if ((*streamI)->getId() == id) {
326 found = true;
327 break;
328 }
329 }
330 if (!found) {
331 ALOGE("%s: Camera %d: Stream %d does not exist",
332 __FUNCTION__, mId, id);
333 return BAD_VALUE;
334 }
335
336 if (width) *width = (*streamI)->getWidth();
337 if (height) *height = (*streamI)->getHeight();
338 if (format) *format = (*streamI)->getFormat();
339
340 return OK;
341 }
342
setStreamTransform(int id,int transform)343 status_t Camera2Device::setStreamTransform(int id,
344 int transform) {
345 ATRACE_CALL();
346 ALOGV("%s: E", __FUNCTION__);
347 bool found = false;
348 StreamList::iterator streamI;
349 for (streamI = mStreams.begin();
350 streamI != mStreams.end(); streamI++) {
351 if ((*streamI)->getId() == id) {
352 found = true;
353 break;
354 }
355 }
356 if (!found) {
357 ALOGE("%s: Camera %d: Stream %d does not exist",
358 __FUNCTION__, mId, id);
359 return BAD_VALUE;
360 }
361
362 return (*streamI)->setTransform(transform);
363 }
364
deleteStream(int id)365 status_t Camera2Device::deleteStream(int id) {
366 ATRACE_CALL();
367 ALOGV("%s: E", __FUNCTION__);
368 bool found = false;
369 for (StreamList::iterator streamI = mStreams.begin();
370 streamI != mStreams.end(); streamI++) {
371 if ((*streamI)->getId() == id) {
372 status_t res = (*streamI)->release();
373 if (res != OK) {
374 ALOGE("%s: Unable to release stream %d from HAL device: "
375 "%s (%d)", __FUNCTION__, id, strerror(-res), res);
376 return res;
377 }
378 mStreams.erase(streamI);
379 found = true;
380 break;
381 }
382 }
383 if (!found) {
384 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
385 __FUNCTION__, mId, id);
386 return BAD_VALUE;
387 }
388 return OK;
389 }
390
deleteReprocessStream(int id)391 status_t Camera2Device::deleteReprocessStream(int id) {
392 ATRACE_CALL();
393 ALOGV("%s: E", __FUNCTION__);
394 bool found = false;
395 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
396 streamI != mReprocessStreams.end(); streamI++) {
397 if ((*streamI)->getId() == id) {
398 status_t res = (*streamI)->release();
399 if (res != OK) {
400 ALOGE("%s: Unable to release reprocess stream %d from "
401 "HAL device: %s (%d)", __FUNCTION__, id,
402 strerror(-res), res);
403 return res;
404 }
405 mReprocessStreams.erase(streamI);
406 found = true;
407 break;
408 }
409 }
410 if (!found) {
411 ALOGE("%s: Camera %d: Unable to find stream %d to delete",
412 __FUNCTION__, mId, id);
413 return BAD_VALUE;
414 }
415 return OK;
416 }
417
configureStreams()418 status_t Camera2Device::configureStreams() {
419 ATRACE_CALL();
420 ALOGV("%s: E", __FUNCTION__);
421
422 /**
423 * HAL2 devices do not need to configure streams;
424 * streams are created on the fly.
425 */
426 ALOGW("%s: No-op for HAL2 devices", __FUNCTION__);
427
428 return OK;
429 }
430
431
createDefaultRequest(int templateId,CameraMetadata * request)432 status_t Camera2Device::createDefaultRequest(int templateId,
433 CameraMetadata *request) {
434 ATRACE_CALL();
435 status_t err;
436 ALOGV("%s: E", __FUNCTION__);
437 camera_metadata_t *rawRequest;
438 err = mHal2Device->ops->construct_default_request(
439 mHal2Device, templateId, &rawRequest);
440 request->acquire(rawRequest);
441 return err;
442 }
443
waitUntilDrained()444 status_t Camera2Device::waitUntilDrained() {
445 ATRACE_CALL();
446 static const uint32_t kSleepTime = 50000; // 50 ms
447 static const uint32_t kMaxSleepTime = 10000000; // 10 s
448 ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
449 if (mRequestQueue.getBufferCount() ==
450 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
451
452 // TODO: Set up notifications from HAL, instead of sleeping here
453 uint32_t totalTime = 0;
454 while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
455 usleep(kSleepTime);
456 totalTime += kSleepTime;
457 if (totalTime > kMaxSleepTime) {
458 ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
459 totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device));
460 return TIMED_OUT;
461 }
462 }
463 ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
464 return OK;
465 }
466
setNotifyCallback(NotificationListener * listener)467 status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
468 ATRACE_CALL();
469 status_t res;
470 res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
471 reinterpret_cast<void*>(listener) );
472 if (res != OK) {
473 ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
474 }
475 return res;
476 }
477
willNotify3A()478 bool Camera2Device::willNotify3A() {
479 return true;
480 }
481
notificationCallback(int32_t msg_type,int32_t ext1,int32_t ext2,int32_t ext3,void * user)482 void Camera2Device::notificationCallback(int32_t msg_type,
483 int32_t ext1,
484 int32_t ext2,
485 int32_t ext3,
486 void *user) {
487 ATRACE_CALL();
488 NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
489 ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
490 ext1, ext2, ext3);
491 if (listener != NULL) {
492 switch (msg_type) {
493 case CAMERA2_MSG_ERROR:
494 // TODO: This needs to be fixed. ext2 and ext3 need to be considered.
495 listener->notifyError(
496 ((ext1 == CAMERA2_MSG_ERROR_DEVICE)
497 || (ext1 == CAMERA2_MSG_ERROR_HARDWARE)) ?
498 ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
499 ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
500 CaptureResultExtras());
501 break;
502 case CAMERA2_MSG_SHUTTER: {
503 // TODO: Only needed for camera2 API, which is unsupported
504 // by HAL2 directly.
505 // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
506 // listener->notifyShutter(requestId, timestamp);
507 break;
508 }
509 case CAMERA2_MSG_AUTOFOCUS:
510 listener->notifyAutoFocus(ext1, ext2);
511 break;
512 case CAMERA2_MSG_AUTOEXPOSURE:
513 listener->notifyAutoExposure(ext1, ext2);
514 break;
515 case CAMERA2_MSG_AUTOWB:
516 listener->notifyAutoWhitebalance(ext1, ext2);
517 break;
518 default:
519 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
520 __FUNCTION__, msg_type, ext1, ext2, ext3);
521 }
522 }
523 }
524
waitForNextFrame(nsecs_t timeout)525 status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
526 return mFrameQueue.waitForBuffer(timeout);
527 }
528
getNextResult(CaptureResult * result)529 status_t Camera2Device::getNextResult(CaptureResult *result) {
530 ATRACE_CALL();
531 ALOGV("%s: get CaptureResult", __FUNCTION__);
532 if (result == NULL) {
533 ALOGE("%s: result pointer is NULL", __FUNCTION__);
534 return BAD_VALUE;
535 }
536 status_t res;
537 camera_metadata_t *rawFrame;
538 res = mFrameQueue.dequeue(&rawFrame);
539 if (rawFrame == NULL) {
540 return NOT_ENOUGH_DATA;
541 } else if (res == OK) {
542 result->mMetadata.acquire(rawFrame);
543 }
544
545 return res;
546 }
547
triggerAutofocus(uint32_t id)548 status_t Camera2Device::triggerAutofocus(uint32_t id) {
549 ATRACE_CALL();
550 status_t res;
551 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
552 res = mHal2Device->ops->trigger_action(mHal2Device,
553 CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
554 if (res != OK) {
555 ALOGE("%s: Error triggering autofocus (id %d)",
556 __FUNCTION__, id);
557 }
558 return res;
559 }
560
triggerCancelAutofocus(uint32_t id)561 status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
562 ATRACE_CALL();
563 status_t res;
564 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
565 res = mHal2Device->ops->trigger_action(mHal2Device,
566 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
567 if (res != OK) {
568 ALOGE("%s: Error canceling autofocus (id %d)",
569 __FUNCTION__, id);
570 }
571 return res;
572 }
573
triggerPrecaptureMetering(uint32_t id)574 status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
575 ATRACE_CALL();
576 status_t res;
577 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
578 res = mHal2Device->ops->trigger_action(mHal2Device,
579 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
580 if (res != OK) {
581 ALOGE("%s: Error triggering precapture metering (id %d)",
582 __FUNCTION__, id);
583 }
584 return res;
585 }
586
pushReprocessBuffer(int reprocessStreamId,buffer_handle_t * buffer,wp<BufferReleasedListener> listener)587 status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
588 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
589 ATRACE_CALL();
590 ALOGV("%s: E", __FUNCTION__);
591 bool found = false;
592 status_t res = OK;
593 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
594 streamI != mReprocessStreams.end(); streamI++) {
595 if ((*streamI)->getId() == reprocessStreamId) {
596 res = (*streamI)->pushIntoStream(buffer, listener);
597 if (res != OK) {
598 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
599 __FUNCTION__, reprocessStreamId, strerror(-res), res);
600 return res;
601 }
602 found = true;
603 break;
604 }
605 }
606 if (!found) {
607 ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
608 __FUNCTION__, mId, reprocessStreamId);
609 res = BAD_VALUE;
610 }
611 return res;
612 }
613
flush(int64_t *)614 status_t Camera2Device::flush(int64_t* /*lastFrameNumber*/) {
615 ATRACE_CALL();
616
617 mRequestQueue.clear();
618 return waitUntilDrained();
619 }
620
getDeviceVersion()621 uint32_t Camera2Device::getDeviceVersion() {
622 ATRACE_CALL();
623 return mDeviceVersion;
624 }
625
626 /**
627 * Camera2Device::MetadataQueue
628 */
629
MetadataQueue()630 Camera2Device::MetadataQueue::MetadataQueue():
631 mHal2Device(NULL),
632 mFrameCount(0),
633 mLatestRequestId(0),
634 mCount(0),
635 mStreamSlotCount(0),
636 mSignalConsumer(true)
637 {
638 ATRACE_CALL();
639 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
640 camera2_request_queue_src_ops::request_count = consumer_buffer_count;
641 camera2_request_queue_src_ops::free_request = consumer_free;
642
643 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
644 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
645 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
646 }
647
~MetadataQueue()648 Camera2Device::MetadataQueue::~MetadataQueue() {
649 ATRACE_CALL();
650 clear();
651 }
652
653 // Connect to camera2 HAL as consumer (input requests/reprocessing)
setConsumerDevice(camera2_device_t * d)654 status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
655 ATRACE_CALL();
656 status_t res;
657 res = d->ops->set_request_queue_src_ops(d,
658 this);
659 if (res != OK) return res;
660 mHal2Device = d;
661 return OK;
662 }
663
setProducerDevice(camera2_device_t * d)664 status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
665 ATRACE_CALL();
666 status_t res;
667 res = d->ops->set_frame_queue_dst_ops(d,
668 this);
669 return res;
670 }
671
672 // Real interfaces
enqueue(camera_metadata_t * buf)673 status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
674 ATRACE_CALL();
675 ALOGVV("%s: E", __FUNCTION__);
676 Mutex::Autolock l(mMutex);
677
678 mCount++;
679 mEntries.push_back(buf);
680
681 return signalConsumerLocked();
682 }
683
getBufferCount()684 int Camera2Device::MetadataQueue::getBufferCount() {
685 ATRACE_CALL();
686 Mutex::Autolock l(mMutex);
687 if (mStreamSlotCount > 0) {
688 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
689 }
690 return mCount;
691 }
692
dequeue(camera_metadata_t ** buf,bool incrementCount)693 status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
694 bool incrementCount)
695 {
696 ATRACE_CALL();
697 ALOGVV("%s: E", __FUNCTION__);
698 status_t res;
699 Mutex::Autolock l(mMutex);
700
701 if (mCount == 0) {
702 if (mStreamSlotCount == 0) {
703 ALOGVV("%s: Empty", __FUNCTION__);
704 *buf = NULL;
705 mSignalConsumer = true;
706 return OK;
707 }
708 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
709 mStreamSlotCount);
710
711 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
712 slotEntry != mStreamSlot.end();
713 slotEntry++ ) {
714 size_t entries = get_camera_metadata_entry_count(*slotEntry);
715 size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
716
717 camera_metadata_t *copy =
718 allocate_camera_metadata(entries, dataBytes);
719 append_camera_metadata(copy, *slotEntry);
720 mEntries.push_back(copy);
721 }
722 mCount = mStreamSlotCount;
723 }
724 ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
725 camera_metadata_t *b = *(mEntries.begin());
726 mEntries.erase(mEntries.begin());
727
728 if (incrementCount) {
729 ATRACE_INT("cam2_request", mFrameCount);
730 camera_metadata_entry_t frameCount;
731 res = find_camera_metadata_entry(b,
732 ANDROID_REQUEST_FRAME_COUNT,
733 &frameCount);
734 if (res != OK) {
735 ALOGE("%s: Unable to add frame count: %s (%d)",
736 __FUNCTION__, strerror(-res), res);
737 } else {
738 *frameCount.data.i32 = mFrameCount;
739 }
740 mFrameCount++;
741 }
742
743 // Check for request ID, and if present, signal waiters.
744 camera_metadata_entry_t requestId;
745 res = find_camera_metadata_entry(b,
746 ANDROID_REQUEST_ID,
747 &requestId);
748 if (res == OK) {
749 mLatestRequestId = requestId.data.i32[0];
750 mNewRequestId.signal();
751 }
752
753 *buf = b;
754 mCount--;
755
756 return OK;
757 }
758
waitForBuffer(nsecs_t timeout)759 status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
760 {
761 Mutex::Autolock l(mMutex);
762 status_t res;
763 while (mCount == 0) {
764 res = notEmpty.waitRelative(mMutex,timeout);
765 if (res != OK) return res;
766 }
767 return OK;
768 }
769
waitForDequeue(int32_t id,nsecs_t timeout)770 status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
771 nsecs_t timeout) {
772 Mutex::Autolock l(mMutex);
773 status_t res;
774 while (mLatestRequestId != id) {
775 nsecs_t startTime = systemTime();
776
777 res = mNewRequestId.waitRelative(mMutex, timeout);
778 if (res != OK) return res;
779
780 timeout -= (systemTime() - startTime);
781 }
782
783 return OK;
784 }
785
setStreamSlot(camera_metadata_t * buf)786 status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
787 {
788 ATRACE_CALL();
789 ALOGV("%s: E", __FUNCTION__);
790 Mutex::Autolock l(mMutex);
791 if (buf == NULL) {
792 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
793 mStreamSlotCount = 0;
794 return OK;
795 }
796
797 if (mStreamSlotCount > 1) {
798 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
799 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
800 mStreamSlotCount = 1;
801 }
802 if (mStreamSlotCount == 1) {
803 free_camera_metadata( *(mStreamSlot.begin()) );
804 *(mStreamSlot.begin()) = buf;
805 } else {
806 mStreamSlot.push_front(buf);
807 mStreamSlotCount = 1;
808 }
809 return signalConsumerLocked();
810 }
811
setStreamSlot(const List<camera_metadata_t * > & bufs)812 status_t Camera2Device::MetadataQueue::setStreamSlot(
813 const List<camera_metadata_t*> &bufs)
814 {
815 ATRACE_CALL();
816 ALOGV("%s: E", __FUNCTION__);
817 Mutex::Autolock l(mMutex);
818
819 if (mStreamSlotCount > 0) {
820 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
821 }
822 mStreamSlotCount = 0;
823 for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
824 r != bufs.end(); r++) {
825 mStreamSlot.push_back(*r);
826 mStreamSlotCount++;
827 }
828 return signalConsumerLocked();
829 }
830
clear()831 status_t Camera2Device::MetadataQueue::clear()
832 {
833 ATRACE_CALL();
834 ALOGV("%s: E", __FUNCTION__);
835
836 Mutex::Autolock l(mMutex);
837
838 // Clear streaming slot
839 freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
840 mStreamSlotCount = 0;
841
842 // Clear request queue
843 freeBuffers(mEntries.begin(), mEntries.end());
844 mCount = 0;
845 return OK;
846 }
847
dump(int fd,const Vector<String16> &)848 status_t Camera2Device::MetadataQueue::dump(int fd,
849 const Vector<String16>& /*args*/) {
850 ATRACE_CALL();
851 String8 result;
852 status_t notLocked;
853 notLocked = mMutex.tryLock();
854 if (notLocked) {
855 result.append(" (Unable to lock queue mutex)\n");
856 }
857 result.appendFormat(" Current frame number: %d\n", mFrameCount);
858 if (mStreamSlotCount == 0) {
859 result.append(" Stream slot: Empty\n");
860 write(fd, result.string(), result.size());
861 } else {
862 result.appendFormat(" Stream slot: %zu entries\n",
863 mStreamSlot.size());
864 int i = 0;
865 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
866 r != mStreamSlot.end(); r++) {
867 result = String8::format(" Stream slot buffer %d:\n", i);
868 write(fd, result.string(), result.size());
869 dump_indented_camera_metadata(*r, fd, 2, 10);
870 i++;
871 }
872 }
873 if (mEntries.size() == 0) {
874 result = " Main queue is empty\n";
875 write(fd, result.string(), result.size());
876 } else {
877 result = String8::format(" Main queue has %zu entries:\n",
878 mEntries.size());
879 int i = 0;
880 for (List<camera_metadata_t*>::iterator r = mEntries.begin();
881 r != mEntries.end(); r++) {
882 result = String8::format(" Queue entry %d:\n", i);
883 write(fd, result.string(), result.size());
884 dump_indented_camera_metadata(*r, fd, 2, 10);
885 i++;
886 }
887 }
888
889 if (notLocked == 0) {
890 mMutex.unlock();
891 }
892
893 return OK;
894 }
895
signalConsumerLocked()896 status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
897 ATRACE_CALL();
898 status_t res = OK;
899 notEmpty.signal();
900 if (mSignalConsumer && mHal2Device != NULL) {
901 mSignalConsumer = false;
902
903 mMutex.unlock();
904 ALOGV("%s: Signaling consumer", __FUNCTION__);
905 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
906 mMutex.lock();
907 }
908 return res;
909 }
910
freeBuffers(List<camera_metadata_t * >::iterator start,List<camera_metadata_t * >::iterator end)911 status_t Camera2Device::MetadataQueue::freeBuffers(
912 List<camera_metadata_t*>::iterator start,
913 List<camera_metadata_t*>::iterator end)
914 {
915 ATRACE_CALL();
916 while (start != end) {
917 free_camera_metadata(*start);
918 start = mStreamSlot.erase(start);
919 }
920 return OK;
921 }
922
getInstance(const camera2_request_queue_src_ops_t * q)923 Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
924 const camera2_request_queue_src_ops_t *q)
925 {
926 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
927 return const_cast<MetadataQueue*>(cmq);
928 }
929
getInstance(const camera2_frame_queue_dst_ops_t * q)930 Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
931 const camera2_frame_queue_dst_ops_t *q)
932 {
933 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
934 return const_cast<MetadataQueue*>(cmq);
935 }
936
consumer_buffer_count(const camera2_request_queue_src_ops_t * q)937 int Camera2Device::MetadataQueue::consumer_buffer_count(
938 const camera2_request_queue_src_ops_t *q)
939 {
940 MetadataQueue *queue = getInstance(q);
941 return queue->getBufferCount();
942 }
943
consumer_dequeue(const camera2_request_queue_src_ops_t * q,camera_metadata_t ** buffer)944 int Camera2Device::MetadataQueue::consumer_dequeue(
945 const camera2_request_queue_src_ops_t *q,
946 camera_metadata_t **buffer)
947 {
948 MetadataQueue *queue = getInstance(q);
949 return queue->dequeue(buffer, true);
950 }
951
consumer_free(const camera2_request_queue_src_ops_t * q,camera_metadata_t * old_buffer)952 int Camera2Device::MetadataQueue::consumer_free(
953 const camera2_request_queue_src_ops_t *q,
954 camera_metadata_t *old_buffer)
955 {
956 ATRACE_CALL();
957 MetadataQueue *queue = getInstance(q);
958 (void)queue;
959 free_camera_metadata(old_buffer);
960 return OK;
961 }
962
producer_dequeue(const camera2_frame_queue_dst_ops_t *,size_t entries,size_t bytes,camera_metadata_t ** buffer)963 int Camera2Device::MetadataQueue::producer_dequeue(
964 const camera2_frame_queue_dst_ops_t * /*q*/,
965 size_t entries, size_t bytes,
966 camera_metadata_t **buffer)
967 {
968 ATRACE_CALL();
969 camera_metadata_t *new_buffer =
970 allocate_camera_metadata(entries, bytes);
971 if (new_buffer == NULL) return NO_MEMORY;
972 *buffer = new_buffer;
973 return OK;
974 }
975
producer_cancel(const camera2_frame_queue_dst_ops_t *,camera_metadata_t * old_buffer)976 int Camera2Device::MetadataQueue::producer_cancel(
977 const camera2_frame_queue_dst_ops_t * /*q*/,
978 camera_metadata_t *old_buffer)
979 {
980 ATRACE_CALL();
981 free_camera_metadata(old_buffer);
982 return OK;
983 }
984
producer_enqueue(const camera2_frame_queue_dst_ops_t * q,camera_metadata_t * filled_buffer)985 int Camera2Device::MetadataQueue::producer_enqueue(
986 const camera2_frame_queue_dst_ops_t *q,
987 camera_metadata_t *filled_buffer)
988 {
989 MetadataQueue *queue = getInstance(q);
990 return queue->enqueue(filled_buffer);
991 }
992
993 /**
994 * Camera2Device::StreamAdapter
995 */
996
997 #ifndef container_of
998 #define container_of(ptr, type, member) \
999 (type *)((char*)(ptr) - offsetof(type, member))
1000 #endif
1001
StreamAdapter(camera2_device_t * d)1002 Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
1003 mState(RELEASED),
1004 mHal2Device(d),
1005 mId(-1),
1006 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
1007 mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
1008 mTotalBuffers(0),
1009 mFormatRequested(0),
1010 mActiveBuffers(0),
1011 mFrameCount(0),
1012 mLastTimestamp(0)
1013 {
1014 camera2_stream_ops::dequeue_buffer = dequeue_buffer;
1015 camera2_stream_ops::enqueue_buffer = enqueue_buffer;
1016 camera2_stream_ops::cancel_buffer = cancel_buffer;
1017 camera2_stream_ops::set_crop = set_crop;
1018 }
1019
~StreamAdapter()1020 Camera2Device::StreamAdapter::~StreamAdapter() {
1021 ATRACE_CALL();
1022 if (mState != RELEASED) {
1023 release();
1024 }
1025 }
1026
connectToDevice(sp<ANativeWindow> consumer,uint32_t width,uint32_t height,int format,size_t size)1027 status_t Camera2Device::StreamAdapter::connectToDevice(
1028 sp<ANativeWindow> consumer,
1029 uint32_t width, uint32_t height, int format, size_t size) {
1030 ATRACE_CALL();
1031 status_t res;
1032 ALOGV("%s: E", __FUNCTION__);
1033
1034 if (mState != RELEASED) return INVALID_OPERATION;
1035 if (consumer == NULL) {
1036 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
1037 return BAD_VALUE;
1038 }
1039
1040 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %zu",
1041 __FUNCTION__, width, height, format, size);
1042
1043 mConsumerInterface = consumer;
1044 mWidth = width;
1045 mHeight = height;
1046 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
1047 mFormatRequested = format;
1048
1049 // Allocate device-side stream interface
1050
1051 uint32_t id;
1052 uint32_t formatActual;
1053 uint32_t usage;
1054 uint32_t maxBuffers = 2;
1055 res = mHal2Device->ops->allocate_stream(mHal2Device,
1056 mWidth, mHeight, mFormatRequested, getStreamOps(),
1057 &id, &formatActual, &usage, &maxBuffers);
1058 if (res != OK) {
1059 ALOGE("%s: Device stream allocation failed: %s (%d)",
1060 __FUNCTION__, strerror(-res), res);
1061 return res;
1062 }
1063
1064 ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1065 "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1066 id, formatActual, usage, maxBuffers);
1067
1068 mId = id;
1069 mFormat = formatActual;
1070 mUsage = usage;
1071 mMaxProducerBuffers = maxBuffers;
1072
1073 mState = ALLOCATED;
1074
1075 // Configure consumer-side ANativeWindow interface
1076 res = native_window_api_connect(mConsumerInterface.get(),
1077 NATIVE_WINDOW_API_CAMERA);
1078 if (res != OK) {
1079 ALOGE("%s: Unable to connect to native window for stream %d",
1080 __FUNCTION__, mId);
1081
1082 return res;
1083 }
1084
1085 mState = CONNECTED;
1086
1087 res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1088 if (res != OK) {
1089 ALOGE("%s: Unable to configure usage %08x for stream %d",
1090 __FUNCTION__, mUsage, mId);
1091 return res;
1092 }
1093
1094 res = native_window_set_scaling_mode(mConsumerInterface.get(),
1095 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1096 if (res != OK) {
1097 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1098 __FUNCTION__, strerror(-res), res);
1099 return res;
1100 }
1101
1102 res = setTransform(0);
1103 if (res != OK) {
1104 return res;
1105 }
1106
1107 if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1108 res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1109 mSize, 1);
1110 if (res != OK) {
1111 ALOGE("%s: Unable to configure compressed stream buffer dimensions"
1112 " %d x %d, size %zu for stream %d",
1113 __FUNCTION__, mWidth, mHeight, mSize, mId);
1114 return res;
1115 }
1116 } else {
1117 res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1118 mWidth, mHeight);
1119 if (res != OK) {
1120 ALOGE("%s: Unable to configure stream buffer dimensions"
1121 " %d x %d for stream %d",
1122 __FUNCTION__, mWidth, mHeight, mId);
1123 return res;
1124 }
1125 }
1126
1127 res = native_window_set_buffers_format(mConsumerInterface.get(), mFormat);
1128 if (res != OK) {
1129 ALOGE("%s: Unable to configure stream buffer format"
1130 " %#x for stream %d",
1131 __FUNCTION__, mFormat, mId);
1132 return res;
1133 }
1134
1135 int maxConsumerBuffers;
1136 res = mConsumerInterface->query(mConsumerInterface.get(),
1137 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1138 if (res != OK) {
1139 ALOGE("%s: Unable to query consumer undequeued"
1140 " buffer count for stream %d", __FUNCTION__, mId);
1141 return res;
1142 }
1143 mMaxConsumerBuffers = maxConsumerBuffers;
1144
1145 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1146 mMaxConsumerBuffers);
1147
1148 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1149 mActiveBuffers = 0;
1150 mFrameCount = 0;
1151 mLastTimestamp = 0;
1152
1153 res = native_window_set_buffer_count(mConsumerInterface.get(),
1154 mTotalBuffers);
1155 if (res != OK) {
1156 ALOGE("%s: Unable to set buffer count for stream %d",
1157 __FUNCTION__, mId);
1158 return res;
1159 }
1160
1161 // Register allocated buffers with HAL device
1162 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1163 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1164 uint32_t bufferIdx = 0;
1165 for (; bufferIdx < mTotalBuffers; bufferIdx++) {
1166 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
1167 &anwBuffers[bufferIdx]);
1168 if (res != OK) {
1169 ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
1170 "stream %d", __FUNCTION__, bufferIdx, mId);
1171 goto cleanUpBuffers;
1172 }
1173
1174 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
1175 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
1176 }
1177
1178 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
1179 res = mHal2Device->ops->register_stream_buffers(mHal2Device,
1180 mId,
1181 mTotalBuffers,
1182 buffers);
1183 if (res != OK) {
1184 ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1185 __FUNCTION__, mId);
1186 } else {
1187 mState = ACTIVE;
1188 }
1189
1190 cleanUpBuffers:
1191 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
1192 for (uint32_t i = 0; i < bufferIdx; i++) {
1193 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
1194 anwBuffers[i], -1);
1195 if (res != OK) {
1196 ALOGE("%s: Unable to cancel buffer %d after registration",
1197 __FUNCTION__, i);
1198 }
1199 }
1200 delete[] anwBuffers;
1201 delete[] buffers;
1202
1203 return res;
1204 }
1205
release()1206 status_t Camera2Device::StreamAdapter::release() {
1207 ATRACE_CALL();
1208 status_t res;
1209 ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1210 mWidth, mHeight, mFormat);
1211 if (mState >= ALLOCATED) {
1212 res = mHal2Device->ops->release_stream(mHal2Device, mId);
1213 if (res != OK) {
1214 ALOGE("%s: Unable to release stream %d",
1215 __FUNCTION__, mId);
1216 return res;
1217 }
1218 }
1219 if (mState >= CONNECTED) {
1220 res = native_window_api_disconnect(mConsumerInterface.get(),
1221 NATIVE_WINDOW_API_CAMERA);
1222
1223 /* this is not an error. if client calling process dies,
1224 the window will also die and all calls to it will return
1225 DEAD_OBJECT, thus it's already "disconnected" */
1226 if (res == DEAD_OBJECT) {
1227 ALOGW("%s: While disconnecting stream %d from native window, the"
1228 " native window died from under us", __FUNCTION__, mId);
1229 }
1230 else if (res != OK) {
1231 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1232 __FUNCTION__, mId, res, strerror(-res));
1233 return res;
1234 }
1235 }
1236 mId = -1;
1237 mState = RELEASED;
1238 return OK;
1239 }
1240
setTransform(int transform)1241 status_t Camera2Device::StreamAdapter::setTransform(int transform) {
1242 ATRACE_CALL();
1243 status_t res;
1244 if (mState < CONNECTED) {
1245 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1246 return INVALID_OPERATION;
1247 }
1248 res = native_window_set_buffers_transform(mConsumerInterface.get(),
1249 transform);
1250 if (res != OK) {
1251 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1252 __FUNCTION__, transform, strerror(-res), res);
1253 }
1254 return res;
1255 }
1256
dump(int fd,const Vector<String16> &)1257 status_t Camera2Device::StreamAdapter::dump(int fd,
1258 const Vector<String16>& /*args*/) {
1259 ATRACE_CALL();
1260 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
1261 mId, mWidth, mHeight, mFormat);
1262 result.appendFormat(" size %zu, usage 0x%x, requested format 0x%x\n",
1263 mSize, mUsage, mFormatRequested);
1264 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
1265 mTotalBuffers, mActiveBuffers);
1266 result.appendFormat(" frame count: %d, last timestamp %" PRId64 "\n",
1267 mFrameCount, mLastTimestamp);
1268 write(fd, result.string(), result.size());
1269 return OK;
1270 }
1271
getStreamOps()1272 const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1273 return static_cast<camera2_stream_ops *>(this);
1274 }
1275
toANW(const camera2_stream_ops_t * w)1276 ANativeWindow* Camera2Device::StreamAdapter::toANW(
1277 const camera2_stream_ops_t *w) {
1278 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1279 }
1280
dequeue_buffer(const camera2_stream_ops_t * w,buffer_handle_t ** buffer)1281 int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1282 buffer_handle_t** buffer) {
1283 ATRACE_CALL();
1284 int res;
1285 StreamAdapter* stream =
1286 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1287 if (stream->mState != ACTIVE) {
1288 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1289 return INVALID_OPERATION;
1290 }
1291
1292 ANativeWindow *a = toANW(w);
1293 ANativeWindowBuffer* anb;
1294 res = native_window_dequeue_buffer_and_wait(a, &anb);
1295 if (res != OK) {
1296 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1297 strerror(-res), res);
1298 return res;
1299 }
1300
1301 *buffer = &(anb->handle);
1302 stream->mActiveBuffers++;
1303
1304 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
1305 return res;
1306 }
1307
enqueue_buffer(const camera2_stream_ops_t * w,int64_t timestamp,buffer_handle_t * buffer)1308 int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1309 int64_t timestamp,
1310 buffer_handle_t* buffer) {
1311 ATRACE_CALL();
1312 StreamAdapter *stream =
1313 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1314 stream->mFrameCount++;
1315 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
1316 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
1317 int state = stream->mState;
1318 if (state != ACTIVE) {
1319 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1320 return INVALID_OPERATION;
1321 }
1322 ANativeWindow *a = toANW(w);
1323 status_t err;
1324
1325 err = native_window_set_buffers_timestamp(a, timestamp);
1326 if (err != OK) {
1327 ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1328 __FUNCTION__, strerror(-err), err);
1329 return err;
1330 }
1331 err = a->queueBuffer(a,
1332 container_of(buffer, ANativeWindowBuffer, handle), -1);
1333 if (err != OK) {
1334 ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1335 __FUNCTION__, strerror(-err), err);
1336 return err;
1337 }
1338
1339 stream->mActiveBuffers--;
1340 stream->mLastTimestamp = timestamp;
1341 return OK;
1342 }
1343
cancel_buffer(const camera2_stream_ops_t * w,buffer_handle_t * buffer)1344 int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1345 buffer_handle_t* buffer) {
1346 ATRACE_CALL();
1347 StreamAdapter *stream =
1348 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1349 ALOGVV("Stream %d cancel: Buffer %p",
1350 stream->mId, (void*)(*buffer));
1351 if (stream->mState != ACTIVE) {
1352 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1353 return INVALID_OPERATION;
1354 }
1355
1356 ANativeWindow *a = toANW(w);
1357 int err = a->cancelBuffer(a,
1358 container_of(buffer, ANativeWindowBuffer, handle), -1);
1359 if (err != OK) {
1360 ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1361 __FUNCTION__, strerror(-err), err);
1362 return err;
1363 }
1364
1365 stream->mActiveBuffers--;
1366 return OK;
1367 }
1368
set_crop(const camera2_stream_ops_t * w,int left,int top,int right,int bottom)1369 int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1370 int left, int top, int right, int bottom) {
1371 ATRACE_CALL();
1372 int state = static_cast<const StreamAdapter*>(w)->mState;
1373 if (state != ACTIVE) {
1374 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1375 return INVALID_OPERATION;
1376 }
1377 ANativeWindow *a = toANW(w);
1378 android_native_rect_t crop = { left, top, right, bottom };
1379 return native_window_set_crop(a, &crop);
1380 }
1381
1382 /**
1383 * Camera2Device::ReprocessStreamAdapter
1384 */
1385
1386 #ifndef container_of
1387 #define container_of(ptr, type, member) \
1388 (type *)((char*)(ptr) - offsetof(type, member))
1389 #endif
1390
ReprocessStreamAdapter(camera2_device_t * d)1391 Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1392 mState(RELEASED),
1393 mHal2Device(d),
1394 mId(-1),
1395 mWidth(0), mHeight(0), mFormat(0),
1396 mActiveBuffers(0),
1397 mFrameCount(0)
1398 {
1399 ATRACE_CALL();
1400 camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1401 camera2_stream_in_ops::release_buffer = release_buffer;
1402 }
1403
~ReprocessStreamAdapter()1404 Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
1405 ATRACE_CALL();
1406 if (mState != RELEASED) {
1407 release();
1408 }
1409 }
1410
connectToDevice(const sp<StreamAdapter> & outputStream)1411 status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1412 const sp<StreamAdapter> &outputStream) {
1413 ATRACE_CALL();
1414 status_t res;
1415 ALOGV("%s: E", __FUNCTION__);
1416
1417 if (mState != RELEASED) return INVALID_OPERATION;
1418 if (outputStream == NULL) {
1419 ALOGE("%s: Null base stream passed to reprocess stream adapter",
1420 __FUNCTION__);
1421 return BAD_VALUE;
1422 }
1423
1424 mBaseStream = outputStream;
1425 mWidth = outputStream->getWidth();
1426 mHeight = outputStream->getHeight();
1427 mFormat = outputStream->getFormat();
1428
1429 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1430 __FUNCTION__, mWidth, mHeight, mFormat);
1431
1432 // Allocate device-side stream interface
1433
1434 uint32_t id;
1435 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
1436 outputStream->getId(), getStreamOps(),
1437 &id);
1438 if (res != OK) {
1439 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1440 __FUNCTION__, strerror(-res), res);
1441 return res;
1442 }
1443
1444 ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1445 __FUNCTION__, id, outputStream->getId());
1446
1447 mId = id;
1448
1449 mState = ACTIVE;
1450
1451 return OK;
1452 }
1453
release()1454 status_t Camera2Device::ReprocessStreamAdapter::release() {
1455 ATRACE_CALL();
1456 status_t res;
1457 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1458 if (mState >= ACTIVE) {
1459 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
1460 if (res != OK) {
1461 ALOGE("%s: Unable to release stream %d",
1462 __FUNCTION__, mId);
1463 return res;
1464 }
1465 }
1466
1467 List<QueueEntry>::iterator s;
1468 for (s = mQueue.begin(); s != mQueue.end(); s++) {
1469 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1470 if (listener != 0) listener->onBufferReleased(s->handle);
1471 }
1472 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1473 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1474 if (listener != 0) listener->onBufferReleased(s->handle);
1475 }
1476 mQueue.clear();
1477 mInFlightQueue.clear();
1478
1479 mState = RELEASED;
1480 return OK;
1481 }
1482
pushIntoStream(buffer_handle_t * handle,const wp<BufferReleasedListener> & releaseListener)1483 status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1484 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
1485 ATRACE_CALL();
1486 // TODO: Some error checking here would be nice
1487 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1488
1489 QueueEntry entry;
1490 entry.handle = handle;
1491 entry.releaseListener = releaseListener;
1492 mQueue.push_back(entry);
1493 return OK;
1494 }
1495
dump(int fd,const Vector<String16> &)1496 status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
1497 const Vector<String16>& /*args*/) {
1498 ATRACE_CALL();
1499 String8 result =
1500 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n",
1501 mId, mWidth, mHeight, mFormat);
1502 result.appendFormat(" acquired buffers: %d\n",
1503 mActiveBuffers);
1504 result.appendFormat(" frame count: %d\n",
1505 mFrameCount);
1506 write(fd, result.string(), result.size());
1507 return OK;
1508 }
1509
getStreamOps()1510 const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1511 return static_cast<camera2_stream_in_ops *>(this);
1512 }
1513
acquire_buffer(const camera2_stream_in_ops_t * w,buffer_handle_t ** buffer)1514 int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1515 const camera2_stream_in_ops_t *w,
1516 buffer_handle_t** buffer) {
1517 ATRACE_CALL();
1518
1519 ReprocessStreamAdapter* stream =
1520 const_cast<ReprocessStreamAdapter*>(
1521 static_cast<const ReprocessStreamAdapter*>(w));
1522 if (stream->mState != ACTIVE) {
1523 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1524 return INVALID_OPERATION;
1525 }
1526
1527 if (stream->mQueue.empty()) {
1528 *buffer = NULL;
1529 return OK;
1530 }
1531
1532 QueueEntry &entry = *(stream->mQueue.begin());
1533
1534 *buffer = entry.handle;
1535
1536 stream->mInFlightQueue.push_back(entry);
1537 stream->mQueue.erase(stream->mQueue.begin());
1538
1539 stream->mActiveBuffers++;
1540
1541 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1542 (void*)(**buffer));
1543 return OK;
1544 }
1545
release_buffer(const camera2_stream_in_ops_t * w,buffer_handle_t * buffer)1546 int Camera2Device::ReprocessStreamAdapter::release_buffer(
1547 const camera2_stream_in_ops_t* w,
1548 buffer_handle_t* buffer) {
1549 ATRACE_CALL();
1550 ReprocessStreamAdapter *stream =
1551 const_cast<ReprocessStreamAdapter*>(
1552 static_cast<const ReprocessStreamAdapter*>(w) );
1553 stream->mFrameCount++;
1554 ALOGV("Reprocess stream %d release: Frame %d (%p)",
1555 stream->mId, stream->mFrameCount, (void*)*buffer);
1556 int state = stream->mState;
1557 if (state != ACTIVE) {
1558 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1559 return INVALID_OPERATION;
1560 }
1561 stream->mActiveBuffers--;
1562
1563 List<QueueEntry>::iterator s;
1564 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1565 if ( s->handle == buffer ) break;
1566 }
1567 if (s == stream->mInFlightQueue.end()) {
1568 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1569 buffer);
1570 return INVALID_OPERATION;
1571 }
1572
1573 sp<BufferReleasedListener> listener = s->releaseListener.promote();
1574 if (listener != 0) {
1575 listener->onBufferReleased(s->handle);
1576 } else {
1577 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1578 }
1579 stream->mInFlightQueue.erase(s);
1580
1581 return OK;
1582 }
1583
1584 }; // namespace android
1585