Home | History | Annotate | Download | only in camera2
      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