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