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