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