Camera2Device.cpp revision abaa51d3ca31f0eda99e1d271e6dc64c877dbf58
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 33namespace android { 34 35Camera2Device::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 43Camera2Device::~Camera2Device() 44{ 45 ATRACE_CALL(); 46 ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId); 47 disconnect(); 48} 49 50int Camera2Device::getId() const { 51 return mId; 52} 53 54status_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 143status_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 168status_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 209const CameraMetadata& Camera2Device::info() const { 210 ALOGVV("%s: E", __FUNCTION__); 211 212 return mDeviceInfo; 213} 214 215status_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 224status_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 231status_t Camera2Device::clearStreamingRequest() { 232 ATRACE_CALL(); 233 return mRequestQueue.setStreamSlot(NULL); 234} 235 236status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) { 237 ATRACE_CALL(); 238 return mRequestQueue.waitForDequeue(requestId, timeout); 239} 240 241status_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 263status_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 300status_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 326status_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 348status_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 374status_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 402status_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 414status_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 437status_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 448bool Camera2Device::willNotify3A() { 449 return true; 450} 451 452void 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 nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 ); 468 listener->notifyShutter(ext1, timestamp); 469 break; 470 } 471 case CAMERA2_MSG_AUTOFOCUS: 472 listener->notifyAutoFocus(ext1, ext2); 473 break; 474 case CAMERA2_MSG_AUTOEXPOSURE: 475 listener->notifyAutoExposure(ext1, ext2); 476 break; 477 case CAMERA2_MSG_AUTOWB: 478 listener->notifyAutoWhitebalance(ext1, ext2); 479 break; 480 default: 481 ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!", 482 __FUNCTION__, msg_type, ext1, ext2, ext3); 483 } 484 } 485} 486 487status_t Camera2Device::waitForNextFrame(nsecs_t timeout) { 488 return mFrameQueue.waitForBuffer(timeout); 489} 490 491status_t Camera2Device::getNextFrame(CameraMetadata *frame) { 492 ATRACE_CALL(); 493 status_t res; 494 camera_metadata_t *rawFrame; 495 res = mFrameQueue.dequeue(&rawFrame); 496 if (rawFrame == NULL) { 497 return NOT_ENOUGH_DATA; 498 } else if (res == OK) { 499 frame->acquire(rawFrame); 500 } 501 return res; 502} 503 504status_t Camera2Device::triggerAutofocus(uint32_t id) { 505 ATRACE_CALL(); 506 status_t res; 507 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id); 508 res = mHal2Device->ops->trigger_action(mHal2Device, 509 CAMERA2_TRIGGER_AUTOFOCUS, id, 0); 510 if (res != OK) { 511 ALOGE("%s: Error triggering autofocus (id %d)", 512 __FUNCTION__, id); 513 } 514 return res; 515} 516 517status_t Camera2Device::triggerCancelAutofocus(uint32_t id) { 518 ATRACE_CALL(); 519 status_t res; 520 ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id); 521 res = mHal2Device->ops->trigger_action(mHal2Device, 522 CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0); 523 if (res != OK) { 524 ALOGE("%s: Error canceling autofocus (id %d)", 525 __FUNCTION__, id); 526 } 527 return res; 528} 529 530status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) { 531 ATRACE_CALL(); 532 status_t res; 533 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id); 534 res = mHal2Device->ops->trigger_action(mHal2Device, 535 CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0); 536 if (res != OK) { 537 ALOGE("%s: Error triggering precapture metering (id %d)", 538 __FUNCTION__, id); 539 } 540 return res; 541} 542 543status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId, 544 buffer_handle_t *buffer, wp<BufferReleasedListener> listener) { 545 ATRACE_CALL(); 546 ALOGV("%s: E", __FUNCTION__); 547 bool found = false; 548 status_t res = OK; 549 for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin(); 550 streamI != mReprocessStreams.end(); streamI++) { 551 if ((*streamI)->getId() == reprocessStreamId) { 552 res = (*streamI)->pushIntoStream(buffer, listener); 553 if (res != OK) { 554 ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)", 555 __FUNCTION__, reprocessStreamId, strerror(-res), res); 556 return res; 557 } 558 found = true; 559 break; 560 } 561 } 562 if (!found) { 563 ALOGE("%s: Camera %d: Unable to find reprocess stream %d", 564 __FUNCTION__, mId, reprocessStreamId); 565 res = BAD_VALUE; 566 } 567 return res; 568} 569 570status_t Camera2Device::flush() { 571 ATRACE_CALL(); 572 573 mRequestQueue.clear(); 574 return waitUntilDrained(); 575} 576 577/** 578 * Camera2Device::MetadataQueue 579 */ 580 581Camera2Device::MetadataQueue::MetadataQueue(): 582 mHal2Device(NULL), 583 mFrameCount(0), 584 mLatestRequestId(0), 585 mCount(0), 586 mStreamSlotCount(0), 587 mSignalConsumer(true) 588{ 589 ATRACE_CALL(); 590 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue; 591 camera2_request_queue_src_ops::request_count = consumer_buffer_count; 592 camera2_request_queue_src_ops::free_request = consumer_free; 593 594 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue; 595 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel; 596 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue; 597} 598 599Camera2Device::MetadataQueue::~MetadataQueue() { 600 ATRACE_CALL(); 601 clear(); 602} 603 604// Connect to camera2 HAL as consumer (input requests/reprocessing) 605status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) { 606 ATRACE_CALL(); 607 status_t res; 608 res = d->ops->set_request_queue_src_ops(d, 609 this); 610 if (res != OK) return res; 611 mHal2Device = d; 612 return OK; 613} 614 615status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) { 616 ATRACE_CALL(); 617 status_t res; 618 res = d->ops->set_frame_queue_dst_ops(d, 619 this); 620 return res; 621} 622 623// Real interfaces 624status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) { 625 ATRACE_CALL(); 626 ALOGVV("%s: E", __FUNCTION__); 627 Mutex::Autolock l(mMutex); 628 629 mCount++; 630 mEntries.push_back(buf); 631 632 return signalConsumerLocked(); 633} 634 635int Camera2Device::MetadataQueue::getBufferCount() { 636 ATRACE_CALL(); 637 Mutex::Autolock l(mMutex); 638 if (mStreamSlotCount > 0) { 639 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS; 640 } 641 return mCount; 642} 643 644status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf, 645 bool incrementCount) 646{ 647 ATRACE_CALL(); 648 ALOGVV("%s: E", __FUNCTION__); 649 status_t res; 650 Mutex::Autolock l(mMutex); 651 652 if (mCount == 0) { 653 if (mStreamSlotCount == 0) { 654 ALOGVV("%s: Empty", __FUNCTION__); 655 *buf = NULL; 656 mSignalConsumer = true; 657 return OK; 658 } 659 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__, 660 mStreamSlotCount); 661 662 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin(); 663 slotEntry != mStreamSlot.end(); 664 slotEntry++ ) { 665 size_t entries = get_camera_metadata_entry_count(*slotEntry); 666 size_t dataBytes = get_camera_metadata_data_count(*slotEntry); 667 668 camera_metadata_t *copy = 669 allocate_camera_metadata(entries, dataBytes); 670 append_camera_metadata(copy, *slotEntry); 671 mEntries.push_back(copy); 672 } 673 mCount = mStreamSlotCount; 674 } 675 ALOGVV("MetadataQueue: deque (%d buffers)", mCount); 676 camera_metadata_t *b = *(mEntries.begin()); 677 mEntries.erase(mEntries.begin()); 678 679 if (incrementCount) { 680 ATRACE_INT("cam2_request", mFrameCount); 681 camera_metadata_entry_t frameCount; 682 res = find_camera_metadata_entry(b, 683 ANDROID_REQUEST_FRAME_COUNT, 684 &frameCount); 685 if (res != OK) { 686 ALOGE("%s: Unable to add frame count: %s (%d)", 687 __FUNCTION__, strerror(-res), res); 688 } else { 689 *frameCount.data.i32 = mFrameCount; 690 } 691 mFrameCount++; 692 } 693 694 // Check for request ID, and if present, signal waiters. 695 camera_metadata_entry_t requestId; 696 res = find_camera_metadata_entry(b, 697 ANDROID_REQUEST_ID, 698 &requestId); 699 if (res == OK) { 700 mLatestRequestId = requestId.data.i32[0]; 701 mNewRequestId.signal(); 702 } 703 704 *buf = b; 705 mCount--; 706 707 return OK; 708} 709 710status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout) 711{ 712 Mutex::Autolock l(mMutex); 713 status_t res; 714 while (mCount == 0) { 715 res = notEmpty.waitRelative(mMutex,timeout); 716 if (res != OK) return res; 717 } 718 return OK; 719} 720 721status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id, 722 nsecs_t timeout) { 723 Mutex::Autolock l(mMutex); 724 status_t res; 725 while (mLatestRequestId != id) { 726 nsecs_t startTime = systemTime(); 727 728 res = mNewRequestId.waitRelative(mMutex, timeout); 729 if (res != OK) return res; 730 731 timeout -= (systemTime() - startTime); 732 } 733 734 return OK; 735} 736 737status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf) 738{ 739 ATRACE_CALL(); 740 ALOGV("%s: E", __FUNCTION__); 741 Mutex::Autolock l(mMutex); 742 if (buf == NULL) { 743 freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); 744 mStreamSlotCount = 0; 745 return OK; 746 } 747 camera_metadata_t *buf2 = clone_camera_metadata(buf); 748 if (!buf2) { 749 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__); 750 return NO_MEMORY; 751 } 752 753 if (mStreamSlotCount > 1) { 754 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin(); 755 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end()); 756 mStreamSlotCount = 1; 757 } 758 if (mStreamSlotCount == 1) { 759 free_camera_metadata( *(mStreamSlot.begin()) ); 760 *(mStreamSlot.begin()) = buf2; 761 } else { 762 mStreamSlot.push_front(buf2); 763 mStreamSlotCount = 1; 764 } 765 return signalConsumerLocked(); 766} 767 768status_t Camera2Device::MetadataQueue::setStreamSlot( 769 const List<camera_metadata_t*> &bufs) 770{ 771 ATRACE_CALL(); 772 ALOGV("%s: E", __FUNCTION__); 773 Mutex::Autolock l(mMutex); 774 775 if (mStreamSlotCount > 0) { 776 freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); 777 } 778 mStreamSlotCount = 0; 779 for (List<camera_metadata_t*>::const_iterator r = bufs.begin(); 780 r != bufs.end(); r++) { 781 camera_metadata_t *r2 = clone_camera_metadata(*r); 782 if (!r2) { 783 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__); 784 return NO_MEMORY; 785 } 786 mStreamSlot.push_back(r2); 787 mStreamSlotCount++; 788 } 789 return signalConsumerLocked(); 790} 791 792status_t Camera2Device::MetadataQueue::clear() 793{ 794 ATRACE_CALL(); 795 ALOGV("%s: E", __FUNCTION__); 796 797 Mutex::Autolock l(mMutex); 798 799 // Clear streaming slot 800 freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); 801 mStreamSlotCount = 0; 802 803 // Clear request queue 804 freeBuffers(mEntries.begin(), mEntries.end()); 805 mCount = 0; 806 return OK; 807} 808 809status_t Camera2Device::MetadataQueue::dump(int fd, 810 const Vector<String16>& /*args*/) { 811 ATRACE_CALL(); 812 String8 result; 813 status_t notLocked; 814 notLocked = mMutex.tryLock(); 815 if (notLocked) { 816 result.append(" (Unable to lock queue mutex)\n"); 817 } 818 result.appendFormat(" Current frame number: %d\n", mFrameCount); 819 if (mStreamSlotCount == 0) { 820 result.append(" Stream slot: Empty\n"); 821 write(fd, result.string(), result.size()); 822 } else { 823 result.appendFormat(" Stream slot: %d entries\n", 824 mStreamSlot.size()); 825 int i = 0; 826 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin(); 827 r != mStreamSlot.end(); r++) { 828 result = String8::format(" Stream slot buffer %d:\n", i); 829 write(fd, result.string(), result.size()); 830 dump_indented_camera_metadata(*r, fd, 2, 10); 831 i++; 832 } 833 } 834 if (mEntries.size() == 0) { 835 result = " Main queue is empty\n"; 836 write(fd, result.string(), result.size()); 837 } else { 838 result = String8::format(" Main queue has %d entries:\n", 839 mEntries.size()); 840 int i = 0; 841 for (List<camera_metadata_t*>::iterator r = mEntries.begin(); 842 r != mEntries.end(); r++) { 843 result = String8::format(" Queue entry %d:\n", i); 844 write(fd, result.string(), result.size()); 845 dump_indented_camera_metadata(*r, fd, 2, 10); 846 i++; 847 } 848 } 849 850 if (notLocked == 0) { 851 mMutex.unlock(); 852 } 853 854 return OK; 855} 856 857status_t Camera2Device::MetadataQueue::signalConsumerLocked() { 858 ATRACE_CALL(); 859 status_t res = OK; 860 notEmpty.signal(); 861 if (mSignalConsumer && mHal2Device != NULL) { 862 mSignalConsumer = false; 863 864 mMutex.unlock(); 865 ALOGV("%s: Signaling consumer", __FUNCTION__); 866 res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device); 867 mMutex.lock(); 868 } 869 return res; 870} 871 872status_t Camera2Device::MetadataQueue::freeBuffers( 873 List<camera_metadata_t*>::iterator start, 874 List<camera_metadata_t*>::iterator end) 875{ 876 ATRACE_CALL(); 877 while (start != end) { 878 free_camera_metadata(*start); 879 start = mStreamSlot.erase(start); 880 } 881 return OK; 882} 883 884Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance( 885 const camera2_request_queue_src_ops_t *q) 886{ 887 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q); 888 return const_cast<MetadataQueue*>(cmq); 889} 890 891Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance( 892 const camera2_frame_queue_dst_ops_t *q) 893{ 894 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q); 895 return const_cast<MetadataQueue*>(cmq); 896} 897 898int Camera2Device::MetadataQueue::consumer_buffer_count( 899 const camera2_request_queue_src_ops_t *q) 900{ 901 MetadataQueue *queue = getInstance(q); 902 return queue->getBufferCount(); 903} 904 905int Camera2Device::MetadataQueue::consumer_dequeue( 906 const camera2_request_queue_src_ops_t *q, 907 camera_metadata_t **buffer) 908{ 909 MetadataQueue *queue = getInstance(q); 910 return queue->dequeue(buffer, true); 911} 912 913int Camera2Device::MetadataQueue::consumer_free( 914 const camera2_request_queue_src_ops_t *q, 915 camera_metadata_t *old_buffer) 916{ 917 ATRACE_CALL(); 918 MetadataQueue *queue = getInstance(q); 919 (void)queue; 920 free_camera_metadata(old_buffer); 921 return OK; 922} 923 924int Camera2Device::MetadataQueue::producer_dequeue( 925 const camera2_frame_queue_dst_ops_t * /*q*/, 926 size_t entries, size_t bytes, 927 camera_metadata_t **buffer) 928{ 929 ATRACE_CALL(); 930 camera_metadata_t *new_buffer = 931 allocate_camera_metadata(entries, bytes); 932 if (new_buffer == NULL) return NO_MEMORY; 933 *buffer = new_buffer; 934 return OK; 935} 936 937int Camera2Device::MetadataQueue::producer_cancel( 938 const camera2_frame_queue_dst_ops_t * /*q*/, 939 camera_metadata_t *old_buffer) 940{ 941 ATRACE_CALL(); 942 free_camera_metadata(old_buffer); 943 return OK; 944} 945 946int Camera2Device::MetadataQueue::producer_enqueue( 947 const camera2_frame_queue_dst_ops_t *q, 948 camera_metadata_t *filled_buffer) 949{ 950 MetadataQueue *queue = getInstance(q); 951 return queue->enqueue(filled_buffer); 952} 953 954/** 955 * Camera2Device::StreamAdapter 956 */ 957 958#ifndef container_of 959#define container_of(ptr, type, member) \ 960 (type *)((char*)(ptr) - offsetof(type, member)) 961#endif 962 963Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d): 964 mState(RELEASED), 965 mHal2Device(d), 966 mId(-1), 967 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0), 968 mMaxProducerBuffers(0), mMaxConsumerBuffers(0), 969 mTotalBuffers(0), 970 mFormatRequested(0), 971 mActiveBuffers(0), 972 mFrameCount(0), 973 mLastTimestamp(0) 974{ 975 camera2_stream_ops::dequeue_buffer = dequeue_buffer; 976 camera2_stream_ops::enqueue_buffer = enqueue_buffer; 977 camera2_stream_ops::cancel_buffer = cancel_buffer; 978 camera2_stream_ops::set_crop = set_crop; 979} 980 981Camera2Device::StreamAdapter::~StreamAdapter() { 982 ATRACE_CALL(); 983 if (mState != RELEASED) { 984 release(); 985 } 986} 987 988status_t Camera2Device::StreamAdapter::connectToDevice( 989 sp<ANativeWindow> consumer, 990 uint32_t width, uint32_t height, int format, size_t size) { 991 ATRACE_CALL(); 992 status_t res; 993 ALOGV("%s: E", __FUNCTION__); 994 995 if (mState != RELEASED) return INVALID_OPERATION; 996 if (consumer == NULL) { 997 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__); 998 return BAD_VALUE; 999 } 1000 1001 ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d", 1002 __FUNCTION__, width, height, format, size); 1003 1004 mConsumerInterface = consumer; 1005 mWidth = width; 1006 mHeight = height; 1007 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0; 1008 mFormatRequested = format; 1009 1010 // Allocate device-side stream interface 1011 1012 uint32_t id; 1013 uint32_t formatActual; 1014 uint32_t usage; 1015 uint32_t maxBuffers = 2; 1016 res = mHal2Device->ops->allocate_stream(mHal2Device, 1017 mWidth, mHeight, mFormatRequested, getStreamOps(), 1018 &id, &formatActual, &usage, &maxBuffers); 1019 if (res != OK) { 1020 ALOGE("%s: Device stream allocation failed: %s (%d)", 1021 __FUNCTION__, strerror(-res), res); 1022 return res; 1023 } 1024 1025 ALOGV("%s: Allocated stream id %d, actual format 0x%x, " 1026 "usage 0x%x, producer wants %d buffers", __FUNCTION__, 1027 id, formatActual, usage, maxBuffers); 1028 1029 mId = id; 1030 mFormat = formatActual; 1031 mUsage = usage; 1032 mMaxProducerBuffers = maxBuffers; 1033 1034 mState = ALLOCATED; 1035 1036 // Configure consumer-side ANativeWindow interface 1037 res = native_window_api_connect(mConsumerInterface.get(), 1038 NATIVE_WINDOW_API_CAMERA); 1039 if (res != OK) { 1040 ALOGE("%s: Unable to connect to native window for stream %d", 1041 __FUNCTION__, mId); 1042 1043 return res; 1044 } 1045 1046 mState = CONNECTED; 1047 1048 res = native_window_set_usage(mConsumerInterface.get(), mUsage); 1049 if (res != OK) { 1050 ALOGE("%s: Unable to configure usage %08x for stream %d", 1051 __FUNCTION__, mUsage, mId); 1052 return res; 1053 } 1054 1055 res = native_window_set_scaling_mode(mConsumerInterface.get(), 1056 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 1057 if (res != OK) { 1058 ALOGE("%s: Unable to configure stream scaling: %s (%d)", 1059 __FUNCTION__, strerror(-res), res); 1060 return res; 1061 } 1062 1063 res = setTransform(0); 1064 if (res != OK) { 1065 return res; 1066 } 1067 1068 if (mFormat == HAL_PIXEL_FORMAT_BLOB) { 1069 res = native_window_set_buffers_geometry(mConsumerInterface.get(), 1070 mSize, 1, mFormat); 1071 if (res != OK) { 1072 ALOGE("%s: Unable to configure compressed stream buffer geometry" 1073 " %d x %d, size %d for stream %d", 1074 __FUNCTION__, mWidth, mHeight, mSize, mId); 1075 return res; 1076 } 1077 } else { 1078 res = native_window_set_buffers_geometry(mConsumerInterface.get(), 1079 mWidth, mHeight, mFormat); 1080 if (res != OK) { 1081 ALOGE("%s: Unable to configure stream buffer geometry" 1082 " %d x %d, format 0x%x for stream %d", 1083 __FUNCTION__, mWidth, mHeight, mFormat, mId); 1084 return res; 1085 } 1086 } 1087 1088 int maxConsumerBuffers; 1089 res = mConsumerInterface->query(mConsumerInterface.get(), 1090 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers); 1091 if (res != OK) { 1092 ALOGE("%s: Unable to query consumer undequeued" 1093 " buffer count for stream %d", __FUNCTION__, mId); 1094 return res; 1095 } 1096 mMaxConsumerBuffers = maxConsumerBuffers; 1097 1098 ALOGV("%s: Consumer wants %d buffers", __FUNCTION__, 1099 mMaxConsumerBuffers); 1100 1101 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers; 1102 mActiveBuffers = 0; 1103 mFrameCount = 0; 1104 mLastTimestamp = 0; 1105 1106 res = native_window_set_buffer_count(mConsumerInterface.get(), 1107 mTotalBuffers); 1108 if (res != OK) { 1109 ALOGE("%s: Unable to set buffer count for stream %d", 1110 __FUNCTION__, mId); 1111 return res; 1112 } 1113 1114 // Register allocated buffers with HAL device 1115 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers]; 1116 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers]; 1117 uint32_t bufferIdx = 0; 1118 for (; bufferIdx < mTotalBuffers; bufferIdx++) { 1119 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(), 1120 &anwBuffers[bufferIdx]); 1121 if (res != OK) { 1122 ALOGE("%s: Unable to dequeue buffer %d for initial registration for " 1123 "stream %d", __FUNCTION__, bufferIdx, mId); 1124 goto cleanUpBuffers; 1125 } 1126 1127 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle; 1128 ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]); 1129 } 1130 1131 ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers); 1132 res = mHal2Device->ops->register_stream_buffers(mHal2Device, 1133 mId, 1134 mTotalBuffers, 1135 buffers); 1136 if (res != OK) { 1137 ALOGE("%s: Unable to register buffers with HAL device for stream %d", 1138 __FUNCTION__, mId); 1139 } else { 1140 mState = ACTIVE; 1141 } 1142 1143cleanUpBuffers: 1144 ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx); 1145 for (uint32_t i = 0; i < bufferIdx; i++) { 1146 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(), 1147 anwBuffers[i], -1); 1148 if (res != OK) { 1149 ALOGE("%s: Unable to cancel buffer %d after registration", 1150 __FUNCTION__, i); 1151 } 1152 } 1153 delete[] anwBuffers; 1154 delete[] buffers; 1155 1156 return res; 1157} 1158 1159status_t Camera2Device::StreamAdapter::release() { 1160 ATRACE_CALL(); 1161 status_t res; 1162 ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId, 1163 mWidth, mHeight, mFormat); 1164 if (mState >= ALLOCATED) { 1165 res = mHal2Device->ops->release_stream(mHal2Device, mId); 1166 if (res != OK) { 1167 ALOGE("%s: Unable to release stream %d", 1168 __FUNCTION__, mId); 1169 return res; 1170 } 1171 } 1172 if (mState >= CONNECTED) { 1173 res = native_window_api_disconnect(mConsumerInterface.get(), 1174 NATIVE_WINDOW_API_CAMERA); 1175 1176 /* this is not an error. if client calling process dies, 1177 the window will also die and all calls to it will return 1178 DEAD_OBJECT, thus it's already "disconnected" */ 1179 if (res == DEAD_OBJECT) { 1180 ALOGW("%s: While disconnecting stream %d from native window, the" 1181 " native window died from under us", __FUNCTION__, mId); 1182 } 1183 else if (res != OK) { 1184 ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)", 1185 __FUNCTION__, mId, res, strerror(-res)); 1186 return res; 1187 } 1188 } 1189 mId = -1; 1190 mState = RELEASED; 1191 return OK; 1192} 1193 1194status_t Camera2Device::StreamAdapter::setTransform(int transform) { 1195 ATRACE_CALL(); 1196 status_t res; 1197 if (mState < CONNECTED) { 1198 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__); 1199 return INVALID_OPERATION; 1200 } 1201 res = native_window_set_buffers_transform(mConsumerInterface.get(), 1202 transform); 1203 if (res != OK) { 1204 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)", 1205 __FUNCTION__, transform, strerror(-res), res); 1206 } 1207 return res; 1208} 1209 1210status_t Camera2Device::StreamAdapter::dump(int fd, 1211 const Vector<String16>& /*args*/) { 1212 ATRACE_CALL(); 1213 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n", 1214 mId, mWidth, mHeight, mFormat); 1215 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n", 1216 mSize, mUsage, mFormatRequested); 1217 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n", 1218 mTotalBuffers, mActiveBuffers); 1219 result.appendFormat(" frame count: %d, last timestamp %lld\n", 1220 mFrameCount, mLastTimestamp); 1221 write(fd, result.string(), result.size()); 1222 return OK; 1223} 1224 1225const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() { 1226 return static_cast<camera2_stream_ops *>(this); 1227} 1228 1229ANativeWindow* Camera2Device::StreamAdapter::toANW( 1230 const camera2_stream_ops_t *w) { 1231 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get(); 1232} 1233 1234int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w, 1235 buffer_handle_t** buffer) { 1236 ATRACE_CALL(); 1237 int res; 1238 StreamAdapter* stream = 1239 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w)); 1240 if (stream->mState != ACTIVE) { 1241 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState); 1242 return INVALID_OPERATION; 1243 } 1244 1245 ANativeWindow *a = toANW(w); 1246 ANativeWindowBuffer* anb; 1247 res = native_window_dequeue_buffer_and_wait(a, &anb); 1248 if (res != OK) { 1249 ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId, 1250 strerror(-res), res); 1251 return res; 1252 } 1253 1254 *buffer = &(anb->handle); 1255 stream->mActiveBuffers++; 1256 1257 ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer)); 1258 return res; 1259} 1260 1261int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w, 1262 int64_t timestamp, 1263 buffer_handle_t* buffer) { 1264 ATRACE_CALL(); 1265 StreamAdapter *stream = 1266 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w)); 1267 stream->mFrameCount++; 1268 ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns", 1269 stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp); 1270 int state = stream->mState; 1271 if (state != ACTIVE) { 1272 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 1273 return INVALID_OPERATION; 1274 } 1275 ANativeWindow *a = toANW(w); 1276 status_t err; 1277 1278 err = native_window_set_buffers_timestamp(a, timestamp); 1279 if (err != OK) { 1280 ALOGE("%s: Error setting timestamp on native window: %s (%d)", 1281 __FUNCTION__, strerror(-err), err); 1282 return err; 1283 } 1284 err = a->queueBuffer(a, 1285 container_of(buffer, ANativeWindowBuffer, handle), -1); 1286 if (err != OK) { 1287 ALOGE("%s: Error queueing buffer to native window: %s (%d)", 1288 __FUNCTION__, strerror(-err), err); 1289 return err; 1290 } 1291 1292 stream->mActiveBuffers--; 1293 stream->mLastTimestamp = timestamp; 1294 return OK; 1295} 1296 1297int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w, 1298 buffer_handle_t* buffer) { 1299 ATRACE_CALL(); 1300 StreamAdapter *stream = 1301 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w)); 1302 ALOGVV("Stream %d cancel: Buffer %p", 1303 stream->mId, (void*)(*buffer)); 1304 if (stream->mState != ACTIVE) { 1305 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState); 1306 return INVALID_OPERATION; 1307 } 1308 1309 ANativeWindow *a = toANW(w); 1310 int err = a->cancelBuffer(a, 1311 container_of(buffer, ANativeWindowBuffer, handle), -1); 1312 if (err != OK) { 1313 ALOGE("%s: Error canceling buffer to native window: %s (%d)", 1314 __FUNCTION__, strerror(-err), err); 1315 return err; 1316 } 1317 1318 stream->mActiveBuffers--; 1319 return OK; 1320} 1321 1322int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w, 1323 int left, int top, int right, int bottom) { 1324 ATRACE_CALL(); 1325 int state = static_cast<const StreamAdapter*>(w)->mState; 1326 if (state != ACTIVE) { 1327 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 1328 return INVALID_OPERATION; 1329 } 1330 ANativeWindow *a = toANW(w); 1331 android_native_rect_t crop = { left, top, right, bottom }; 1332 return native_window_set_crop(a, &crop); 1333} 1334 1335/** 1336 * Camera2Device::ReprocessStreamAdapter 1337 */ 1338 1339#ifndef container_of 1340#define container_of(ptr, type, member) \ 1341 (type *)((char*)(ptr) - offsetof(type, member)) 1342#endif 1343 1344Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d): 1345 mState(RELEASED), 1346 mHal2Device(d), 1347 mId(-1), 1348 mWidth(0), mHeight(0), mFormat(0), 1349 mActiveBuffers(0), 1350 mFrameCount(0) 1351{ 1352 ATRACE_CALL(); 1353 camera2_stream_in_ops::acquire_buffer = acquire_buffer; 1354 camera2_stream_in_ops::release_buffer = release_buffer; 1355} 1356 1357Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() { 1358 ATRACE_CALL(); 1359 if (mState != RELEASED) { 1360 release(); 1361 } 1362} 1363 1364status_t Camera2Device::ReprocessStreamAdapter::connectToDevice( 1365 const sp<StreamAdapter> &outputStream) { 1366 ATRACE_CALL(); 1367 status_t res; 1368 ALOGV("%s: E", __FUNCTION__); 1369 1370 if (mState != RELEASED) return INVALID_OPERATION; 1371 if (outputStream == NULL) { 1372 ALOGE("%s: Null base stream passed to reprocess stream adapter", 1373 __FUNCTION__); 1374 return BAD_VALUE; 1375 } 1376 1377 mBaseStream = outputStream; 1378 mWidth = outputStream->getWidth(); 1379 mHeight = outputStream->getHeight(); 1380 mFormat = outputStream->getFormat(); 1381 1382 ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x", 1383 __FUNCTION__, mWidth, mHeight, mFormat); 1384 1385 // Allocate device-side stream interface 1386 1387 uint32_t id; 1388 res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device, 1389 outputStream->getId(), getStreamOps(), 1390 &id); 1391 if (res != OK) { 1392 ALOGE("%s: Device reprocess stream allocation failed: %s (%d)", 1393 __FUNCTION__, strerror(-res), res); 1394 return res; 1395 } 1396 1397 ALOGV("%s: Allocated reprocess stream id %d based on stream %d", 1398 __FUNCTION__, id, outputStream->getId()); 1399 1400 mId = id; 1401 1402 mState = ACTIVE; 1403 1404 return OK; 1405} 1406 1407status_t Camera2Device::ReprocessStreamAdapter::release() { 1408 ATRACE_CALL(); 1409 status_t res; 1410 ALOGV("%s: Releasing stream %d", __FUNCTION__, mId); 1411 if (mState >= ACTIVE) { 1412 res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId); 1413 if (res != OK) { 1414 ALOGE("%s: Unable to release stream %d", 1415 __FUNCTION__, mId); 1416 return res; 1417 } 1418 } 1419 1420 List<QueueEntry>::iterator s; 1421 for (s = mQueue.begin(); s != mQueue.end(); s++) { 1422 sp<BufferReleasedListener> listener = s->releaseListener.promote(); 1423 if (listener != 0) listener->onBufferReleased(s->handle); 1424 } 1425 for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) { 1426 sp<BufferReleasedListener> listener = s->releaseListener.promote(); 1427 if (listener != 0) listener->onBufferReleased(s->handle); 1428 } 1429 mQueue.clear(); 1430 mInFlightQueue.clear(); 1431 1432 mState = RELEASED; 1433 return OK; 1434} 1435 1436status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream( 1437 buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) { 1438 ATRACE_CALL(); 1439 // TODO: Some error checking here would be nice 1440 ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle)); 1441 1442 QueueEntry entry; 1443 entry.handle = handle; 1444 entry.releaseListener = releaseListener; 1445 mQueue.push_back(entry); 1446 return OK; 1447} 1448 1449status_t Camera2Device::ReprocessStreamAdapter::dump(int fd, 1450 const Vector<String16>& /*args*/) { 1451 ATRACE_CALL(); 1452 String8 result = 1453 String8::format(" Reprocess stream %d: %d x %d, fmt 0x%x\n", 1454 mId, mWidth, mHeight, mFormat); 1455 result.appendFormat(" acquired buffers: %d\n", 1456 mActiveBuffers); 1457 result.appendFormat(" frame count: %d\n", 1458 mFrameCount); 1459 write(fd, result.string(), result.size()); 1460 return OK; 1461} 1462 1463const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() { 1464 return static_cast<camera2_stream_in_ops *>(this); 1465} 1466 1467int Camera2Device::ReprocessStreamAdapter::acquire_buffer( 1468 const camera2_stream_in_ops_t *w, 1469 buffer_handle_t** buffer) { 1470 ATRACE_CALL(); 1471 1472 ReprocessStreamAdapter* stream = 1473 const_cast<ReprocessStreamAdapter*>( 1474 static_cast<const ReprocessStreamAdapter*>(w)); 1475 if (stream->mState != ACTIVE) { 1476 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState); 1477 return INVALID_OPERATION; 1478 } 1479 1480 if (stream->mQueue.empty()) { 1481 *buffer = NULL; 1482 return OK; 1483 } 1484 1485 QueueEntry &entry = *(stream->mQueue.begin()); 1486 1487 *buffer = entry.handle; 1488 1489 stream->mInFlightQueue.push_back(entry); 1490 stream->mQueue.erase(stream->mQueue.begin()); 1491 1492 stream->mActiveBuffers++; 1493 1494 ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId, 1495 (void*)(**buffer)); 1496 return OK; 1497} 1498 1499int Camera2Device::ReprocessStreamAdapter::release_buffer( 1500 const camera2_stream_in_ops_t* w, 1501 buffer_handle_t* buffer) { 1502 ATRACE_CALL(); 1503 ReprocessStreamAdapter *stream = 1504 const_cast<ReprocessStreamAdapter*>( 1505 static_cast<const ReprocessStreamAdapter*>(w) ); 1506 stream->mFrameCount++; 1507 ALOGV("Reprocess stream %d release: Frame %d (%p)", 1508 stream->mId, stream->mFrameCount, (void*)*buffer); 1509 int state = stream->mState; 1510 if (state != ACTIVE) { 1511 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 1512 return INVALID_OPERATION; 1513 } 1514 stream->mActiveBuffers--; 1515 1516 List<QueueEntry>::iterator s; 1517 for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) { 1518 if ( s->handle == buffer ) break; 1519 } 1520 if (s == stream->mInFlightQueue.end()) { 1521 ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__, 1522 buffer); 1523 return INVALID_OPERATION; 1524 } 1525 1526 sp<BufferReleasedListener> listener = s->releaseListener.promote(); 1527 if (listener != 0) { 1528 listener->onBufferReleased(s->handle); 1529 } else { 1530 ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__); 1531 } 1532 stream->mInFlightQueue.erase(s); 1533 1534 return OK; 1535} 1536 1537}; // namespace android 1538