Camera2Device.cpp revision 6db981c45a964f0d9df4c3451f064dff7954d78e
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#define LOG_TAG "Camera2Device"
18//#define LOG_NDEBUG 0
19
20#include <utils/Log.h>
21#include "Camera2Device.h"
22
23namespace android {
24
25Camera2Device::Camera2Device(int id):
26        mId(id),
27        mDevice(NULL)
28{
29    ALOGV("%s: E", __FUNCTION__);
30}
31
32Camera2Device::~Camera2Device()
33{
34    ALOGV("%s: E", __FUNCTION__);
35    if (mDevice) {
36        status_t res;
37        res = mDevice->common.close(&mDevice->common);
38        if (res != OK) {
39            ALOGE("%s: Could not close camera %d: %s (%d)",
40                    __FUNCTION__,
41                    mId, strerror(-res), res);
42        }
43        mDevice = NULL;
44    }
45}
46
47status_t Camera2Device::initialize(camera_module_t *module)
48{
49    ALOGV("%s: E", __FUNCTION__);
50
51    status_t res;
52    char name[10];
53    snprintf(name, sizeof(name), "%d", mId);
54
55    res = module->common.methods->open(&module->common, name,
56            reinterpret_cast<hw_device_t**>(&mDevice));
57
58    if (res != OK) {
59        ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
60                mId, strerror(-res), res);
61        return res;
62    }
63
64    if (mDevice->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
65        ALOGE("%s: Could not open camera %d: "
66                "Camera device is not version %x, reports %x instead",
67                __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
68                mDevice->common.version);
69        return BAD_VALUE;
70    }
71
72    camera_info info;
73    res = module->get_camera_info(mId, &info);
74    if (res != OK ) return res;
75
76    if (info.device_version != mDevice->common.version) {
77        ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
78                " and device version (%x).", __FUNCTION__,
79                mDevice->common.version, info.device_version);
80        return BAD_VALUE;
81    }
82
83    mDeviceInfo = info.static_camera_characteristics;
84
85    res = mRequestQueue.setConsumerDevice(mDevice);
86    if (res != OK) {
87        ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
88                __FUNCTION__, mId, strerror(-res), res);
89        return res;
90    }
91    res = mFrameQueue.setProducerDevice(mDevice);
92    if (res != OK) {
93        ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
94                __FUNCTION__, mId, strerror(-res), res);
95        return res;
96    }
97
98    res = mDevice->ops->get_metadata_vendor_tag_ops(mDevice, &mVendorTagOps);
99    if (res != OK ) {
100        ALOGE("%s: Camera %d: Unable to retrieve tag ops from device: %s (%d)",
101                __FUNCTION__, mId, strerror(-res), res);
102        return res;
103    }
104
105    return OK;
106}
107
108camera_metadata_t *Camera2Device::info() {
109    ALOGV("%s: E", __FUNCTION__);
110
111    return mDeviceInfo;
112}
113
114status_t Camera2Device::setStreamingRequest(camera_metadata_t* request)
115{
116    ALOGV("%s: E", __FUNCTION__);
117
118    mRequestQueue.setStreamSlot(request);
119    return OK;
120}
121
122status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
123        uint32_t width, uint32_t height, int format, int *id) {
124    status_t res;
125    ALOGV("%s: E", __FUNCTION__);
126
127    sp<StreamAdapter> stream = new StreamAdapter(mDevice);
128
129    res = stream->connectToDevice(consumer, width, height, format);
130    if (res != OK) {
131        ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
132                "%s (%d)",
133                __FUNCTION__, mId, width, height, format, strerror(-res), res);
134        return res;
135    }
136
137    *id = stream->getId();
138
139    mStreams.push_back(stream);
140    return OK;
141}
142
143status_t Camera2Device::deleteStream(int id) {
144    ALOGV("%s: E", __FUNCTION__);
145
146    bool found = false;
147    for (StreamList::iterator streamI = mStreams.begin();
148         streamI != mStreams.end(); streamI++) {
149        if ((*streamI)->getId() == id) {
150            mStreams.erase(streamI);
151            found = true;
152            break;
153        }
154    }
155    if (!found) {
156        ALOGE("%s: Camera %d: Unable to find stream %d to delete",
157                __FUNCTION__, mId, id);
158        return BAD_VALUE;
159    }
160    return OK;
161}
162
163status_t Camera2Device::createDefaultRequest(int templateId,
164        camera_metadata_t **request) {
165    ALOGV("%s: E", __FUNCTION__);
166    return mDevice->ops->construct_default_request(mDevice, templateId, request);
167}
168
169/**
170 * Camera2Device::MetadataQueue
171 */
172
173Camera2Device::MetadataQueue::MetadataQueue():
174            mDevice(NULL),
175            mFrameCount(0),
176            mCount(0),
177            mStreamSlotCount(0),
178            mSignalConsumer(true)
179{
180    camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
181    camera2_request_queue_src_ops::request_count = consumer_buffer_count;
182    camera2_request_queue_src_ops::free_request = consumer_free;
183
184    camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
185    camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
186    camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
187}
188
189Camera2Device::MetadataQueue::~MetadataQueue() {
190    Mutex::Autolock l(mMutex);
191    freeBuffers(mEntries.begin(), mEntries.end());
192    freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
193}
194
195// Connect to camera2 HAL as consumer (input requests/reprocessing)
196status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
197    status_t res;
198    res = d->ops->set_request_queue_src_ops(d,
199            this);
200    if (res != OK) return res;
201    mDevice = d;
202    return OK;
203}
204
205status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
206    status_t res;
207    res = d->ops->set_frame_queue_dst_ops(d,
208            this);
209    return res;
210}
211
212// Real interfaces
213status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
214    ALOGV("%s: E", __FUNCTION__);
215    Mutex::Autolock l(mMutex);
216
217    mCount++;
218    mEntries.push_back(buf);
219
220    return signalConsumerLocked();
221}
222
223int Camera2Device::MetadataQueue::getBufferCount() {
224    Mutex::Autolock l(mMutex);
225    if (mStreamSlotCount > 0) {
226        return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
227    }
228    return mCount;
229}
230
231status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
232        bool incrementCount)
233{
234    ALOGV("%s: E", __FUNCTION__);
235    status_t res;
236    Mutex::Autolock l(mMutex);
237
238    if (mCount == 0) {
239        if (mStreamSlotCount == 0) {
240            ALOGV("%s: Empty", __FUNCTION__);
241            *buf = NULL;
242            mSignalConsumer = true;
243            return OK;
244        }
245        ALOGV("%s: Streaming %d frames to queue", __FUNCTION__,
246              mStreamSlotCount);
247
248        for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
249                slotEntry != mStreamSlot.end();
250                slotEntry++ ) {
251            size_t entries = get_camera_metadata_entry_count(*slotEntry);
252            size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
253
254            camera_metadata_t *copy =
255                    allocate_camera_metadata(entries, dataBytes);
256            append_camera_metadata(copy, *slotEntry);
257            mEntries.push_back(copy);
258        }
259        mCount = mStreamSlotCount;
260    }
261    ALOGV("MetadataQueue: deque (%d buffers)", mCount);
262    camera_metadata_t *b = *(mEntries.begin());
263    mEntries.erase(mEntries.begin());
264
265    if (incrementCount) {
266        camera_metadata_entry_t frameCount;
267        res = find_camera_metadata_entry(b,
268                ANDROID_REQUEST_FRAME_COUNT,
269                &frameCount);
270        if (res != OK) {
271            ALOGE("%s: Unable to add frame count: %s (%d)",
272                    __FUNCTION__, strerror(-res), res);
273        } else {
274            *frameCount.data.i32 = mFrameCount;
275        }
276        mFrameCount++;
277    }
278
279    *buf = b;
280    mCount--;
281
282    return OK;
283}
284
285status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
286{
287    Mutex::Autolock l(mMutex);
288    status_t res;
289    while (mCount == 0) {
290        res = notEmpty.waitRelative(mMutex,timeout);
291        if (res != OK) return res;
292    }
293    return OK;
294}
295
296status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
297{
298    ALOGV("%s: E", __FUNCTION__);
299    Mutex::Autolock l(mMutex);
300    if (buf == NULL) {
301        freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
302        mStreamSlotCount = 0;
303        return OK;
304    }
305    if (mStreamSlotCount > 1) {
306        List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
307        freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
308        mStreamSlotCount = 1;
309    }
310    if (mStreamSlotCount == 1) {
311        free_camera_metadata( *(mStreamSlot.begin()) );
312        *(mStreamSlot.begin()) = buf;
313    } else {
314        mStreamSlot.push_front(buf);
315        mStreamSlotCount = 1;
316    }
317    return signalConsumerLocked();
318}
319
320status_t Camera2Device::MetadataQueue::setStreamSlot(
321        const List<camera_metadata_t*> &bufs)
322{
323    ALOGV("%s: E", __FUNCTION__);
324    Mutex::Autolock l(mMutex);
325    if (mStreamSlotCount > 0) {
326        freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
327    }
328    mStreamSlot = bufs;
329    mStreamSlotCount = mStreamSlot.size();
330    return signalConsumerLocked();
331}
332
333status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
334    status_t res = OK;
335    notEmpty.signal();
336    if (mSignalConsumer && mDevice != NULL) {
337        mSignalConsumer = false;
338
339        mMutex.unlock();
340        ALOGV("%s: Signaling consumer", __FUNCTION__);
341        res = mDevice->ops->notify_request_queue_not_empty(mDevice);
342        mMutex.lock();
343    }
344    return res;
345}
346
347status_t Camera2Device::MetadataQueue::freeBuffers(
348        List<camera_metadata_t*>::iterator start,
349        List<camera_metadata_t*>::iterator end)
350{
351    while (start != end) {
352        free_camera_metadata(*start);
353        start = mStreamSlot.erase(start);
354    }
355    return OK;
356}
357
358Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
359        const camera2_request_queue_src_ops_t *q)
360{
361    const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
362    return const_cast<MetadataQueue*>(cmq);
363}
364
365Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
366        const camera2_frame_queue_dst_ops_t *q)
367{
368    const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
369    return const_cast<MetadataQueue*>(cmq);
370}
371
372int Camera2Device::MetadataQueue::consumer_buffer_count(
373        const camera2_request_queue_src_ops_t *q)
374{
375    MetadataQueue *queue = getInstance(q);
376    return queue->getBufferCount();
377}
378
379int Camera2Device::MetadataQueue::consumer_dequeue(
380        const camera2_request_queue_src_ops_t *q,
381        camera_metadata_t **buffer)
382{
383    MetadataQueue *queue = getInstance(q);
384    return queue->dequeue(buffer, true);
385}
386
387int Camera2Device::MetadataQueue::consumer_free(
388        const camera2_request_queue_src_ops_t *q,
389        camera_metadata_t *old_buffer)
390{
391    MetadataQueue *queue = getInstance(q);
392    free_camera_metadata(old_buffer);
393    return OK;
394}
395
396int Camera2Device::MetadataQueue::producer_dequeue(
397        const camera2_frame_queue_dst_ops_t *q,
398        size_t entries, size_t bytes,
399        camera_metadata_t **buffer)
400{
401    camera_metadata_t *new_buffer =
402            allocate_camera_metadata(entries, bytes);
403    if (new_buffer == NULL) return NO_MEMORY;
404    *buffer = new_buffer;
405        return OK;
406}
407
408int Camera2Device::MetadataQueue::producer_cancel(
409        const camera2_frame_queue_dst_ops_t *q,
410        camera_metadata_t *old_buffer)
411{
412    free_camera_metadata(old_buffer);
413    return OK;
414}
415
416int Camera2Device::MetadataQueue::producer_enqueue(
417        const camera2_frame_queue_dst_ops_t *q,
418        camera_metadata_t *filled_buffer)
419{
420    MetadataQueue *queue = getInstance(q);
421    return queue->enqueue(filled_buffer);
422}
423
424/**
425 * Camera2Device::StreamAdapter
426 */
427
428#ifndef container_of
429#define container_of(ptr, type, member) \
430    (type *)((char*)(ptr) - offsetof(type, member))
431#endif
432
433Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
434        mState(DISCONNECTED),
435        mDevice(d),
436        mId(-1),
437        mWidth(0), mHeight(0), mFormatRequested(0)
438{
439    camera2_stream_ops::dequeue_buffer = dequeue_buffer;
440    camera2_stream_ops::enqueue_buffer = enqueue_buffer;
441    camera2_stream_ops::cancel_buffer = cancel_buffer;
442    camera2_stream_ops::set_crop = set_crop;
443}
444
445Camera2Device::StreamAdapter::~StreamAdapter() {
446    disconnect();
447}
448
449status_t Camera2Device::StreamAdapter::connectToDevice(sp<ANativeWindow> consumer,
450        uint32_t width, uint32_t height, int format) {
451    status_t res;
452
453    if (mState != DISCONNECTED) return INVALID_OPERATION;
454    if (consumer == NULL) {
455        ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
456        return BAD_VALUE;
457    }
458
459    mConsumerInterface = consumer;
460    mWidth = width;
461    mHeight = height;
462    mFormatRequested = format;
463
464    // Allocate device-side stream interface
465
466    uint32_t id;
467    uint32_t formatActual;
468    uint32_t usage;
469    uint32_t maxBuffers = 2;
470    res = mDevice->ops->allocate_stream(mDevice,
471            mWidth, mHeight, mFormatRequested, getStreamOps(),
472            &id, &formatActual, &usage, &maxBuffers);
473    if (res != OK) {
474        ALOGE("%s: Device stream allocation failed: %s (%d)",
475                __FUNCTION__, strerror(-res), res);
476        return res;
477    }
478
479    mId = id;
480    mFormat = formatActual;
481    mUsage = usage;
482    mMaxProducerBuffers = maxBuffers;
483
484    mState = ALLOCATED;
485
486    // Configure consumer-side ANativeWindow interface
487    res = native_window_api_connect(mConsumerInterface.get(),
488            NATIVE_WINDOW_API_CAMERA);
489    if (res != OK) {
490        ALOGE("%s: Unable to connect to native window for stream %d",
491                __FUNCTION__, mId);
492
493        return res;
494    }
495
496    mState = CONNECTED;
497
498    res = native_window_set_usage(mConsumerInterface.get(), mUsage);
499    if (res != OK) {
500        ALOGE("%s: Unable to configure usage %08x for stream %d",
501                __FUNCTION__, mUsage, mId);
502        return res;
503    }
504
505    res = native_window_set_buffers_geometry(mConsumerInterface.get(),
506            mWidth, mHeight, mFormat);
507    if (res != OK) {
508        ALOGE("%s: Unable to configure buffer geometry"
509                " %d x %d, format 0x%x for stream %d",
510                __FUNCTION__, mWidth, mHeight, mFormat, mId);
511        return res;
512    }
513
514    int maxConsumerBuffers;
515    res = mConsumerInterface->query(mConsumerInterface.get(),
516            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
517    if (res != OK) {
518        ALOGE("%s: Unable to query consumer undequeued"
519                " buffer count for stream %d", __FUNCTION__, mId);
520        return res;
521    }
522    mMaxConsumerBuffers = maxConsumerBuffers;
523
524    ALOGV("%s: Producer wants %d buffers, consumer wants %d", __FUNCTION__,
525            mMaxProducerBuffers, mMaxConsumerBuffers);
526
527    int totalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
528
529    res = native_window_set_buffer_count(mConsumerInterface.get(),
530            totalBuffers);
531    if (res != OK) {
532        ALOGE("%s: Unable to set buffer count for stream %d",
533                __FUNCTION__, mId);
534        return res;
535    }
536
537    // Register allocated buffers with HAL device
538    buffer_handle_t *buffers = new buffer_handle_t[totalBuffers];
539    ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[totalBuffers];
540    int bufferIdx = 0;
541    for (; bufferIdx < totalBuffers; bufferIdx++) {
542        res = mConsumerInterface->dequeueBuffer(mConsumerInterface.get(),
543                &anwBuffers[bufferIdx]);
544        if (res != OK) {
545            ALOGE("%s: Unable to dequeue buffer %d for initial registration for"
546                    "stream %d", __FUNCTION__, bufferIdx, mId);
547            goto cleanUpBuffers;
548        }
549
550        res = mConsumerInterface->lockBuffer(mConsumerInterface.get(),
551                anwBuffers[bufferIdx]);
552        if (res != OK) {
553            ALOGE("%s: Unable to lock buffer %d for initial registration for"
554                    "stream %d", __FUNCTION__, bufferIdx, mId);
555            bufferIdx++;
556            goto cleanUpBuffers;
557        }
558
559        buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
560    }
561
562    res = mDevice->ops->register_stream_buffers(mDevice,
563            mId,
564            totalBuffers,
565            buffers);
566    if (res != OK) {
567        ALOGE("%s: Unable to register buffers with HAL device for stream %d",
568                __FUNCTION__, mId);
569    } else {
570        mState = ACTIVE;
571    }
572
573cleanUpBuffers:
574    for (int i = 0; i < bufferIdx; i++) {
575        res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
576                anwBuffers[i]);
577        if (res != OK) {
578            ALOGE("%s: Unable to cancel buffer %d after registration",
579                    __FUNCTION__, i);
580        }
581    }
582    delete anwBuffers;
583    delete buffers;
584
585    return res;
586}
587
588status_t Camera2Device::StreamAdapter::disconnect() {
589    status_t res;
590    if (mState >= ALLOCATED) {
591        res = mDevice->ops->release_stream(mDevice, mId);
592        if (res != OK) {
593            ALOGE("%s: Unable to release stream %d",
594                    __FUNCTION__, mId);
595            return res;
596        }
597    }
598    if (mState >= CONNECTED) {
599        res = native_window_api_disconnect(mConsumerInterface.get(),
600                NATIVE_WINDOW_API_CAMERA);
601        if (res != OK) {
602            ALOGE("%s: Unable to disconnect stream %d from native window",
603                    __FUNCTION__, mId);
604            return res;
605        }
606    }
607    mId = -1;
608    mState = DISCONNECTED;
609    return OK;
610}
611
612int Camera2Device::StreamAdapter::getId() {
613    return mId;
614}
615
616const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
617    return static_cast<camera2_stream_ops *>(this);
618}
619
620ANativeWindow* Camera2Device::StreamAdapter::toANW(
621        const camera2_stream_ops_t *w) {
622    return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
623}
624
625int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
626        buffer_handle_t** buffer) {
627    int res;
628    int state = static_cast<const StreamAdapter*>(w)->mState;
629    if (state != ACTIVE) {
630        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
631        return INVALID_OPERATION;
632    }
633
634    ANativeWindow *a = toANW(w);
635    ANativeWindowBuffer* anb;
636    res = a->dequeueBuffer(a, &anb);
637    if (res != OK) return res;
638    res = a->lockBuffer(a, anb);
639    if (res != OK) return res;
640
641    *buffer = &(anb->handle);
642    ALOGV("%s: Buffer %p", __FUNCTION__, *buffer);
643    return res;
644}
645
646int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
647        int64_t timestamp,
648        buffer_handle_t* buffer) {
649    ALOGV("%s: Buffer %p captured at %lld ns", __FUNCTION__, buffer, timestamp);
650    int state = static_cast<const StreamAdapter*>(w)->mState;
651    if (state != ACTIVE) {
652        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
653        return INVALID_OPERATION;
654    }
655    ANativeWindow *a = toANW(w);
656    status_t err;
657    err = native_window_set_buffers_timestamp(a, timestamp);
658    if (err != OK) return err;
659    return a->queueBuffer(a,
660            container_of(buffer, ANativeWindowBuffer, handle));
661}
662
663int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
664        buffer_handle_t* buffer) {
665    int state = static_cast<const StreamAdapter*>(w)->mState;
666    if (state != ACTIVE) {
667        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
668        return INVALID_OPERATION;
669    }
670    ANativeWindow *a = toANW(w);
671    return a->cancelBuffer(a,
672            container_of(buffer, ANativeWindowBuffer, handle));
673}
674
675int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
676        int left, int top, int right, int bottom) {
677    int state = static_cast<const StreamAdapter*>(w)->mState;
678    if (state != ACTIVE) {
679        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
680        return INVALID_OPERATION;
681    }
682    ANativeWindow *a = toANW(w);
683    android_native_rect_t crop = { left, top, right, bottom };
684    return native_window_set_crop(a, &crop);
685}
686
687
688}; // namespace android
689