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 free_camera_metadata(old_buffer); 214 return OK; 215 } 216 217 int MetadataQueue::producer_dequeue(const camera2_frame_queue_dst_ops_t *q, 218 size_t entries, size_t bytes, 219 camera_metadata_t **buffer) { 220 camera_metadata_t *new_buffer = 221 allocate_camera_metadata(entries, bytes); 222 if (new_buffer == NULL) return NO_MEMORY; 223 *buffer = new_buffer; 224 return OK; 225 } 226 227 int MetadataQueue::producer_cancel(const camera2_frame_queue_dst_ops_t *q, 228 camera_metadata_t *old_buffer) { 229 free_camera_metadata(old_buffer); 230 return OK; 231 } 232 233 int MetadataQueue::producer_enqueue(const camera2_frame_queue_dst_ops_t *q, 234 camera_metadata_t *filled_buffer) { 235 MetadataQueue *queue = getInstance(q); 236 return queue->enqueue(filled_buffer); 237 } 238 239 /** 240 * NotifierListener 241 */ 242 243 NotifierListener::NotifierListener() { 244 } 245 246 status_t NotifierListener::getNotificationsFrom(camera2_device *dev) { 247 if (!dev) return BAD_VALUE; 248 status_t err; 249 err = dev->ops->set_notify_callback(dev, 250 notify_callback_dispatch, 251 (void*)this); 252 return err; 253 } 254 255 status_t NotifierListener::getNextNotification(int32_t *msg_type, 256 int32_t *ext1, 257 int32_t *ext2, 258 int32_t *ext3) { 259 Mutex::Autolock l(mMutex); 260 if (mNotifications.size() == 0) return BAD_VALUE; 261 return getNextNotificationLocked(msg_type, ext1, ext2, ext3); 262 } 263 264 status_t NotifierListener::waitForNotification(int32_t *msg_type, 265 int32_t *ext1, 266 int32_t *ext2, 267 int32_t *ext3) { 268 Mutex::Autolock l(mMutex); 269 while (mNotifications.size() == 0) { 270 mNewNotification.wait(mMutex); 271 } 272 return getNextNotificationLocked(msg_type, ext1, ext2, ext3); 273 } 274 275 int NotifierListener::numNotifications() { 276 Mutex::Autolock l(mMutex); 277 return mNotifications.size(); 278 } 279 280 status_t NotifierListener::getNextNotificationLocked(int32_t *msg_type, 281 int32_t *ext1, 282 int32_t *ext2, 283 int32_t *ext3) { 284 *msg_type = mNotifications.begin()->msg_type; 285 *ext1 = mNotifications.begin()->ext1; 286 *ext2 = mNotifications.begin()->ext2; 287 *ext3 = mNotifications.begin()->ext3; 288 mNotifications.erase(mNotifications.begin()); 289 return OK; 290 } 291 292 void NotifierListener::onNotify(int32_t msg_type, 293 int32_t ext1, 294 int32_t ext2, 295 int32_t ext3) { 296 Mutex::Autolock l(mMutex); 297 mNotifications.push_back(Notification(msg_type, ext1, ext2, ext3)); 298 mNewNotification.signal(); 299 } 300 301 void NotifierListener::notify_callback_dispatch(int32_t msg_type, 302 int32_t ext1, 303 int32_t ext2, 304 int32_t ext3, 305 void *user) { 306 NotifierListener *me = reinterpret_cast<NotifierListener*>(user); 307 me->onNotify(msg_type, ext1, ext2, ext3); 308 } 309 310 /** 311 * StreamAdapter 312 */ 313 314 #ifndef container_of 315 #define container_of(ptr, type, member) \ 316 (type *)((char*)(ptr) - offsetof(type, member)) 317 #endif 318 319 StreamAdapter::StreamAdapter(sp<IGraphicBufferProducer> consumer): 320 mState(UNINITIALIZED), mDevice(NULL), 321 mId(-1), 322 mWidth(0), mHeight(0), mFormat(0) 323 { 324 mConsumerInterface = new Surface(consumer); 325 camera2_stream_ops::dequeue_buffer = dequeue_buffer; 326 camera2_stream_ops::enqueue_buffer = enqueue_buffer; 327 camera2_stream_ops::cancel_buffer = cancel_buffer; 328 camera2_stream_ops::set_crop = set_crop; 329 } 330 331 StreamAdapter::~StreamAdapter() { 332 disconnect(); 333 } 334 335 status_t StreamAdapter::connectToDevice(camera2_device_t *d, 336 uint32_t width, uint32_t height, int format) { 337 if (mState != UNINITIALIZED) return INVALID_OPERATION; 338 if (d == NULL) { 339 ALOGE("%s: Null device passed to stream adapter", __FUNCTION__); 340 return BAD_VALUE; 341 } 342 343 status_t res; 344 345 mWidth = width; 346 mHeight = height; 347 mFormat = format; 348 349 // Allocate device-side stream interface 350 351 uint32_t id; 352 uint32_t formatActual; // ignored 353 uint32_t usage; 354 uint32_t maxBuffers = 2; 355 res = d->ops->allocate_stream(d, 356 mWidth, mHeight, mFormat, getStreamOps(), 357 &id, &formatActual, &usage, &maxBuffers); 358 if (res != OK) { 359 ALOGE("%s: Device stream allocation failed: %s (%d)", 360 __FUNCTION__, strerror(-res), res); 361 mState = UNINITIALIZED; 362 return res; 363 } 364 mDevice = d; 365 366 mId = id; 367 mUsage = usage; 368 mMaxProducerBuffers = maxBuffers; 369 370 // Configure consumer-side ANativeWindow interface 371 372 res = native_window_api_connect(mConsumerInterface.get(), 373 NATIVE_WINDOW_API_CAMERA); 374 if (res != OK) { 375 ALOGE("%s: Unable to connect to native window for stream %d", 376 __FUNCTION__, mId); 377 mState = ALLOCATED; 378 return res; 379 } 380 381 res = native_window_set_usage(mConsumerInterface.get(), mUsage); 382 if (res != OK) { 383 ALOGE("%s: Unable to configure usage %08x for stream %d", 384 __FUNCTION__, mUsage, mId); 385 mState = CONNECTED; 386 return res; 387 } 388 389 res = native_window_set_buffers_geometry(mConsumerInterface.get(), 390 mWidth, mHeight, mFormat); 391 if (res != OK) { 392 ALOGE("%s: Unable to configure buffer geometry" 393 " %d x %d, format 0x%x for stream %d", 394 __FUNCTION__, mWidth, mHeight, mFormat, mId); 395 mState = CONNECTED; 396 return res; 397 } 398 399 int maxConsumerBuffers; 400 res = mConsumerInterface->query(mConsumerInterface.get(), 401 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers); 402 if (res != OK) { 403 ALOGE("%s: Unable to query consumer undequeued" 404 " buffer count for stream %d", __FUNCTION__, mId); 405 mState = CONNECTED; 406 return res; 407 } 408 mMaxConsumerBuffers = maxConsumerBuffers; 409 410 ALOGV("%s: Producer wants %d buffers, consumer wants %d", __FUNCTION__, 411 mMaxProducerBuffers, mMaxConsumerBuffers); 412 413 int totalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers; 414 415 res = native_window_set_buffer_count(mConsumerInterface.get(), 416 totalBuffers); 417 if (res != OK) { 418 ALOGE("%s: Unable to set buffer count for stream %d", 419 __FUNCTION__, mId); 420 mState = CONNECTED; 421 return res; 422 } 423 424 // Register allocated buffers with HAL device 425 buffer_handle_t *buffers = new buffer_handle_t[totalBuffers]; 426 ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[totalBuffers]; 427 int bufferIdx = 0; 428 for (; bufferIdx < totalBuffers; bufferIdx++) { 429 res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(), 430 &anwBuffers[bufferIdx]); 431 if (res != OK) { 432 ALOGE("%s: Unable to dequeue buffer %d for initial registration for" 433 "stream %d", __FUNCTION__, bufferIdx, mId); 434 mState = CONNECTED; 435 goto cleanUpBuffers; 436 } 437 buffers[bufferIdx] = anwBuffers[bufferIdx]->handle; 438 } 439 440 res = mDevice->ops->register_stream_buffers(mDevice, 441 mId, 442 totalBuffers, 443 buffers); 444 if (res != OK) { 445 ALOGE("%s: Unable to register buffers with HAL device for stream %d", 446 __FUNCTION__, mId); 447 mState = CONNECTED; 448 } else { 449 mState = ACTIVE; 450 } 451 452 cleanUpBuffers: 453 for (int i = 0; i < bufferIdx; i++) { 454 res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(), 455 anwBuffers[i], -1); 456 } 457 delete anwBuffers; 458 delete buffers; 459 460 return res; 461 } 462 463 status_t StreamAdapter::disconnect() { 464 status_t res; 465 if (mState >= ALLOCATED) { 466 res = mDevice->ops->release_stream(mDevice, mId); 467 if (res != OK) { 468 ALOGE("%s: Unable to release stream %d", 469 __FUNCTION__, mId); 470 return res; 471 } 472 } 473 if (mState >= CONNECTED) { 474 res = native_window_api_disconnect(mConsumerInterface.get(), 475 NATIVE_WINDOW_API_CAMERA); 476 if (res != OK) { 477 ALOGE("%s: Unable to disconnect stream %d from native window", 478 __FUNCTION__, mId); 479 return res; 480 } 481 } 482 mId = -1; 483 mState = DISCONNECTED; 484 return OK; 485 } 486 487 int StreamAdapter::getId() { 488 return mId; 489 } 490 491 const camera2_stream_ops *StreamAdapter::getStreamOps() { 492 return static_cast<camera2_stream_ops *>(this); 493 } 494 495 ANativeWindow* StreamAdapter::toANW(const camera2_stream_ops_t *w) { 496 return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get(); 497 } 498 499 int StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w, 500 buffer_handle_t** buffer) { 501 int res; 502 int state = static_cast<const StreamAdapter*>(w)->mState; 503 if (state != ACTIVE) { 504 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 505 return INVALID_OPERATION; 506 } 507 508 ANativeWindow *a = toANW(w); 509 ANativeWindowBuffer* anb; 510 res = native_window_dequeue_buffer_and_wait(a, &anb); 511 if (res != OK) return res; 512 513 *buffer = &(anb->handle); 514 515 return res; 516 } 517 518 int StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w, 519 int64_t timestamp, 520 buffer_handle_t* buffer) { 521 int state = static_cast<const StreamAdapter*>(w)->mState; 522 if (state != ACTIVE) { 523 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 524 return INVALID_OPERATION; 525 } 526 ANativeWindow *a = toANW(w); 527 status_t err; 528 err = native_window_set_buffers_timestamp(a, timestamp); 529 if (err != OK) return err; 530 return a->queueBuffer(a, 531 container_of(buffer, ANativeWindowBuffer, handle), -1); 532 } 533 534 int StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w, 535 buffer_handle_t* buffer) { 536 int state = static_cast<const StreamAdapter*>(w)->mState; 537 if (state != ACTIVE) { 538 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 539 return INVALID_OPERATION; 540 } 541 ANativeWindow *a = toANW(w); 542 return a->cancelBuffer(a, 543 container_of(buffer, ANativeWindowBuffer, handle), -1); 544 } 545 546 int StreamAdapter::set_crop(const camera2_stream_ops_t* w, 547 int left, int top, int right, int bottom) { 548 int state = static_cast<const StreamAdapter*>(w)->mState; 549 if (state != ACTIVE) { 550 ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state); 551 return INVALID_OPERATION; 552 } 553 ANativeWindow *a = toANW(w); 554 android_native_rect_t crop = { left, top, right, bottom }; 555 return native_window_set_crop(a, &crop); 556 } 557 558 /** 559 * FrameWaiter 560 */ 561 562 FrameWaiter::FrameWaiter(): 563 mPendingFrames(0) { 564 } 565 566 status_t FrameWaiter::waitForFrame(nsecs_t timeout) { 567 status_t res; 568 Mutex::Autolock lock(mMutex); 569 while (mPendingFrames == 0) { 570 res = mCondition.waitRelative(mMutex, timeout); 571 if (res != OK) return res; 572 } 573 mPendingFrames--; 574 return OK; 575 } 576 577 void FrameWaiter::onFrameAvailable() { 578 Mutex::Autolock lock(mMutex); 579 mPendingFrames++; 580 mCondition.signal(); 581 } 582 583 int HWModuleHelpers::closeModule(hw_module_t* module) { 584 int status; 585 586 if (!module) { 587 return -EINVAL; 588 } 589 590 status = dlclose(module->dso); 591 if (status != 0) { 592 char const *err_str = dlerror(); 593 ALOGE("%s dlclose failed, error: %s", __func__, err_str ?: "unknown"); 594 } 595 596 return status; 597 } 598 599 } // namespace tests 600 } // namespace camera2 601 } // namespace android 602