Camera2Device.cpp revision 2c08dc66c2980a50e90befe84f836b7ebf17fe94
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 "Camera2Device" 18//#define LOG_NDEBUG 0 19//#define LOG_NNDEBUG 0 // Per-frame verbose logging 20 21#ifdef LOG_NNDEBUG 22#define ALOGVV(...) ALOGV(__VA_ARGS__) 23#else 24#define ALOGVV(...) ((void)0) 25#endif 26 27#include <utils/Log.h> 28#include "Camera2Device.h" 29 30namespace android { 31 32Camera2Device::Camera2Device(int id): 33 mId(id), 34 mDevice(NULL) 35{ 36 ALOGV("%s: E", __FUNCTION__); 37} 38 39Camera2Device::~Camera2Device() 40{ 41 ALOGV("%s: E", __FUNCTION__); 42 if (mDevice) { 43 status_t res; 44 res = mDevice->common.close(&mDevice->common); 45 if (res != OK) { 46 ALOGE("%s: Could not close camera %d: %s (%d)", 47 __FUNCTION__, 48 mId, strerror(-res), res); 49 } 50 mDevice = NULL; 51 } 52} 53 54status_t Camera2Device::initialize(camera_module_t *module) 55{ 56 ALOGV("%s: E", __FUNCTION__); 57 58 status_t res; 59 char name[10]; 60 snprintf(name, sizeof(name), "%d", mId); 61 62 res = module->common.methods->open(&module->common, name, 63 reinterpret_cast<hw_device_t**>(&mDevice)); 64 65 if (res != OK) { 66 ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__, 67 mId, strerror(-res), res); 68 return res; 69 } 70 71 if (mDevice->common.version != CAMERA_DEVICE_API_VERSION_2_0) { 72 ALOGE("%s: Could not open camera %d: " 73 "Camera device is not version %x, reports %x instead", 74 __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0, 75 mDevice->common.version); 76 return BAD_VALUE; 77 } 78 79 camera_info info; 80 res = module->get_camera_info(mId, &info); 81 if (res != OK ) return res; 82 83 if (info.device_version != mDevice->common.version) { 84 ALOGE("%s: HAL reporting mismatched camera_info version (%x)" 85 " and device version (%x).", __FUNCTION__, 86 mDevice->common.version, info.device_version); 87 return BAD_VALUE; 88 } 89 90 mDeviceInfo = info.static_camera_characteristics; 91 92 res = mRequestQueue.setConsumerDevice(mDevice); 93 if (res != OK) { 94 ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)", 95 __FUNCTION__, mId, strerror(-res), res); 96 return res; 97 } 98 res = mFrameQueue.setProducerDevice(mDevice); 99 if (res != OK) { 100 ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)", 101 __FUNCTION__, mId, strerror(-res), res); 102 return res; 103 } 104 105 res = mDevice->ops->get_metadata_vendor_tag_ops(mDevice, &mVendorTagOps); 106 if (res != OK ) { 107 ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)", 108 __FUNCTION__, mId, strerror(-res), res); 109 return res; 110 } 111 112 return OK; 113} 114 115status_t Camera2Device::dump(int fd, const Vector<String16>& args) { 116 117 String8 result; 118 119 result.appendFormat(" Camera2Device[%d] dump:\n", mId); 120 121 result.appendFormat(" Static camera information metadata:\n"); 122 write(fd, result.string(), result.size()); 123 dump_camera_metadata(mDeviceInfo, fd, 2); 124 125 result = " Request queue contents:\n"; 126 write(fd, result.string(), result.size()); 127 mRequestQueue.dump(fd, args); 128 129 result = " Frame queue contents:\n"; 130 write(fd, result.string(), result.size()); 131 mFrameQueue.dump(fd, args); 132 133 result = " Active streams:\n"; 134 write(fd, result.string(), result.size()); 135 for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) { 136 (*s)->dump(fd, args); 137 } 138 139 result = " HAL device dump:\n"; 140 write(fd, result.string(), result.size()); 141 142 status_t res; 143 res = mDevice->ops->dump(mDevice, fd); 144 145 return res; 146} 147 148camera_metadata_t *Camera2Device::info() { 149 ALOGV("%s: E", __FUNCTION__); 150 151 return mDeviceInfo; 152} 153 154status_t Camera2Device::capture(camera_metadata_t* request) { 155 ALOGV("%s: E", __FUNCTION__); 156 157 mRequestQueue.enqueue(request); 158 return OK; 159} 160 161 162status_t Camera2Device::setStreamingRequest(camera_metadata_t* request) { 163 ALOGV("%s: E", __FUNCTION__); 164 165 mRequestQueue.setStreamSlot(request); 166 return OK; 167} 168 169status_t Camera2Device::createStream(sp<ANativeWindow> consumer, 170 uint32_t width, uint32_t height, int format, size_t size, int *id) { 171 status_t res; 172 ALOGV("%s: E", __FUNCTION__); 173 174 sp<StreamAdapter> stream = new StreamAdapter(mDevice); 175 176 res = stream->connectToDevice(consumer, width, height, format, size); 177 if (res != OK) { 178 ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):" 179 "%s (%d)", 180 __FUNCTION__, mId, width, height, format, strerror(-res), res); 181 return res; 182 } 183 184 *id = stream->getId(); 185 186 mStreams.push_back(stream); 187 return OK; 188} 189 190status_t Camera2Device::getStreamInfo(int id, 191 uint32_t *width, uint32_t *height, uint32_t *format) { 192 ALOGV("%s: E", __FUNCTION__); 193 bool found = false; 194 StreamList::iterator streamI; 195 for (streamI = mStreams.begin(); 196 streamI != mStreams.end(); streamI++) { 197 if ((*streamI)->getId() == id) { 198 found = true; 199 break; 200 } 201 } 202 if (!found) { 203 ALOGE("%s: Camera %d: Stream %d does not exist", 204 __FUNCTION__, mId, id); 205 return BAD_VALUE; 206 } 207 208 if (width) *width = (*streamI)->getWidth(); 209 if (height) *height = (*streamI)->getHeight(); 210 if (format) *format = (*streamI)->getFormat(); 211 212 return OK; 213} 214 215status_t Camera2Device::setStreamTransform(int id, 216 int transform) { 217 ALOGV("%s: E", __FUNCTION__); 218 bool found = false; 219 StreamList::iterator streamI; 220 for (streamI = mStreams.begin(); 221 streamI != mStreams.end(); streamI++) { 222 if ((*streamI)->getId() == id) { 223 found = true; 224 break; 225 } 226 } 227 if (!found) { 228 ALOGE("%s: Camera %d: Stream %d does not exist", 229 __FUNCTION__, mId, id); 230 return BAD_VALUE; 231 } 232 233 return (*streamI)->setTransform(transform); 234} 235 236status_t Camera2Device::deleteStream(int id) { 237 ALOGV("%s: E", __FUNCTION__); 238 bool found = false; 239 for (StreamList::iterator streamI = mStreams.begin(); 240 streamI != mStreams.end(); streamI++) { 241 if ((*streamI)->getId() == id) { 242 status_t res = (*streamI)->disconnect(); 243 if (res != OK) { 244 ALOGE("%s: Unable to disconnect stream %d from HAL device: " 245 "%s (%d)", __FUNCTION__, id, strerror(-res), res); 246 return res; 247 } 248 mStreams.erase(streamI); 249 found = true; 250 break; 251 } 252 } 253 if (!found) { 254 ALOGE("%s: Camera %d: Unable to find stream %d to delete", 255 __FUNCTION__, mId, id); 256 return BAD_VALUE; 257 } 258 return OK; 259} 260 261status_t Camera2Device::createDefaultRequest(int templateId, 262 camera_metadata_t **request) { 263 ALOGV("%s: E", __FUNCTION__); 264 return mDevice->ops->construct_default_request( 265 mDevice, templateId, request); 266} 267 268status_t Camera2Device::waitUntilDrained() { 269 static const uint32_t kSleepTime = 50000; // 50 ms 270 static const uint32_t kMaxSleepTime = 10000000; // 10 s 271 272 if (mRequestQueue.getBufferCount() == 273 CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION; 274 275 // TODO: Set up notifications from HAL, instead of sleeping here 276 uint32_t totalTime = 0; 277 while (mDevice->ops->get_in_progress_count(mDevice) > 0) { 278 usleep(kSleepTime); 279 totalTime += kSleepTime; 280 if (totalTime > kMaxSleepTime) { 281 ALOGE("%s: Waited %d us, requests still in flight", __FUNCTION__, 282 totalTime); 283 return TIMED_OUT; 284 } 285 } 286 return OK; 287} 288 289/** 290 * Camera2Device::MetadataQueue 291 */ 292 293Camera2Device::MetadataQueue::MetadataQueue(): 294 mDevice(NULL), 295 mFrameCount(0), 296 mCount(0), 297 mStreamSlotCount(0), 298 mSignalConsumer(true) 299{ 300 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue; 301 camera2_request_queue_src_ops::request_count = consumer_buffer_count; 302 camera2_request_queue_src_ops::free_request = consumer_free; 303 304 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue; 305 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel; 306 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue; 307} 308 309Camera2Device::MetadataQueue::~MetadataQueue() { 310 Mutex::Autolock l(mMutex); 311 freeBuffers(mEntries.begin(), mEntries.end()); 312 freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); 313} 314 315// Connect to camera2 HAL as consumer (input requests/reprocessing) 316status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) { 317 status_t res; 318 res = d->ops->set_request_queue_src_ops(d, 319 this); 320 if (res != OK) return res; 321 mDevice = d; 322 return OK; 323} 324 325status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) { 326 status_t res; 327 res = d->ops->set_frame_queue_dst_ops(d, 328 this); 329 return res; 330} 331 332// Real interfaces 333status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) { 334 ALOGVV("%s: E", __FUNCTION__); 335 Mutex::Autolock l(mMutex); 336 337 mCount++; 338 mEntries.push_back(buf); 339 340 return signalConsumerLocked(); 341} 342 343int Camera2Device::MetadataQueue::getBufferCount() { 344 Mutex::Autolock l(mMutex); 345 if (mStreamSlotCount > 0) { 346 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS; 347 } 348 return mCount; 349} 350 351status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf, 352 bool incrementCount) 353{ 354 ALOGVV("%s: E", __FUNCTION__); 355 status_t res; 356 Mutex::Autolock l(mMutex); 357 358 if (mCount == 0) { 359 if (mStreamSlotCount == 0) { 360 ALOGVV("%s: Empty", __FUNCTION__); 361 *buf = NULL; 362 mSignalConsumer = true; 363 return OK; 364 } 365 ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__, 366 mStreamSlotCount); 367 368 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin(); 369 slotEntry != mStreamSlot.end(); 370 slotEntry++ ) { 371 size_t entries = get_camera_metadata_entry_count(*slotEntry); 372 size_t dataBytes = get_camera_metadata_data_count(*slotEntry); 373 374 camera_metadata_t *copy = 375 allocate_camera_metadata(entries, dataBytes); 376 append_camera_metadata(copy, *slotEntry); 377 mEntries.push_back(copy); 378 } 379 mCount = mStreamSlotCount; 380 } 381 ALOGVV("MetadataQueue: deque (%d buffers)", mCount); 382 camera_metadata_t *b = *(mEntries.begin()); 383 mEntries.erase(mEntries.begin()); 384 385 if (incrementCount) { 386 camera_metadata_entry_t frameCount; 387 res = find_camera_metadata_entry(b, 388 ANDROID_REQUEST_FRAME_COUNT, 389 &frameCount); 390 if (res != OK) { 391 ALOGE("%s: Unable to add frame count: %s (%d)", 392 __FUNCTION__, strerror(-res), res); 393 } else { 394 *frameCount.data.i32 = mFrameCount; 395 } 396 mFrameCount++; 397 } 398 399 *buf = b; 400 mCount--; 401 402 return OK; 403} 404 405status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout) 406{ 407 Mutex::Autolock l(mMutex); 408 status_t res; 409 while (mCount == 0) { 410 res = notEmpty.waitRelative(mMutex,timeout); 411 if (res != OK) return res; 412 } 413 return OK; 414} 415 416status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf) 417{ 418 ALOGV("%s: E", __FUNCTION__); 419 Mutex::Autolock l(mMutex); 420 if (buf == NULL) { 421 freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); 422 mStreamSlotCount = 0; 423 return OK; 424 } 425 camera_metadata_t *buf2 = clone_camera_metadata(buf); 426 if (!buf2) { 427 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__); 428 return NO_MEMORY; 429 } 430 431 if (mStreamSlotCount > 1) { 432 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin(); 433 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end()); 434 mStreamSlotCount = 1; 435 } 436 if (mStreamSlotCount == 1) { 437 free_camera_metadata( *(mStreamSlot.begin()) ); 438 *(mStreamSlot.begin()) = buf2; 439 } else { 440 mStreamSlot.push_front(buf2); 441 mStreamSlotCount = 1; 442 } 443 return signalConsumerLocked(); 444} 445 446status_t Camera2Device::MetadataQueue::setStreamSlot( 447 const List<camera_metadata_t*> &bufs) 448{ 449 ALOGV("%s: E", __FUNCTION__); 450 Mutex::Autolock l(mMutex); 451 status_t res; 452 453 if (mStreamSlotCount > 0) { 454 freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); 455 } 456 mStreamSlotCount = 0; 457 for (List<camera_metadata_t*>::const_iterator r = bufs.begin(); 458 r != bufs.end(); r++) { 459 camera_metadata_t *r2 = clone_camera_metadata(*r); 460 if (!r2) { 461 ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__); 462 return NO_MEMORY; 463 } 464 mStreamSlot.push_back(r2); 465 mStreamSlotCount++; 466 } 467 return signalConsumerLocked(); 468} 469 470status_t Camera2Device::MetadataQueue::dump(int fd, 471 const Vector<String16>& args) { 472 String8 result; 473 status_t notLocked; 474 notLocked = mMutex.tryLock(); 475 if (notLocked) { 476 result.append(" (Unable to lock queue mutex)\n"); 477 } 478 result.appendFormat(" Current frame number: %d\n", mFrameCount); 479 if (mStreamSlotCount == 0) { 480 result.append(" Stream slot: Empty\n"); 481 write(fd, result.string(), result.size()); 482 } else { 483 result.appendFormat(" Stream slot: %d entries\n", 484 mStreamSlot.size()); 485 int i = 0; 486 for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin(); 487 r != mStreamSlot.end(); r++) { 488 result = String8::format(" Stream slot buffer %d:\n", i); 489 write(fd, result.string(), result.size()); 490 dump_camera_metadata(*r, fd, 2); 491 i++; 492 } 493 } 494 if (mEntries.size() == 0) { 495 result = " Main queue is empty\n"; 496 write(fd, result.string(), result.size()); 497 } else { 498 result = String8::format(" Main queue has %d entries:\n", 499 mEntries.size()); 500 int i = 0; 501 for (List<camera_metadata_t*>::iterator r = mEntries.begin(); 502 r != mEntries.end(); r++) { 503 result = String8::format(" Queue entry %d:\n", i); 504 write(fd, result.string(), result.size()); 505 dump_camera_metadata(*r, fd, 2); 506 i++; 507 } 508 } 509 510 if (notLocked == 0) { 511 mMutex.unlock(); 512 } 513 514 return OK; 515} 516 517status_t Camera2Device::MetadataQueue::signalConsumerLocked() { 518 status_t res = OK; 519 notEmpty.signal(); 520 if (mSignalConsumer && mDevice != NULL) { 521 mSignalConsumer = false; 522 523 mMutex.unlock(); 524 ALOGV("%s: Signaling consumer", __FUNCTION__); 525 res = mDevice->ops->notify_request_queue_not_empty(mDevice); 526 mMutex.lock(); 527 } 528 return res; 529} 530 531status_t Camera2Device::MetadataQueue::freeBuffers( 532 List<camera_metadata_t*>::iterator start, 533 List<camera_metadata_t*>::iterator end) 534{ 535 while (start != end) { 536 free_camera_metadata(*start); 537 start = mStreamSlot.erase(start); 538 } 539 return OK; 540} 541 542Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance( 543 const camera2_request_queue_src_ops_t *q) 544{ 545 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q); 546 return const_cast<MetadataQueue*>(cmq); 547} 548 549Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance( 550 const camera2_frame_queue_dst_ops_t *q) 551{ 552 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q); 553 return const_cast<MetadataQueue*>(cmq); 554} 555 556int Camera2Device::MetadataQueue::consumer_buffer_count( 557 const camera2_request_queue_src_ops_t *q) 558{ 559 MetadataQueue *queue = getInstance(q); 560 return queue->getBufferCount(); 561} 562 563int Camera2Device::MetadataQueue::consumer_dequeue( 564 const camera2_request_queue_src_ops_t *q, 565 camera_metadata_t **buffer) 566{ 567 MetadataQueue *queue = getInstance(q); 568 return queue->dequeue(buffer, true); 569} 570 571int Camera2Device::MetadataQueue::consumer_free( 572 const camera2_request_queue_src_ops_t *q, 573 camera_metadata_t *old_buffer) 574{ 575 MetadataQueue *queue = getInstance(q); 576 free_camera_metadata(old_buffer); 577 return OK; 578} 579 580int Camera2Device::MetadataQueue::producer_dequeue( 581 const camera2_frame_queue_dst_ops_t *q, 582 size_t entries, size_t bytes, 583 camera_metadata_t **buffer) 584{ 585 camera_metadata_t *new_buffer = 586 allocate_camera_metadata(entries, bytes); 587 if (new_buffer == NULL) return NO_MEMORY; 588 *buffer = new_buffer; 589 return OK; 590} 591 592int Camera2Device::MetadataQueue::producer_cancel( 593 const camera2_frame_queue_dst_ops_t *q, 594 camera_metadata_t *old_buffer) 595{ 596 free_camera_metadata(old_buffer); 597 return OK; 598} 599 600int Camera2Device::MetadataQueue::producer_enqueue( 601 const camera2_frame_queue_dst_ops_t *q, 602 camera_metadata_t *filled_buffer) 603{ 604 MetadataQueue *queue = getInstance(q); 605 return queue->enqueue(filled_buffer); 606} 607 608/** 609 * Camera2Device::StreamAdapter 610 */ 611 612#ifndef container_of 613#define container_of(ptr, type, member) \ 614 (type *)((char*)(ptr) - offsetof(type, member)) 615#endif 616 617Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d): 618 mState(DISCONNECTED), 619 mDevice(d), 620 mId(-1), 621 mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0), 622 mMaxProducerBuffers(0), mMaxConsumerBuffers(0), 623 mTotalBuffers(0), 624 mFormatRequested(0), 625 mActiveBuffers(0), 626 mFrameCount(0), 627 mLastTimestamp(0) 628{ 629 camera2_stream_ops::dequeue_buffer = dequeue_buffer; 630 camera2_stream_ops::enqueue_buffer = enqueue_buffer; 631 camera2_stream_ops::cancel_buffer = cancel_buffer; 632 camera2_stream_ops::set_crop = set_crop; 633} 634 635Camera2Device::StreamAdapter::~StreamAdapter() { 636 disconnect(); 637} 638 639status_t Camera2Device::StreamAdapter::connectToDevice( 640 sp<ANativeWindow> consumer, 641 uint32_t width, uint32_t height, int format, size_t size) { 642 status_t res; 643 644 if (mState != DISCONNECTED) return INVALID_OPERATION; 645 if (consumer == NULL) { 646 ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__); 647 return BAD_VALUE; 648 } 649 650 mConsumerInterface = consumer; 651 mWidth = width; 652 mHeight = height; 653 mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0; 654 mFormatRequested = format; 655 656 // Allocate device-side stream interface 657 658 uint32_t id; 659 uint32_t formatActual; 660 uint32_t usage; 661 uint32_t maxBuffers = 2; 662 res = mDevice->ops->allocate_stream(mDevice, 663 mWidth, mHeight, mFormatRequested, getStreamOps(), 664 &id, &formatActual, &usage, &maxBuffers); 665 if (res != OK) { 666 ALOGE("%s: Device stream allocation failed: %s (%d)", 667 __FUNCTION__, strerror(-res), res); 668 return res; 669 } 670 671 mId = id; 672 mFormat = formatActual; 673 mUsage = usage; 674 mMaxProducerBuffers = maxBuffers; 675 676 mState = ALLOCATED; 677 678 // Configure consumer-side ANativeWindow interface 679 res = native_window_api_connect(mConsumerInterface.get(), 680 NATIVE_WINDOW_API_CAMERA); 681 if (res != OK) { 682 ALOGE("%s: Unable to connect to native window for stream %d", 683 __FUNCTION__, mId); 684 685 return res; 686 } 687 688 mState = CONNECTED; 689 690 res = native_window_set_usage(mConsumerInterface.get(), mUsage); 691 if (res != OK) { 692 ALOGE("%s: Unable to configure usage %08x for stream %d", 693 __FUNCTION__, mUsage, mId); 694 return res; 695 } 696 697 res = native_window_set_scaling_mode(mConsumerInterface.get(), 698 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 699 if (res != OK) { 700 ALOGE("%s: Unable to configure stream scaling: %s (%d)", 701 __FUNCTION__, strerror(-res), res); 702 return res; 703 } 704 705 res = setTransform(0); 706 if (res != OK) { 707 return res; 708 } 709 710 if (mFormat == HAL_PIXEL_FORMAT_BLOB) { 711 res = native_window_set_buffers_geometry(mConsumerInterface.get(), 712 mSize, 1, mFormat); 713 if (res != OK) { 714 ALOGE("%s: Unable to configure compressed stream buffer geometry" 715 " %d x %d, size %d for stream %d", 716 __FUNCTION__, mWidth, mHeight, mSize, mId); 717 return res; 718 } 719 } else { 720 res = native_window_set_buffers_geometry(mConsumerInterface.get(), 721 mWidth, mHeight, mFormat); 722 if (res != OK) { 723 ALOGE("%s: Unable to configure stream buffer geometry" 724 " %d x %d, format 0x%x for stream %d", 725 __FUNCTION__, mWidth, mHeight, mFormat, mId); 726 return res; 727 } 728 } 729 730 int maxConsumerBuffers; 731 res = mConsumerInterface->query(mConsumerInterface.get(), 732 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers); 733 if (res != OK) { 734 ALOGE("%s: Unable to query consumer undequeued" 735 " buffer count for stream %d", __FUNCTION__, mId); 736 return res; 737 } 738 mMaxConsumerBuffers = maxConsumerBuffers; 739 740 ALOGV("%s: Producer wants %d buffers, consumer wants %d", __FUNCTION__, 741 mMaxProducerBuffers, mMaxConsumerBuffers); 742 743 mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers; 744 mActiveBuffers = 0; 745 mFrameCount = 0; 746 mLastTimestamp = 0; 747 748 res = native_window_set_buffer_count(mConsumerInterface.get(), 749 mTotalBuffers); 750 if (res != OK) { 751 ALOGE("%s: Unable to set buffer count for stream %d", 752 __FUNCTION__, mId); 753 return res; 754 } 755 756 // Register allocated buffers with HAL device 757 buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers]; 758 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers]; 759 uint32_t bufferIdx = 0; 760 for (; bufferIdx < mTotalBuffers; bufferIdx++) { 761 res = mConsumerInterface->dequeueBuffer(mConsumerInterface.get(), 762 &anwBuffers[bufferIdx]); 763 if (res != OK) { 764 ALOGE("%s: Unable to dequeue buffer %d for initial registration for" 765 "stream %d", __FUNCTION__, bufferIdx, mId); 766 goto cleanUpBuffers; 767 } 768 769 res = mConsumerInterface->lockBuffer(mConsumerInterface.get(), 770 anwBuffers[bufferIdx]); 771 if (res != OK) { 772 ALOGE("%s: Unable to lock buffer %d for initial registration for" 773 "stream %d", __FUNCTION__, bufferIdx, mId); 774 bufferIdx++; 775 goto cleanUpBuffers; 776 } 777 778 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle; 779 } 780 781 res = mDevice->ops->register_stream_buffers(mDevice, 782 mId, 783 mTotalBuffers, 784 buffers); 785 if (res != OK) { 786 ALOGE("%s: Unable to register buffers with HAL device for stream %d", 787 __FUNCTION__, mId); 788 } else { 789 mState = ACTIVE; 790 } 791 792cleanUpBuffers: 793 for (uint32_t i = 0; i < bufferIdx; i++) { 794 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(), 795 anwBuffers[i]); 796 if (res != OK) { 797 ALOGE("%s: Unable to cancel buffer %d after registration", 798 __FUNCTION__, i); 799 } 800 } 801 delete[] anwBuffers; 802 delete[] buffers; 803 804 return res; 805} 806 807status_t Camera2Device::StreamAdapter::disconnect() { 808 status_t res; 809 if (mState >= ALLOCATED) { 810 res = mDevice->ops->release_stream(mDevice, mId); 811 if (res != OK) { 812 ALOGE("%s: Unable to release stream %d", 813 __FUNCTION__, mId); 814 return res; 815 } 816 } 817 if (mState >= CONNECTED) { 818 res = native_window_api_disconnect(mConsumerInterface.get(), 819 NATIVE_WINDOW_API_CAMERA); 820 if (res != OK) { 821 ALOGE("%s: Unable to disconnect stream %d from native window", 822 __FUNCTION__, mId); 823 return res; 824 } 825 } 826 mId = -1; 827 mState = DISCONNECTED; 828 return OK; 829} 830 831status_t Camera2Device::StreamAdapter::setTransform(int transform) { 832 status_t res; 833 if (mState < CONNECTED) { 834 ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__); 835 return INVALID_OPERATION; 836 } 837 res = native_window_set_buffers_transform(mConsumerInterface.get(), 838 transform); 839 if (res != OK) { 840 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)", 841 __FUNCTION__, transform, strerror(-res), res); 842 } 843 return res; 844} 845 846status_t Camera2Device::StreamAdapter::dump(int fd, 847 const Vector<String16>& args) { 848 String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n", 849 mId, mWidth, mHeight, mFormat); 850 result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n", 851 mSize, mUsage, mFormatRequested); 852 result.appendFormat(" total buffers: %d, dequeued buffers: %d\n", 853 mTotalBuffers, mActiveBuffers); 854 result.appendFormat(" frame count: %d, last timestamp %lld\n", 855 mFrameCount, mLastTimestamp); 856 write(fd, result.string(), result.size()); 857 return OK; 858} 859 860const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() { 861 return static_cast<camera2_stream_ops *>(this); 862} 863 864ANativeWindow* Camera2Device::StreamAdapter::toANW( 865 const camera2_stream_ops_t *w) { 866 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get(); 867} 868 869int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w, 870 buffer_handle_t** buffer) { 871 int res; 872 StreamAdapter* stream = 873 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w)); 874 if (stream->mState != ACTIVE) { 875 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState); 876 return INVALID_OPERATION; 877 } 878 879 ANativeWindow *a = toANW(w); 880 ANativeWindowBuffer* anb; 881 res = a->dequeueBuffer(a, &anb); 882 if (res != OK) return res; 883 res = a->lockBuffer(a, anb); 884 if (res != OK) return res; 885 886 *buffer = &(anb->handle); 887 stream->mActiveBuffers++; 888 889 ALOGVV("%s: Buffer %p", __FUNCTION__, *buffer); 890 return res; 891} 892 893int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w, 894 int64_t timestamp, 895 buffer_handle_t* buffer) { 896 StreamAdapter *stream = 897 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w)); 898 ALOGVV("%s: Stream %d: Buffer %p captured at %lld ns", 899 __FUNCTION__, stream->mId, buffer, timestamp); 900 int state = stream->mState; 901 if (state != ACTIVE) { 902 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 903 return INVALID_OPERATION; 904 } 905 ANativeWindow *a = toANW(w); 906 status_t err; 907 err = native_window_set_buffers_timestamp(a, timestamp); 908 if (err != OK) { 909 ALOGE("%s: Error setting timestamp on native window: %s (%d)", 910 __FUNCTION__, strerror(-err), err); 911 return err; 912 } 913 err = a->queueBuffer(a, 914 container_of(buffer, ANativeWindowBuffer, handle)); 915 if (err != OK) { 916 ALOGE("%s: Error queueing buffer to native window: %s (%d)", 917 __FUNCTION__, strerror(-err), err); 918 } 919 stream->mActiveBuffers--; 920 stream->mFrameCount++; 921 stream->mLastTimestamp = timestamp; 922 return err; 923} 924 925int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w, 926 buffer_handle_t* buffer) { 927 StreamAdapter *stream = 928 const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w)); 929 if (stream->mState != ACTIVE) { 930 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState); 931 return INVALID_OPERATION; 932 } 933 stream->mActiveBuffers--; 934 ANativeWindow *a = toANW(w); 935 return a->cancelBuffer(a, 936 container_of(buffer, ANativeWindowBuffer, handle)); 937} 938 939int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w, 940 int left, int top, int right, int bottom) { 941 int state = static_cast<const StreamAdapter*>(w)->mState; 942 if (state != ACTIVE) { 943 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 944 return INVALID_OPERATION; 945 } 946 ANativeWindow *a = toANW(w); 947 android_native_rect_t crop = { left, top, right, bottom }; 948 return native_window_set_crop(a, &crop); 949} 950 951 952}; // namespace android 953