camera2_utils.cpp revision e302ee3dd3abacebeb32263654186ab433efc14c
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// Utility classes for camera2 HAL testing 18 19#define LOG_TAG "Camera2_test_utils" 20#define LOG_NDEBUG 0 21 22#include "utils/Log.h" 23#include "camera2_utils.h" 24#include <dlfcn.h> 25 26namespace android { 27namespace camera2 { 28namespace tests { 29 30/** 31 * MetadataQueue 32 */ 33 34MetadataQueue::MetadataQueue(): 35 mDevice(NULL), 36 mFrameCount(0), 37 mCount(0), 38 mStreamSlotCount(0), 39 mSignalConsumer(true) 40{ 41 camera2_request_queue_src_ops::dequeue_request = consumer_dequeue; 42 camera2_request_queue_src_ops::request_count = consumer_buffer_count; 43 camera2_request_queue_src_ops::free_request = consumer_free; 44 45 camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue; 46 camera2_frame_queue_dst_ops::cancel_frame = producer_cancel; 47 camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue; 48} 49 50MetadataQueue::~MetadataQueue() { 51 freeBuffers(mEntries.begin(), mEntries.end()); 52 freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); 53} 54 55// Interface to camera2 HAL as consumer (input requests/reprocessing) 56const camera2_request_queue_src_ops_t* MetadataQueue::getToConsumerInterface() { 57 return static_cast<camera2_request_queue_src_ops_t*>(this); 58} 59 60void MetadataQueue::setFromConsumerInterface(camera2_device_t *d) { 61 mDevice = d; 62} 63 64const camera2_frame_queue_dst_ops_t* MetadataQueue::getToProducerInterface() { 65 return static_cast<camera2_frame_queue_dst_ops_t*>(this); 66} 67 68// Real interfaces 69status_t MetadataQueue::enqueue(camera_metadata_t *buf) { 70 Mutex::Autolock l(mMutex); 71 72 mCount++; 73 mEntries.push_back(buf); 74 notEmpty.signal(); 75 76 if (mSignalConsumer && mDevice != NULL) { 77 mSignalConsumer = false; 78 79 mMutex.unlock(); 80 ALOGV("%s: Signaling consumer", __FUNCTION__); 81 mDevice->ops->notify_request_queue_not_empty(mDevice); 82 mMutex.lock(); 83 } 84 return OK; 85} 86 87int MetadataQueue::getBufferCount() { 88 Mutex::Autolock l(mMutex); 89 if (mStreamSlotCount > 0) { 90 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS; 91 } 92 return mCount; 93} 94 95status_t MetadataQueue::dequeue(camera_metadata_t **buf, bool incrementCount) { 96 Mutex::Autolock l(mMutex); 97 98 if (mCount == 0) { 99 if (mStreamSlotCount == 0) { 100 ALOGV("%s: Empty", __FUNCTION__); 101 *buf = NULL; 102 mSignalConsumer = true; 103 return OK; 104 } 105 ALOGV("%s: Streaming %d frames to queue", __FUNCTION__, 106 mStreamSlotCount); 107 108 for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin(); 109 slotEntry != mStreamSlot.end(); 110 slotEntry++ ) { 111 size_t entries = get_camera_metadata_entry_count(*slotEntry); 112 size_t dataBytes = get_camera_metadata_data_count(*slotEntry); 113 114 camera_metadata_t *copy = allocate_camera_metadata(entries, dataBytes); 115 append_camera_metadata(copy, *slotEntry); 116 mEntries.push_back(copy); 117 } 118 mCount = mStreamSlotCount; 119 } 120 ALOGV("MetadataQueue: deque (%d buffers)", mCount); 121 camera_metadata_t *b = *(mEntries.begin()); 122 mEntries.erase(mEntries.begin()); 123 124 if (incrementCount) { 125 add_camera_metadata_entry(b, 126 ANDROID_REQUEST_FRAME_COUNT, 127 (void**)&mFrameCount, 1); 128 mFrameCount++; 129 } 130 131 *buf = b; 132 mCount--; 133 134 return OK; 135} 136 137status_t MetadataQueue::waitForBuffer(nsecs_t timeout) { 138 Mutex::Autolock l(mMutex); 139 status_t res; 140 while (mCount == 0) { 141 res = notEmpty.waitRelative(mMutex,timeout); 142 if (res != OK) return res; 143 } 144 return OK; 145} 146 147status_t MetadataQueue::setStreamSlot(camera_metadata_t *buf) { 148 if (buf == NULL) { 149 freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); 150 mStreamSlotCount = 0; 151 return OK; 152 } 153 if (mStreamSlotCount > 1) { 154 List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin(); 155 freeBuffers(++mStreamSlot.begin(), mStreamSlot.end()); 156 mStreamSlotCount = 1; 157 } 158 if (mStreamSlotCount == 1) { 159 free_camera_metadata( *(mStreamSlot.begin()) ); 160 *(mStreamSlot.begin()) = buf; 161 } else { 162 mStreamSlot.push_front(buf); 163 mStreamSlotCount = 1; 164 } 165 return OK; 166} 167 168status_t MetadataQueue::setStreamSlot(const List<camera_metadata_t*> &bufs) { 169 if (mStreamSlotCount > 0) { 170 freeBuffers(mStreamSlot.begin(), mStreamSlot.end()); 171 } 172 mStreamSlot = bufs; 173 mStreamSlotCount = mStreamSlot.size(); 174 175 return OK; 176} 177 178status_t MetadataQueue::freeBuffers(List<camera_metadata_t*>::iterator start, 179 List<camera_metadata_t*>::iterator end) { 180 while (start != end) { 181 free_camera_metadata(*start); 182 start = mStreamSlot.erase(start); 183 } 184 return OK; 185} 186 187MetadataQueue* MetadataQueue::getInstance( 188 const camera2_request_queue_src_ops_t *q) { 189 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q); 190 return const_cast<MetadataQueue*>(cmq); 191} 192 193MetadataQueue* MetadataQueue::getInstance( 194 const camera2_frame_queue_dst_ops_t *q) { 195 const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q); 196 return const_cast<MetadataQueue*>(cmq); 197} 198 199int MetadataQueue::consumer_buffer_count( 200 const camera2_request_queue_src_ops_t *q) { 201 MetadataQueue *queue = getInstance(q); 202 return queue->getBufferCount(); 203} 204 205int MetadataQueue::consumer_dequeue(const camera2_request_queue_src_ops_t *q, 206 camera_metadata_t **buffer) { 207 MetadataQueue *queue = getInstance(q); 208 return queue->dequeue(buffer, true); 209} 210 211int MetadataQueue::consumer_free(const camera2_request_queue_src_ops_t *q, 212 camera_metadata_t *old_buffer) { 213 MetadataQueue *queue = getInstance(q); 214 free_camera_metadata(old_buffer); 215 return OK; 216} 217 218int MetadataQueue::producer_dequeue(const camera2_frame_queue_dst_ops_t *q, 219 size_t entries, size_t bytes, 220 camera_metadata_t **buffer) { 221 camera_metadata_t *new_buffer = 222 allocate_camera_metadata(entries, bytes); 223 if (new_buffer == NULL) return NO_MEMORY; 224 *buffer = new_buffer; 225 return OK; 226} 227 228int MetadataQueue::producer_cancel(const camera2_frame_queue_dst_ops_t *q, 229 camera_metadata_t *old_buffer) { 230 free_camera_metadata(old_buffer); 231 return OK; 232} 233 234int MetadataQueue::producer_enqueue(const camera2_frame_queue_dst_ops_t *q, 235 camera_metadata_t *filled_buffer) { 236 MetadataQueue *queue = getInstance(q); 237 return queue->enqueue(filled_buffer); 238} 239 240/** 241 * NotifierListener 242 */ 243 244NotifierListener::NotifierListener() { 245} 246 247status_t NotifierListener::getNotificationsFrom(camera2_device *dev) { 248 if (!dev) return BAD_VALUE; 249 status_t err; 250 err = dev->ops->set_notify_callback(dev, 251 notify_callback_dispatch, 252 (void*)this); 253 return err; 254} 255 256status_t NotifierListener::getNextNotification(int32_t *msg_type, 257 int32_t *ext1, 258 int32_t *ext2, 259 int32_t *ext3) { 260 Mutex::Autolock l(mMutex); 261 if (mNotifications.size() == 0) return BAD_VALUE; 262 return getNextNotificationLocked(msg_type, ext1, ext2, ext3); 263} 264 265status_t NotifierListener::waitForNotification(int32_t *msg_type, 266 int32_t *ext1, 267 int32_t *ext2, 268 int32_t *ext3) { 269 Mutex::Autolock l(mMutex); 270 while (mNotifications.size() == 0) { 271 mNewNotification.wait(mMutex); 272 } 273 return getNextNotificationLocked(msg_type, ext1, ext2, ext3); 274} 275 276int NotifierListener::numNotifications() { 277 Mutex::Autolock l(mMutex); 278 return mNotifications.size(); 279} 280 281status_t NotifierListener::getNextNotificationLocked(int32_t *msg_type, 282 int32_t *ext1, 283 int32_t *ext2, 284 int32_t *ext3) { 285 *msg_type = mNotifications.begin()->msg_type; 286 *ext1 = mNotifications.begin()->ext1; 287 *ext2 = mNotifications.begin()->ext2; 288 *ext3 = mNotifications.begin()->ext3; 289 mNotifications.erase(mNotifications.begin()); 290 return OK; 291} 292 293void NotifierListener::onNotify(int32_t msg_type, 294 int32_t ext1, 295 int32_t ext2, 296 int32_t ext3) { 297 Mutex::Autolock l(mMutex); 298 mNotifications.push_back(Notification(msg_type, ext1, ext2, ext3)); 299 mNewNotification.signal(); 300} 301 302void NotifierListener::notify_callback_dispatch(int32_t msg_type, 303 int32_t ext1, 304 int32_t ext2, 305 int32_t ext3, 306 void *user) { 307 NotifierListener *me = reinterpret_cast<NotifierListener*>(user); 308 me->onNotify(msg_type, ext1, ext2, ext3); 309} 310 311/** 312 * StreamAdapter 313 */ 314 315#ifndef container_of 316#define container_of(ptr, type, member) \ 317 (type *)((char*)(ptr) - offsetof(type, member)) 318#endif 319 320StreamAdapter::StreamAdapter(sp<ISurfaceTexture> consumer): 321 mState(UNINITIALIZED), mDevice(NULL), 322 mId(-1), 323 mWidth(0), mHeight(0), mFormat(0) 324{ 325 mConsumerInterface = new SurfaceTextureClient(consumer); 326 camera2_stream_ops::dequeue_buffer = dequeue_buffer; 327 camera2_stream_ops::enqueue_buffer = enqueue_buffer; 328 camera2_stream_ops::cancel_buffer = cancel_buffer; 329 camera2_stream_ops::set_crop = set_crop; 330} 331 332StreamAdapter::~StreamAdapter() { 333 disconnect(); 334} 335 336status_t StreamAdapter::connectToDevice(camera2_device_t *d, 337 uint32_t width, uint32_t height, int format) { 338 if (mState != UNINITIALIZED) return INVALID_OPERATION; 339 if (d == NULL) { 340 ALOGE("%s: Null device passed to stream adapter", __FUNCTION__); 341 return BAD_VALUE; 342 } 343 344 status_t res; 345 346 mWidth = width; 347 mHeight = height; 348 mFormat = format; 349 350 // Allocate device-side stream interface 351 352 uint32_t id; 353 uint32_t formatActual; // ignored 354 uint32_t usage; 355 uint32_t maxBuffers = 2; 356 res = d->ops->allocate_stream(d, 357 mWidth, mHeight, mFormat, getStreamOps(), 358 &id, &formatActual, &usage, &maxBuffers); 359 if (res != OK) { 360 ALOGE("%s: Device stream allocation failed: %s (%d)", 361 __FUNCTION__, strerror(-res), res); 362 mState = UNINITIALIZED; 363 return res; 364 } 365 mDevice = d; 366 367 mId = id; 368 mUsage = usage; 369 mMaxProducerBuffers = maxBuffers; 370 371 // Configure consumer-side ANativeWindow interface 372 373 res = native_window_api_connect(mConsumerInterface.get(), 374 NATIVE_WINDOW_API_CAMERA); 375 if (res != OK) { 376 ALOGE("%s: Unable to connect to native window for stream %d", 377 __FUNCTION__, mId); 378 mState = ALLOCATED; 379 return res; 380 } 381 382 res = native_window_set_usage(mConsumerInterface.get(), mUsage); 383 if (res != OK) { 384 ALOGE("%s: Unable to configure usage %08x for stream %d", 385 __FUNCTION__, mUsage, mId); 386 mState = CONNECTED; 387 return res; 388 } 389 390 res = native_window_set_buffers_geometry(mConsumerInterface.get(), 391 mWidth, mHeight, mFormat); 392 if (res != OK) { 393 ALOGE("%s: Unable to configure buffer geometry" 394 " %d x %d, format 0x%x for stream %d", 395 __FUNCTION__, mWidth, mHeight, mFormat, mId); 396 mState = CONNECTED; 397 return res; 398 } 399 400 int maxConsumerBuffers; 401 res = mConsumerInterface->query(mConsumerInterface.get(), 402 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers); 403 if (res != OK) { 404 ALOGE("%s: Unable to query consumer undequeued" 405 " buffer count for stream %d", __FUNCTION__, mId); 406 mState = CONNECTED; 407 return res; 408 } 409 mMaxConsumerBuffers = maxConsumerBuffers; 410 411 ALOGV("%s: Producer wants %d buffers, consumer wants %d", __FUNCTION__, 412 mMaxProducerBuffers, mMaxConsumerBuffers); 413 414 int totalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers; 415 416 res = native_window_set_buffer_count(mConsumerInterface.get(), 417 totalBuffers); 418 if (res != OK) { 419 ALOGE("%s: Unable to set buffer count for stream %d", 420 __FUNCTION__, mId); 421 mState = CONNECTED; 422 return res; 423 } 424 425 // Register allocated buffers with HAL device 426 buffer_handle_t *buffers = new buffer_handle_t[totalBuffers]; 427 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[totalBuffers]; 428 int bufferIdx = 0; 429 for (; bufferIdx < totalBuffers; bufferIdx++) { 430 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(), 431 &anwBuffers[bufferIdx]); 432 if (res != OK) { 433 ALOGE("%s: Unable to dequeue buffer %d for initial registration for" 434 "stream %d", __FUNCTION__, bufferIdx, mId); 435 mState = CONNECTED; 436 goto cleanUpBuffers; 437 } 438 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle; 439 } 440 441 res = mDevice->ops->register_stream_buffers(mDevice, 442 mId, 443 totalBuffers, 444 buffers); 445 if (res != OK) { 446 ALOGE("%s: Unable to register buffers with HAL device for stream %d", 447 __FUNCTION__, mId); 448 mState = CONNECTED; 449 } else { 450 mState = ACTIVE; 451 } 452 453cleanUpBuffers: 454 for (int i = 0; i < bufferIdx; i++) { 455 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(), 456 anwBuffers[i], -1); 457 } 458 delete anwBuffers; 459 delete buffers; 460 461 return res; 462} 463 464status_t StreamAdapter::disconnect() { 465 status_t res; 466 if (mState >= ALLOCATED) { 467 res = mDevice->ops->release_stream(mDevice, mId); 468 if (res != OK) { 469 ALOGE("%s: Unable to release stream %d", 470 __FUNCTION__, mId); 471 return res; 472 } 473 } 474 if (mState >= CONNECTED) { 475 res = native_window_api_disconnect(mConsumerInterface.get(), 476 NATIVE_WINDOW_API_CAMERA); 477 if (res != OK) { 478 ALOGE("%s: Unable to disconnect stream %d from native window", 479 __FUNCTION__, mId); 480 return res; 481 } 482 } 483 mId = -1; 484 mState = DISCONNECTED; 485 return OK; 486} 487 488int StreamAdapter::getId() { 489 return mId; 490} 491 492const camera2_stream_ops *StreamAdapter::getStreamOps() { 493 return static_cast<camera2_stream_ops *>(this); 494} 495 496ANativeWindow* StreamAdapter::toANW(const camera2_stream_ops_t *w) { 497 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get(); 498} 499 500int StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w, 501 buffer_handle_t** buffer) { 502 int res; 503 int state = static_cast<const StreamAdapter*>(w)->mState; 504 if (state != ACTIVE) { 505 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 506 return INVALID_OPERATION; 507 } 508 509 ANativeWindow *a = toANW(w); 510 ANativeWindowBuffer* anb; 511 res = native_window_dequeue_buffer_and_wait(a, &anb); 512 if (res != OK) return res; 513 514 *buffer = &(anb->handle); 515 516 return res; 517} 518 519int StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w, 520 int64_t timestamp, 521 buffer_handle_t* buffer) { 522 int state = static_cast<const StreamAdapter*>(w)->mState; 523 if (state != ACTIVE) { 524 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 525 return INVALID_OPERATION; 526 } 527 ANativeWindow *a = toANW(w); 528 status_t err; 529 err = native_window_set_buffers_timestamp(a, timestamp); 530 if (err != OK) return err; 531 return a->queueBuffer(a, 532 container_of(buffer, ANativeWindowBuffer, handle), -1); 533} 534 535int StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w, 536 buffer_handle_t* buffer) { 537 int state = static_cast<const StreamAdapter*>(w)->mState; 538 if (state != ACTIVE) { 539 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 540 return INVALID_OPERATION; 541 } 542 ANativeWindow *a = toANW(w); 543 return a->cancelBuffer(a, 544 container_of(buffer, ANativeWindowBuffer, handle), -1); 545} 546 547int StreamAdapter::set_crop(const camera2_stream_ops_t* w, 548 int left, int top, int right, int bottom) { 549 int state = static_cast<const StreamAdapter*>(w)->mState; 550 if (state != ACTIVE) { 551 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 552 return INVALID_OPERATION; 553 } 554 ANativeWindow *a = toANW(w); 555 android_native_rect_t crop = { left, top, right, bottom }; 556 return native_window_set_crop(a, &crop); 557} 558 559/** 560 * FrameWaiter 561 */ 562 563FrameWaiter::FrameWaiter(): 564 mPendingFrames(0) { 565} 566 567status_t FrameWaiter::waitForFrame(nsecs_t timeout) { 568 status_t res; 569 Mutex::Autolock lock(mMutex); 570 while (mPendingFrames == 0) { 571 res = mCondition.waitRelative(mMutex, timeout); 572 if (res != OK) return res; 573 } 574 mPendingFrames--; 575 return OK; 576} 577 578void FrameWaiter::onFrameAvailable() { 579 Mutex::Autolock lock(mMutex); 580 mPendingFrames++; 581 mCondition.signal(); 582} 583 584int HWModuleHelpers::closeModule(hw_module_t* module) { 585 int status; 586 587 if (!module) { 588 return -EINVAL; 589 } 590 591 status = dlclose(module->dso); 592 if (status != 0) { 593 char const *err_str = dlerror(); 594 ALOGE("%s dlclose failed, error: %s", __func__, err_str ?: "unknown"); 595 } 596 597 return status; 598} 599 600} // namespace tests 601} // namespace camera2 602} // namespace android 603