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