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