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     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