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