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 26 namespace android { 27 namespace camera2 { 28 namespace tests { 29 30 /** 31 * MetadataQueue 32 */ 33 34 MetadataQueue::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 50 MetadataQueue::~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) 56 const camera2_request_queue_src_ops_t* MetadataQueue::getToConsumerInterface() { 57 return static_cast<camera2_request_queue_src_ops_t*>(this); 58 } 59 60 void MetadataQueue::setFromConsumerInterface(camera2_device_t *d) { 61 mDevice = d; 62 } 63 64 const camera2_frame_queue_dst_ops_t* MetadataQueue::getToProducerInterface() { 65 return static_cast<camera2_frame_queue_dst_ops_t*>(this); 66 } 67 68 // Real interfaces 69 status_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 87 int MetadataQueue::getBufferCount() { 88 Mutex::Autolock l(mMutex); 89 if (mStreamSlotCount > 0) { 90 return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS; 91 } 92 return mCount; 93 } 94 95 status_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 137 status_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 147 status_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 168 status_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 178 status_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 187 MetadataQueue* 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 193 MetadataQueue* 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 199 int MetadataQueue::consumer_buffer_count( 200 const camera2_request_queue_src_ops_t *q) { 201 MetadataQueue *queue = getInstance(q); 202 return queue->getBufferCount(); 203 } 204 205 int 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 211 int 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 218 int 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 228 int 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 234 int 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 244 NotifierListener::NotifierListener() { 245 } 246 247 status_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 256 status_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 265 status_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 276 int NotifierListener::numNotifications() { 277 Mutex::Autolock l(mMutex); 278 return mNotifications.size(); 279 } 280 281 status_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 293 void 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 302 void 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 320 StreamAdapter::StreamAdapter(sp<IGraphicBufferProducer> consumer): 321 mState(UNINITIALIZED), mDevice(NULL), 322 mId(-1), 323 mWidth(0), mHeight(0), mFormat(0) 324 { 325 mConsumerInterface = new Surface(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 332 StreamAdapter::~StreamAdapter() { 333 disconnect(); 334 } 335 336 status_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 453 cleanUpBuffers: 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 464 status_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 488 int StreamAdapter::getId() { 489 return mId; 490 } 491 492 const camera2_stream_ops *StreamAdapter::getStreamOps() { 493 return static_cast<camera2_stream_ops *>(this); 494 } 495 496 ANativeWindow* StreamAdapter::toANW(const camera2_stream_ops_t *w) { 497 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get(); 498 } 499 500 int 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 519 int 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 535 int 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 547 int 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 563 FrameWaiter::FrameWaiter(): 564 mPendingFrames(0) { 565 } 566 567 status_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 578 void FrameWaiter::onFrameAvailable() { 579 Mutex::Autolock lock(mMutex); 580 mPendingFrames++; 581 mCondition.signal(); 582 } 583 584 int 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