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