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