Camera2Device.cpp revision 1fa8999c91d5df81949aa723000058380cd3faa2
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 "Camera2-Device"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20//#define LOG_NNDEBUG 0  // Per-frame verbose logging
21
22#ifdef LOG_NNDEBUG
23#define ALOGVV(...) ALOGV(__VA_ARGS__)
24#else
25#define ALOGVV(...) ((void)0)
26#endif
27
28#include <inttypes.h>
29#include <utils/Log.h>
30#include <utils/Trace.h>
31#include <utils/Timers.h>
32#include "Camera2Device.h"
33#include "CameraService.h"
34
35namespace android {
36
37Camera2Device::Camera2Device(int id):
38        mId(id),
39        mHal2Device(NULL)
40{
41    ATRACE_CALL();
42    ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
43}
44
45Camera2Device::~Camera2Device()
46{
47    ATRACE_CALL();
48    ALOGV("%s: Tearing down for camera id %d", __FUNCTION__, mId);
49    disconnect();
50}
51
52int Camera2Device::getId() const {
53    return mId;
54}
55
56status_t Camera2Device::initialize(CameraModule *module)
57{
58    ATRACE_CALL();
59    ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
60    if (mHal2Device != NULL) {
61        ALOGE("%s: Already initialized!", __FUNCTION__);
62        return INVALID_OPERATION;
63    }
64
65    status_t res;
66    char name[10];
67    snprintf(name, sizeof(name), "%d", mId);
68
69    camera2_device_t *device;
70
71    res = module->open(name, reinterpret_cast<hw_device_t**>(&device));
72
73    if (res != OK) {
74        ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
75                mId, strerror(-res), res);
76        return res;
77    }
78
79    if (device->common.version != CAMERA_DEVICE_API_VERSION_2_0) {
80        ALOGE("%s: Could not open camera %d: "
81                "Camera device is not version %x, reports %x instead",
82                __FUNCTION__, mId, CAMERA_DEVICE_API_VERSION_2_0,
83                device->common.version);
84        device->common.close(&device->common);
85        return BAD_VALUE;
86    }
87
88    camera_info info;
89    res = module->getCameraInfo(mId, &info);
90    if (res != OK ) return res;
91
92    if (info.device_version != device->common.version) {
93        ALOGE("%s: HAL reporting mismatched camera_info version (%x)"
94                " and device version (%x).", __FUNCTION__,
95                device->common.version, info.device_version);
96        device->common.close(&device->common);
97        return BAD_VALUE;
98    }
99
100    res = mRequestQueue.setConsumerDevice(device);
101    if (res != OK) {
102        ALOGE("%s: Camera %d: Unable to connect request queue to device: %s (%d)",
103                __FUNCTION__, mId, strerror(-res), res);
104        device->common.close(&device->common);
105        return res;
106    }
107    res = mFrameQueue.setProducerDevice(device);
108    if (res != OK) {
109        ALOGE("%s: Camera %d: Unable to connect frame queue to device: %s (%d)",
110                __FUNCTION__, mId, strerror(-res), res);
111        device->common.close(&device->common);
112        return res;
113    }
114
115    res = device->ops->set_notify_callback(device, notificationCallback,
116            NULL);
117    if (res != OK) {
118        ALOGE("%s: Camera %d: Unable to initialize notification callback!",
119                __FUNCTION__, mId);
120        device->common.close(&device->common);
121        return res;
122    }
123
124    mDeviceInfo = info.static_camera_characteristics;
125    mHal2Device = device;
126    mDeviceVersion = device->common.version;
127
128    return OK;
129}
130
131status_t Camera2Device::disconnect() {
132    ATRACE_CALL();
133    status_t res = OK;
134    if (mHal2Device) {
135        ALOGV("%s: Closing device for camera %d", __FUNCTION__, mId);
136
137        int inProgressCount = mHal2Device->ops->get_in_progress_count(mHal2Device);
138        if (inProgressCount > 0) {
139            ALOGW("%s: Closing camera device %d with %d requests in flight!",
140                    __FUNCTION__, mId, inProgressCount);
141        }
142        mReprocessStreams.clear();
143        mStreams.clear();
144        res = mHal2Device->common.close(&mHal2Device->common);
145        if (res != OK) {
146            ALOGE("%s: Could not close camera %d: %s (%d)",
147                    __FUNCTION__,
148                    mId, strerror(-res), res);
149        }
150        mHal2Device = NULL;
151        ALOGV("%s: Shutdown complete", __FUNCTION__);
152    }
153    return res;
154}
155
156status_t Camera2Device::dump(int fd, const Vector<String16>& args) {
157    ATRACE_CALL();
158    String8 result;
159    int detailLevel = 0;
160    int n = args.size();
161    String16 detailOption("-d");
162    for (int i = 0; i + 1 < n; i++) {
163        if (args[i] == detailOption) {
164            String8 levelStr(args[i+1]);
165            detailLevel = atoi(levelStr.string());
166        }
167    }
168
169    result.appendFormat("  Camera2Device[%d] dump (detail level %d):\n",
170            mId, detailLevel);
171
172    if (detailLevel > 0) {
173        result = "    Request queue contents:\n";
174        write(fd, result.string(), result.size());
175        mRequestQueue.dump(fd, args);
176
177        result = "    Frame queue contents:\n";
178        write(fd, result.string(), result.size());
179        mFrameQueue.dump(fd, args);
180    }
181
182    result = "    Active streams:\n";
183    write(fd, result.string(), result.size());
184    for (StreamList::iterator s = mStreams.begin(); s != mStreams.end(); s++) {
185        (*s)->dump(fd, args);
186    }
187
188    result = "    HAL device dump:\n";
189    write(fd, result.string(), result.size());
190
191    status_t res;
192    res = mHal2Device->ops->dump(mHal2Device, fd);
193
194    return res;
195}
196
197const CameraMetadata& Camera2Device::info() const {
198    ALOGVV("%s: E", __FUNCTION__);
199
200    return mDeviceInfo;
201}
202
203status_t Camera2Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
204    ATRACE_CALL();
205    ALOGV("%s: E", __FUNCTION__);
206
207    mRequestQueue.enqueue(request.release());
208    return OK;
209}
210
211status_t Camera2Device::captureList(const List<const CameraMetadata> &requests,
212                                    int64_t* /*lastFrameNumber*/) {
213    ATRACE_CALL();
214    ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__);
215    return INVALID_OPERATION;
216}
217
218status_t Camera2Device::setStreamingRequest(const CameraMetadata &request,
219                                            int64_t* /*lastFrameNumber*/) {
220    ATRACE_CALL();
221    ALOGV("%s: E", __FUNCTION__);
222    CameraMetadata streamRequest(request);
223    return mRequestQueue.setStreamSlot(streamRequest.release());
224}
225
226status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests,
227                                                int64_t* /*lastFrameNumber*/) {
228    ATRACE_CALL();
229    ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__);
230    return INVALID_OPERATION;
231}
232
233status_t Camera2Device::clearStreamingRequest(int64_t* /*lastFrameNumber*/) {
234    ATRACE_CALL();
235    return mRequestQueue.setStreamSlot(NULL);
236}
237
238status_t Camera2Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
239    ATRACE_CALL();
240    return mRequestQueue.waitForDequeue(requestId, timeout);
241}
242
243status_t Camera2Device::createStream(sp<ANativeWindow> consumer,
244        uint32_t width, uint32_t height, int format,
245        android_dataspace /*dataSpace*/, camera3_stream_rotation_t rotation, int *id) {
246    ATRACE_CALL();
247    status_t res;
248    ALOGV("%s: E", __FUNCTION__);
249
250    sp<StreamAdapter> stream = new StreamAdapter(mHal2Device);
251    size_t size = 0;
252    if (format == HAL_PIXEL_FORMAT_BLOB) {
253        size = getJpegBufferSize(width, height);
254    }
255    res = stream->connectToDevice(consumer, width, height, format, size);
256    if (res != OK) {
257        ALOGE("%s: Camera %d: Unable to create stream (%d x %d, format %x):"
258                "%s (%d)",
259                __FUNCTION__, mId, width, height, format, strerror(-res), res);
260        return res;
261    }
262
263    *id = stream->getId();
264
265    mStreams.push_back(stream);
266    return OK;
267}
268
269ssize_t Camera2Device::getJpegBufferSize(uint32_t width, uint32_t height) const {
270    // Always give the max jpeg buffer size regardless of the actual jpeg resolution.
271    camera_metadata_ro_entry jpegBufMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE);
272    if (jpegBufMaxSize.count == 0) {
273        ALOGE("%s: Camera %d: Can't find maximum JPEG size in static metadata!", __FUNCTION__, mId);
274        return BAD_VALUE;
275    }
276
277    return jpegBufMaxSize.data.i32[0];
278}
279
280status_t Camera2Device::createReprocessStreamFromStream(int outputId, int *id) {
281    ATRACE_CALL();
282    status_t res;
283    ALOGV("%s: E", __FUNCTION__);
284
285    bool found = false;
286    StreamList::iterator streamI;
287    for (streamI = mStreams.begin();
288         streamI != mStreams.end(); streamI++) {
289        if ((*streamI)->getId() == outputId) {
290            found = true;
291            break;
292        }
293    }
294    if (!found) {
295        ALOGE("%s: Camera %d: Output stream %d doesn't exist; can't create "
296                "reprocess stream from it!", __FUNCTION__, mId, outputId);
297        return BAD_VALUE;
298    }
299
300    sp<ReprocessStreamAdapter> stream = new ReprocessStreamAdapter(mHal2Device);
301
302    res = stream->connectToDevice((*streamI));
303    if (res != OK) {
304        ALOGE("%s: Camera %d: Unable to create reprocessing stream from "\
305                "stream %d: %s (%d)", __FUNCTION__, mId, outputId,
306                strerror(-res), res);
307        return res;
308    }
309
310    *id = stream->getId();
311
312    mReprocessStreams.push_back(stream);
313    return OK;
314}
315
316
317status_t Camera2Device::getStreamInfo(int id,
318        uint32_t *width, uint32_t *height, uint32_t *format) {
319    ATRACE_CALL();
320    ALOGV("%s: E", __FUNCTION__);
321    bool found = false;
322    StreamList::iterator streamI;
323    for (streamI = mStreams.begin();
324         streamI != mStreams.end(); streamI++) {
325        if ((*streamI)->getId() == id) {
326            found = true;
327            break;
328        }
329    }
330    if (!found) {
331        ALOGE("%s: Camera %d: Stream %d does not exist",
332                __FUNCTION__, mId, id);
333        return BAD_VALUE;
334    }
335
336    if (width) *width = (*streamI)->getWidth();
337    if (height) *height = (*streamI)->getHeight();
338    if (format) *format = (*streamI)->getFormat();
339
340    return OK;
341}
342
343status_t Camera2Device::setStreamTransform(int id,
344        int transform) {
345    ATRACE_CALL();
346    ALOGV("%s: E", __FUNCTION__);
347    bool found = false;
348    StreamList::iterator streamI;
349    for (streamI = mStreams.begin();
350         streamI != mStreams.end(); streamI++) {
351        if ((*streamI)->getId() == id) {
352            found = true;
353            break;
354        }
355    }
356    if (!found) {
357        ALOGE("%s: Camera %d: Stream %d does not exist",
358                __FUNCTION__, mId, id);
359        return BAD_VALUE;
360    }
361
362    return (*streamI)->setTransform(transform);
363}
364
365status_t Camera2Device::deleteStream(int id) {
366    ATRACE_CALL();
367    ALOGV("%s: E", __FUNCTION__);
368    bool found = false;
369    for (StreamList::iterator streamI = mStreams.begin();
370         streamI != mStreams.end(); streamI++) {
371        if ((*streamI)->getId() == id) {
372            status_t res = (*streamI)->release();
373            if (res != OK) {
374                ALOGE("%s: Unable to release stream %d from HAL device: "
375                        "%s (%d)", __FUNCTION__, id, strerror(-res), res);
376                return res;
377            }
378            mStreams.erase(streamI);
379            found = true;
380            break;
381        }
382    }
383    if (!found) {
384        ALOGE("%s: Camera %d: Unable to find stream %d to delete",
385                __FUNCTION__, mId, id);
386        return BAD_VALUE;
387    }
388    return OK;
389}
390
391status_t Camera2Device::deleteReprocessStream(int id) {
392    ATRACE_CALL();
393    ALOGV("%s: E", __FUNCTION__);
394    bool found = false;
395    for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
396         streamI != mReprocessStreams.end(); streamI++) {
397        if ((*streamI)->getId() == id) {
398            status_t res = (*streamI)->release();
399            if (res != OK) {
400                ALOGE("%s: Unable to release reprocess stream %d from "
401                        "HAL device: %s (%d)", __FUNCTION__, id,
402                        strerror(-res), res);
403                return res;
404            }
405            mReprocessStreams.erase(streamI);
406            found = true;
407            break;
408        }
409    }
410    if (!found) {
411        ALOGE("%s: Camera %d: Unable to find stream %d to delete",
412                __FUNCTION__, mId, id);
413        return BAD_VALUE;
414    }
415    return OK;
416}
417
418status_t Camera2Device::configureStreams(bool isConstrainedHighSpeed) {
419    ATRACE_CALL();
420    ALOGV("%s: E", __FUNCTION__);
421
422    /**
423     * HAL2 devices do not need to configure streams;
424     * streams are created on the fly.
425     */
426    ALOGW("%s: No-op for HAL2 devices", __FUNCTION__);
427
428    return OK;
429}
430
431
432status_t Camera2Device::createDefaultRequest(int templateId,
433        CameraMetadata *request) {
434    ATRACE_CALL();
435    status_t err;
436    ALOGV("%s: E", __FUNCTION__);
437    camera_metadata_t *rawRequest;
438    err = mHal2Device->ops->construct_default_request(
439        mHal2Device, templateId, &rawRequest);
440    request->acquire(rawRequest);
441    return err;
442}
443
444status_t Camera2Device::waitUntilDrained() {
445    ATRACE_CALL();
446    static const uint32_t kSleepTime = 50000; // 50 ms
447    static const uint32_t kMaxSleepTime = 10000000; // 10 s
448    ALOGV("%s: Camera %d: Starting wait", __FUNCTION__, mId);
449    if (mRequestQueue.getBufferCount() ==
450            CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS) return INVALID_OPERATION;
451
452    // TODO: Set up notifications from HAL, instead of sleeping here
453    uint32_t totalTime = 0;
454    while (mHal2Device->ops->get_in_progress_count(mHal2Device) > 0) {
455        usleep(kSleepTime);
456        totalTime += kSleepTime;
457        if (totalTime > kMaxSleepTime) {
458            ALOGE("%s: Waited %d us, %d requests still in flight", __FUNCTION__,
459                    totalTime, mHal2Device->ops->get_in_progress_count(mHal2Device));
460            return TIMED_OUT;
461        }
462    }
463    ALOGV("%s: Camera %d: HAL is idle", __FUNCTION__, mId);
464    return OK;
465}
466
467status_t Camera2Device::setNotifyCallback(NotificationListener *listener) {
468    ATRACE_CALL();
469    status_t res;
470    res = mHal2Device->ops->set_notify_callback(mHal2Device, notificationCallback,
471            reinterpret_cast<void*>(listener) );
472    if (res != OK) {
473        ALOGE("%s: Unable to set notification callback!", __FUNCTION__);
474    }
475    return res;
476}
477
478bool Camera2Device::willNotify3A() {
479    return true;
480}
481
482void Camera2Device::notificationCallback(int32_t msg_type,
483        int32_t ext1,
484        int32_t ext2,
485        int32_t ext3,
486        void *user) {
487    ATRACE_CALL();
488    NotificationListener *listener = reinterpret_cast<NotificationListener*>(user);
489    ALOGV("%s: Notification %d, arguments %d, %d, %d", __FUNCTION__, msg_type,
490            ext1, ext2, ext3);
491    if (listener != NULL) {
492        switch (msg_type) {
493            case CAMERA2_MSG_ERROR:
494                // TODO: This needs to be fixed. ext2 and ext3 need to be considered.
495                listener->notifyError(
496                        ((ext1 == CAMERA2_MSG_ERROR_DEVICE)
497                        || (ext1 == CAMERA2_MSG_ERROR_HARDWARE)) ?
498                                ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
499                                ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
500                        CaptureResultExtras());
501                break;
502            case CAMERA2_MSG_SHUTTER: {
503                // TODO: Only needed for camera2 API, which is unsupported
504                // by HAL2 directly.
505                // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
506                // listener->notifyShutter(requestId, timestamp);
507                break;
508            }
509            case CAMERA2_MSG_AUTOFOCUS:
510                listener->notifyAutoFocus(ext1, ext2);
511                break;
512            case CAMERA2_MSG_AUTOEXPOSURE:
513                listener->notifyAutoExposure(ext1, ext2);
514                break;
515            case CAMERA2_MSG_AUTOWB:
516                listener->notifyAutoWhitebalance(ext1, ext2);
517                break;
518            default:
519                ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
520                        __FUNCTION__, msg_type, ext1, ext2, ext3);
521        }
522    }
523}
524
525status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
526    return mFrameQueue.waitForBuffer(timeout);
527}
528
529status_t Camera2Device::getNextResult(CaptureResult *result) {
530    ATRACE_CALL();
531    ALOGV("%s: get CaptureResult", __FUNCTION__);
532    if (result == NULL) {
533        ALOGE("%s: result pointer is NULL", __FUNCTION__);
534        return BAD_VALUE;
535    }
536    status_t res;
537    camera_metadata_t *rawFrame;
538    res = mFrameQueue.dequeue(&rawFrame);
539    if (rawFrame == NULL) {
540        return NOT_ENOUGH_DATA;
541    } else if (res == OK) {
542        result->mMetadata.acquire(rawFrame);
543    }
544
545    return res;
546}
547
548status_t Camera2Device::triggerAutofocus(uint32_t id) {
549    ATRACE_CALL();
550    status_t res;
551    ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
552    res = mHal2Device->ops->trigger_action(mHal2Device,
553            CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
554    if (res != OK) {
555        ALOGE("%s: Error triggering autofocus (id %d)",
556                __FUNCTION__, id);
557    }
558    return res;
559}
560
561status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
562    ATRACE_CALL();
563    status_t res;
564    ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
565    res = mHal2Device->ops->trigger_action(mHal2Device,
566            CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
567    if (res != OK) {
568        ALOGE("%s: Error canceling autofocus (id %d)",
569                __FUNCTION__, id);
570    }
571    return res;
572}
573
574status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
575    ATRACE_CALL();
576    status_t res;
577    ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
578    res = mHal2Device->ops->trigger_action(mHal2Device,
579            CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
580    if (res != OK) {
581        ALOGE("%s: Error triggering precapture metering (id %d)",
582                __FUNCTION__, id);
583    }
584    return res;
585}
586
587status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
588        buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
589    ATRACE_CALL();
590    ALOGV("%s: E", __FUNCTION__);
591    bool found = false;
592    status_t res = OK;
593    for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
594         streamI != mReprocessStreams.end(); streamI++) {
595        if ((*streamI)->getId() == reprocessStreamId) {
596            res = (*streamI)->pushIntoStream(buffer, listener);
597            if (res != OK) {
598                ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
599                        __FUNCTION__, reprocessStreamId, strerror(-res), res);
600                return res;
601            }
602            found = true;
603            break;
604        }
605    }
606    if (!found) {
607        ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
608                __FUNCTION__, mId, reprocessStreamId);
609        res = BAD_VALUE;
610    }
611    return res;
612}
613
614status_t Camera2Device::flush(int64_t* /*lastFrameNumber*/) {
615    ATRACE_CALL();
616
617    mRequestQueue.clear();
618    return waitUntilDrained();
619}
620
621status_t Camera2Device::prepare(int streamId) {
622    ATRACE_CALL();
623    ALOGE("%s: Camera %d: unimplemented", __FUNCTION__, mId);
624    return NO_INIT;
625}
626
627uint32_t Camera2Device::getDeviceVersion() {
628    ATRACE_CALL();
629    return mDeviceVersion;
630}
631
632/**
633 * Camera2Device::MetadataQueue
634 */
635
636Camera2Device::MetadataQueue::MetadataQueue():
637            mHal2Device(NULL),
638            mFrameCount(0),
639            mLatestRequestId(0),
640            mCount(0),
641            mStreamSlotCount(0),
642            mSignalConsumer(true)
643{
644    ATRACE_CALL();
645    camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
646    camera2_request_queue_src_ops::request_count = consumer_buffer_count;
647    camera2_request_queue_src_ops::free_request = consumer_free;
648
649    camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
650    camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
651    camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
652}
653
654Camera2Device::MetadataQueue::~MetadataQueue() {
655    ATRACE_CALL();
656    clear();
657}
658
659// Connect to camera2 HAL as consumer (input requests/reprocessing)
660status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
661    ATRACE_CALL();
662    status_t res;
663    res = d->ops->set_request_queue_src_ops(d,
664            this);
665    if (res != OK) return res;
666    mHal2Device = d;
667    return OK;
668}
669
670status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
671    ATRACE_CALL();
672    status_t res;
673    res = d->ops->set_frame_queue_dst_ops(d,
674            this);
675    return res;
676}
677
678// Real interfaces
679status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
680    ATRACE_CALL();
681    ALOGVV("%s: E", __FUNCTION__);
682    Mutex::Autolock l(mMutex);
683
684    mCount++;
685    mEntries.push_back(buf);
686
687    return signalConsumerLocked();
688}
689
690int Camera2Device::MetadataQueue::getBufferCount() {
691    ATRACE_CALL();
692    Mutex::Autolock l(mMutex);
693    if (mStreamSlotCount > 0) {
694        return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
695    }
696    return mCount;
697}
698
699status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
700        bool incrementCount)
701{
702    ATRACE_CALL();
703    ALOGVV("%s: E", __FUNCTION__);
704    status_t res;
705    Mutex::Autolock l(mMutex);
706
707    if (mCount == 0) {
708        if (mStreamSlotCount == 0) {
709            ALOGVV("%s: Empty", __FUNCTION__);
710            *buf = NULL;
711            mSignalConsumer = true;
712            return OK;
713        }
714        ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
715              mStreamSlotCount);
716
717        for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
718                slotEntry != mStreamSlot.end();
719                slotEntry++ ) {
720            size_t entries = get_camera_metadata_entry_count(*slotEntry);
721            size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
722
723            camera_metadata_t *copy =
724                    allocate_camera_metadata(entries, dataBytes);
725            append_camera_metadata(copy, *slotEntry);
726            mEntries.push_back(copy);
727        }
728        mCount = mStreamSlotCount;
729    }
730    ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
731    camera_metadata_t *b = *(mEntries.begin());
732    mEntries.erase(mEntries.begin());
733
734    if (incrementCount) {
735        ATRACE_INT("cam2_request", mFrameCount);
736        camera_metadata_entry_t frameCount;
737        res = find_camera_metadata_entry(b,
738                ANDROID_REQUEST_FRAME_COUNT,
739                &frameCount);
740        if (res != OK) {
741            ALOGE("%s: Unable to add frame count: %s (%d)",
742                    __FUNCTION__, strerror(-res), res);
743        } else {
744            *frameCount.data.i32 = mFrameCount;
745        }
746        mFrameCount++;
747    }
748
749    // Check for request ID, and if present, signal waiters.
750    camera_metadata_entry_t requestId;
751    res = find_camera_metadata_entry(b,
752            ANDROID_REQUEST_ID,
753            &requestId);
754    if (res == OK) {
755        mLatestRequestId = requestId.data.i32[0];
756        mNewRequestId.signal();
757    }
758
759    *buf = b;
760    mCount--;
761
762    return OK;
763}
764
765status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
766{
767    Mutex::Autolock l(mMutex);
768    status_t res;
769    while (mCount == 0) {
770        res = notEmpty.waitRelative(mMutex,timeout);
771        if (res != OK) return res;
772    }
773    return OK;
774}
775
776status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
777        nsecs_t timeout) {
778    Mutex::Autolock l(mMutex);
779    status_t res;
780    while (mLatestRequestId != id) {
781        nsecs_t startTime = systemTime();
782
783        res = mNewRequestId.waitRelative(mMutex, timeout);
784        if (res != OK) return res;
785
786        timeout -= (systemTime() - startTime);
787    }
788
789    return OK;
790}
791
792status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
793{
794    ATRACE_CALL();
795    ALOGV("%s: E", __FUNCTION__);
796    Mutex::Autolock l(mMutex);
797    if (buf == NULL) {
798        freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
799        mStreamSlotCount = 0;
800        return OK;
801    }
802
803    if (mStreamSlotCount > 1) {
804        List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
805        freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
806        mStreamSlotCount = 1;
807    }
808    if (mStreamSlotCount == 1) {
809        free_camera_metadata( *(mStreamSlot.begin()) );
810        *(mStreamSlot.begin()) = buf;
811    } else {
812        mStreamSlot.push_front(buf);
813        mStreamSlotCount = 1;
814    }
815    return signalConsumerLocked();
816}
817
818status_t Camera2Device::MetadataQueue::setStreamSlot(
819        const List<camera_metadata_t*> &bufs)
820{
821    ATRACE_CALL();
822    ALOGV("%s: E", __FUNCTION__);
823    Mutex::Autolock l(mMutex);
824
825    if (mStreamSlotCount > 0) {
826        freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
827    }
828    mStreamSlotCount = 0;
829    for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
830         r != bufs.end(); r++) {
831        mStreamSlot.push_back(*r);
832        mStreamSlotCount++;
833    }
834    return signalConsumerLocked();
835}
836
837status_t Camera2Device::MetadataQueue::clear()
838{
839    ATRACE_CALL();
840    ALOGV("%s: E", __FUNCTION__);
841
842    Mutex::Autolock l(mMutex);
843
844    // Clear streaming slot
845    freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
846    mStreamSlotCount = 0;
847
848    // Clear request queue
849    freeBuffers(mEntries.begin(), mEntries.end());
850    mCount = 0;
851    return OK;
852}
853
854status_t Camera2Device::MetadataQueue::dump(int fd,
855        const Vector<String16>& /*args*/) {
856    ATRACE_CALL();
857    String8 result;
858    status_t notLocked;
859    notLocked = mMutex.tryLock();
860    if (notLocked) {
861        result.append("    (Unable to lock queue mutex)\n");
862    }
863    result.appendFormat("      Current frame number: %d\n", mFrameCount);
864    if (mStreamSlotCount == 0) {
865        result.append("      Stream slot: Empty\n");
866        write(fd, result.string(), result.size());
867    } else {
868        result.appendFormat("      Stream slot: %zu entries\n",
869                mStreamSlot.size());
870        int i = 0;
871        for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
872             r != mStreamSlot.end(); r++) {
873            result = String8::format("       Stream slot buffer %d:\n", i);
874            write(fd, result.string(), result.size());
875            dump_indented_camera_metadata(*r, fd, 2, 10);
876            i++;
877        }
878    }
879    if (mEntries.size() == 0) {
880        result = "      Main queue is empty\n";
881        write(fd, result.string(), result.size());
882    } else {
883        result = String8::format("      Main queue has %zu entries:\n",
884                mEntries.size());
885        int i = 0;
886        for (List<camera_metadata_t*>::iterator r = mEntries.begin();
887             r != mEntries.end(); r++) {
888            result = String8::format("       Queue entry %d:\n", i);
889            write(fd, result.string(), result.size());
890            dump_indented_camera_metadata(*r, fd, 2, 10);
891            i++;
892        }
893    }
894
895    if (notLocked == 0) {
896        mMutex.unlock();
897    }
898
899    return OK;
900}
901
902status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
903    ATRACE_CALL();
904    status_t res = OK;
905    notEmpty.signal();
906    if (mSignalConsumer && mHal2Device != NULL) {
907        mSignalConsumer = false;
908
909        mMutex.unlock();
910        ALOGV("%s: Signaling consumer", __FUNCTION__);
911        res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
912        mMutex.lock();
913    }
914    return res;
915}
916
917status_t Camera2Device::MetadataQueue::freeBuffers(
918        List<camera_metadata_t*>::iterator start,
919        List<camera_metadata_t*>::iterator end)
920{
921    ATRACE_CALL();
922    while (start != end) {
923        free_camera_metadata(*start);
924        start = mStreamSlot.erase(start);
925    }
926    return OK;
927}
928
929Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
930        const camera2_request_queue_src_ops_t *q)
931{
932    const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
933    return const_cast<MetadataQueue*>(cmq);
934}
935
936Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
937        const camera2_frame_queue_dst_ops_t *q)
938{
939    const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
940    return const_cast<MetadataQueue*>(cmq);
941}
942
943int Camera2Device::MetadataQueue::consumer_buffer_count(
944        const camera2_request_queue_src_ops_t *q)
945{
946    MetadataQueue *queue = getInstance(q);
947    return queue->getBufferCount();
948}
949
950int Camera2Device::MetadataQueue::consumer_dequeue(
951        const camera2_request_queue_src_ops_t *q,
952        camera_metadata_t **buffer)
953{
954    MetadataQueue *queue = getInstance(q);
955    return queue->dequeue(buffer, true);
956}
957
958int Camera2Device::MetadataQueue::consumer_free(
959        const camera2_request_queue_src_ops_t *q,
960        camera_metadata_t *old_buffer)
961{
962    ATRACE_CALL();
963    MetadataQueue *queue = getInstance(q);
964    (void)queue;
965    free_camera_metadata(old_buffer);
966    return OK;
967}
968
969int Camera2Device::MetadataQueue::producer_dequeue(
970        const camera2_frame_queue_dst_ops_t * /*q*/,
971        size_t entries, size_t bytes,
972        camera_metadata_t **buffer)
973{
974    ATRACE_CALL();
975    camera_metadata_t *new_buffer =
976            allocate_camera_metadata(entries, bytes);
977    if (new_buffer == NULL) return NO_MEMORY;
978    *buffer = new_buffer;
979        return OK;
980}
981
982int Camera2Device::MetadataQueue::producer_cancel(
983        const camera2_frame_queue_dst_ops_t * /*q*/,
984        camera_metadata_t *old_buffer)
985{
986    ATRACE_CALL();
987    free_camera_metadata(old_buffer);
988    return OK;
989}
990
991int Camera2Device::MetadataQueue::producer_enqueue(
992        const camera2_frame_queue_dst_ops_t *q,
993        camera_metadata_t *filled_buffer)
994{
995    MetadataQueue *queue = getInstance(q);
996    return queue->enqueue(filled_buffer);
997}
998
999/**
1000 * Camera2Device::StreamAdapter
1001 */
1002
1003#ifndef container_of
1004#define container_of(ptr, type, member) \
1005    (type *)((char*)(ptr) - offsetof(type, member))
1006#endif
1007
1008Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
1009        mState(RELEASED),
1010        mHal2Device(d),
1011        mId(-1),
1012        mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
1013        mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
1014        mTotalBuffers(0),
1015        mFormatRequested(0),
1016        mActiveBuffers(0),
1017        mFrameCount(0),
1018        mLastTimestamp(0)
1019{
1020    camera2_stream_ops::dequeue_buffer = dequeue_buffer;
1021    camera2_stream_ops::enqueue_buffer = enqueue_buffer;
1022    camera2_stream_ops::cancel_buffer = cancel_buffer;
1023    camera2_stream_ops::set_crop = set_crop;
1024}
1025
1026Camera2Device::StreamAdapter::~StreamAdapter() {
1027    ATRACE_CALL();
1028    if (mState != RELEASED) {
1029        release();
1030    }
1031}
1032
1033status_t Camera2Device::StreamAdapter::connectToDevice(
1034        sp<ANativeWindow> consumer,
1035        uint32_t width, uint32_t height, int format, size_t size) {
1036    ATRACE_CALL();
1037    status_t res;
1038    ALOGV("%s: E", __FUNCTION__);
1039
1040    if (mState != RELEASED) return INVALID_OPERATION;
1041    if (consumer == NULL) {
1042        ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
1043        return BAD_VALUE;
1044    }
1045
1046    ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %zu",
1047            __FUNCTION__, width, height, format, size);
1048
1049    mConsumerInterface = consumer;
1050    mWidth = width;
1051    mHeight = height;
1052    mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
1053    mFormatRequested = format;
1054
1055    // Allocate device-side stream interface
1056
1057    uint32_t id;
1058    uint32_t formatActual;
1059    uint32_t usage;
1060    uint32_t maxBuffers = 2;
1061    res = mHal2Device->ops->allocate_stream(mHal2Device,
1062            mWidth, mHeight, mFormatRequested, getStreamOps(),
1063            &id, &formatActual, &usage, &maxBuffers);
1064    if (res != OK) {
1065        ALOGE("%s: Device stream allocation failed: %s (%d)",
1066                __FUNCTION__, strerror(-res), res);
1067        return res;
1068    }
1069
1070    ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1071            "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1072            id, formatActual, usage, maxBuffers);
1073
1074    mId = id;
1075    mFormat = formatActual;
1076    mUsage = usage;
1077    mMaxProducerBuffers = maxBuffers;
1078
1079    mState = ALLOCATED;
1080
1081    // Configure consumer-side ANativeWindow interface
1082    res = native_window_api_connect(mConsumerInterface.get(),
1083            NATIVE_WINDOW_API_CAMERA);
1084    if (res != OK) {
1085        ALOGE("%s: Unable to connect to native window for stream %d",
1086                __FUNCTION__, mId);
1087
1088        return res;
1089    }
1090
1091    mState = CONNECTED;
1092
1093    res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1094    if (res != OK) {
1095        ALOGE("%s: Unable to configure usage %08x for stream %d",
1096                __FUNCTION__, mUsage, mId);
1097        return res;
1098    }
1099
1100    res = native_window_set_scaling_mode(mConsumerInterface.get(),
1101            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1102    if (res != OK) {
1103        ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1104                __FUNCTION__, strerror(-res), res);
1105        return res;
1106    }
1107
1108    res = setTransform(0);
1109    if (res != OK) {
1110        return res;
1111    }
1112
1113    if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1114        res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1115                mSize, 1);
1116        if (res != OK) {
1117            ALOGE("%s: Unable to configure compressed stream buffer dimensions"
1118                    " %d x %d, size %zu for stream %d",
1119                    __FUNCTION__, mWidth, mHeight, mSize, mId);
1120            return res;
1121        }
1122    } else {
1123        res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
1124                mWidth, mHeight);
1125        if (res != OK) {
1126            ALOGE("%s: Unable to configure stream buffer dimensions"
1127                    " %d x %d for stream %d",
1128                    __FUNCTION__, mWidth, mHeight, mId);
1129            return res;
1130        }
1131    }
1132
1133    res = native_window_set_buffers_format(mConsumerInterface.get(), mFormat);
1134    if (res != OK) {
1135        ALOGE("%s: Unable to configure stream buffer format"
1136                " %#x for stream %d",
1137                __FUNCTION__, mFormat, mId);
1138        return res;
1139    }
1140
1141    int maxConsumerBuffers;
1142    res = mConsumerInterface->query(mConsumerInterface.get(),
1143            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1144    if (res != OK) {
1145        ALOGE("%s: Unable to query consumer undequeued"
1146                " buffer count for stream %d", __FUNCTION__, mId);
1147        return res;
1148    }
1149    mMaxConsumerBuffers = maxConsumerBuffers;
1150
1151    ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1152            mMaxConsumerBuffers);
1153
1154    mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1155    mActiveBuffers = 0;
1156    mFrameCount = 0;
1157    mLastTimestamp = 0;
1158
1159    res = native_window_set_buffer_count(mConsumerInterface.get(),
1160            mTotalBuffers);
1161    if (res != OK) {
1162        ALOGE("%s: Unable to set buffer count for stream %d",
1163                __FUNCTION__, mId);
1164        return res;
1165    }
1166
1167    // Register allocated buffers with HAL device
1168    buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1169    ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1170    uint32_t bufferIdx = 0;
1171    for (; bufferIdx < mTotalBuffers; bufferIdx++) {
1172        res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
1173                &anwBuffers[bufferIdx]);
1174        if (res != OK) {
1175            ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
1176                    "stream %d", __FUNCTION__, bufferIdx, mId);
1177            goto cleanUpBuffers;
1178        }
1179
1180        buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
1181        ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
1182    }
1183
1184    ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
1185    res = mHal2Device->ops->register_stream_buffers(mHal2Device,
1186            mId,
1187            mTotalBuffers,
1188            buffers);
1189    if (res != OK) {
1190        ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1191                __FUNCTION__, mId);
1192    } else {
1193        mState = ACTIVE;
1194    }
1195
1196cleanUpBuffers:
1197    ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
1198    for (uint32_t i = 0; i < bufferIdx; i++) {
1199        res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
1200                anwBuffers[i], -1);
1201        if (res != OK) {
1202            ALOGE("%s: Unable to cancel buffer %d after registration",
1203                    __FUNCTION__, i);
1204        }
1205    }
1206    delete[] anwBuffers;
1207    delete[] buffers;
1208
1209    return res;
1210}
1211
1212status_t Camera2Device::StreamAdapter::release() {
1213    ATRACE_CALL();
1214    status_t res;
1215    ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1216            mWidth, mHeight, mFormat);
1217    if (mState >= ALLOCATED) {
1218        res = mHal2Device->ops->release_stream(mHal2Device, mId);
1219        if (res != OK) {
1220            ALOGE("%s: Unable to release stream %d",
1221                    __FUNCTION__, mId);
1222            return res;
1223        }
1224    }
1225    if (mState >= CONNECTED) {
1226        res = native_window_api_disconnect(mConsumerInterface.get(),
1227                NATIVE_WINDOW_API_CAMERA);
1228
1229        /* this is not an error. if client calling process dies,
1230           the window will also die and all calls to it will return
1231           DEAD_OBJECT, thus it's already "disconnected" */
1232        if (res == DEAD_OBJECT) {
1233            ALOGW("%s: While disconnecting stream %d from native window, the"
1234                  " native window died from under us", __FUNCTION__, mId);
1235        }
1236        else if (res != OK) {
1237            ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1238                    __FUNCTION__, mId, res, strerror(-res));
1239            return res;
1240        }
1241    }
1242    mId = -1;
1243    mState = RELEASED;
1244    return OK;
1245}
1246
1247status_t Camera2Device::StreamAdapter::setTransform(int transform) {
1248    ATRACE_CALL();
1249    status_t res;
1250    if (mState < CONNECTED) {
1251        ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1252        return INVALID_OPERATION;
1253    }
1254    res = native_window_set_buffers_transform(mConsumerInterface.get(),
1255                                              transform);
1256    if (res != OK) {
1257        ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1258                __FUNCTION__, transform, strerror(-res), res);
1259    }
1260    return res;
1261}
1262
1263status_t Camera2Device::StreamAdapter::dump(int fd,
1264        const Vector<String16>& /*args*/) {
1265    ATRACE_CALL();
1266    String8 result = String8::format("      Stream %d: %d x %d, format 0x%x\n",
1267            mId, mWidth, mHeight, mFormat);
1268    result.appendFormat("        size %zu, usage 0x%x, requested format 0x%x\n",
1269            mSize, mUsage, mFormatRequested);
1270    result.appendFormat("        total buffers: %d, dequeued buffers: %d\n",
1271            mTotalBuffers, mActiveBuffers);
1272    result.appendFormat("        frame count: %d, last timestamp %" PRId64 "\n",
1273            mFrameCount, mLastTimestamp);
1274    write(fd, result.string(), result.size());
1275    return OK;
1276}
1277
1278const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1279    return static_cast<camera2_stream_ops *>(this);
1280}
1281
1282ANativeWindow* Camera2Device::StreamAdapter::toANW(
1283        const camera2_stream_ops_t *w) {
1284    return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1285}
1286
1287int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1288        buffer_handle_t** buffer) {
1289    ATRACE_CALL();
1290    int res;
1291    StreamAdapter* stream =
1292            const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1293    if (stream->mState != ACTIVE) {
1294        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1295        return INVALID_OPERATION;
1296    }
1297
1298    ANativeWindow *a = toANW(w);
1299    ANativeWindowBuffer* anb;
1300    res = native_window_dequeue_buffer_and_wait(a, &anb);
1301    if (res != OK) {
1302        ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1303                strerror(-res), res);
1304        return res;
1305    }
1306
1307    *buffer = &(anb->handle);
1308    stream->mActiveBuffers++;
1309
1310    ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
1311    return res;
1312}
1313
1314int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1315        int64_t timestamp,
1316        buffer_handle_t* buffer) {
1317    ATRACE_CALL();
1318    StreamAdapter *stream =
1319            const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1320    stream->mFrameCount++;
1321    ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
1322            stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
1323    int state = stream->mState;
1324    if (state != ACTIVE) {
1325        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1326        return INVALID_OPERATION;
1327    }
1328    ANativeWindow *a = toANW(w);
1329    status_t err;
1330
1331    err = native_window_set_buffers_timestamp(a, timestamp);
1332    if (err != OK) {
1333        ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1334                __FUNCTION__, strerror(-err), err);
1335        return err;
1336    }
1337    err = a->queueBuffer(a,
1338            container_of(buffer, ANativeWindowBuffer, handle), -1);
1339    if (err != OK) {
1340        ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1341                __FUNCTION__, strerror(-err), err);
1342        return err;
1343    }
1344
1345    stream->mActiveBuffers--;
1346    stream->mLastTimestamp = timestamp;
1347    return OK;
1348}
1349
1350int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1351        buffer_handle_t* buffer) {
1352    ATRACE_CALL();
1353    StreamAdapter *stream =
1354            const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1355    ALOGVV("Stream %d cancel: Buffer %p",
1356            stream->mId, (void*)(*buffer));
1357    if (stream->mState != ACTIVE) {
1358        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1359        return INVALID_OPERATION;
1360    }
1361
1362    ANativeWindow *a = toANW(w);
1363    int err = a->cancelBuffer(a,
1364            container_of(buffer, ANativeWindowBuffer, handle), -1);
1365    if (err != OK) {
1366        ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1367                __FUNCTION__, strerror(-err), err);
1368        return err;
1369    }
1370
1371    stream->mActiveBuffers--;
1372    return OK;
1373}
1374
1375int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1376        int left, int top, int right, int bottom) {
1377    ATRACE_CALL();
1378    int state = static_cast<const StreamAdapter*>(w)->mState;
1379    if (state != ACTIVE) {
1380        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1381        return INVALID_OPERATION;
1382    }
1383    ANativeWindow *a = toANW(w);
1384    android_native_rect_t crop = { left, top, right, bottom };
1385    return native_window_set_crop(a, &crop);
1386}
1387
1388/**
1389 * Camera2Device::ReprocessStreamAdapter
1390 */
1391
1392#ifndef container_of
1393#define container_of(ptr, type, member) \
1394    (type *)((char*)(ptr) - offsetof(type, member))
1395#endif
1396
1397Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1398        mState(RELEASED),
1399        mHal2Device(d),
1400        mId(-1),
1401        mWidth(0), mHeight(0), mFormat(0),
1402        mActiveBuffers(0),
1403        mFrameCount(0)
1404{
1405    ATRACE_CALL();
1406    camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1407    camera2_stream_in_ops::release_buffer = release_buffer;
1408}
1409
1410Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
1411    ATRACE_CALL();
1412    if (mState != RELEASED) {
1413        release();
1414    }
1415}
1416
1417status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1418        const sp<StreamAdapter> &outputStream) {
1419    ATRACE_CALL();
1420    status_t res;
1421    ALOGV("%s: E", __FUNCTION__);
1422
1423    if (mState != RELEASED) return INVALID_OPERATION;
1424    if (outputStream == NULL) {
1425        ALOGE("%s: Null base stream passed to reprocess stream adapter",
1426                __FUNCTION__);
1427        return BAD_VALUE;
1428    }
1429
1430    mBaseStream = outputStream;
1431    mWidth = outputStream->getWidth();
1432    mHeight = outputStream->getHeight();
1433    mFormat = outputStream->getFormat();
1434
1435    ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1436            __FUNCTION__, mWidth, mHeight, mFormat);
1437
1438    // Allocate device-side stream interface
1439
1440    uint32_t id;
1441    res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
1442            outputStream->getId(), getStreamOps(),
1443            &id);
1444    if (res != OK) {
1445        ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1446                __FUNCTION__, strerror(-res), res);
1447        return res;
1448    }
1449
1450    ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1451            __FUNCTION__, id, outputStream->getId());
1452
1453    mId = id;
1454
1455    mState = ACTIVE;
1456
1457    return OK;
1458}
1459
1460status_t Camera2Device::ReprocessStreamAdapter::release() {
1461    ATRACE_CALL();
1462    status_t res;
1463    ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1464    if (mState >= ACTIVE) {
1465        res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
1466        if (res != OK) {
1467            ALOGE("%s: Unable to release stream %d",
1468                    __FUNCTION__, mId);
1469            return res;
1470        }
1471    }
1472
1473    List<QueueEntry>::iterator s;
1474    for (s = mQueue.begin(); s != mQueue.end(); s++) {
1475        sp<BufferReleasedListener> listener = s->releaseListener.promote();
1476        if (listener != 0) listener->onBufferReleased(s->handle);
1477    }
1478    for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1479        sp<BufferReleasedListener> listener = s->releaseListener.promote();
1480        if (listener != 0) listener->onBufferReleased(s->handle);
1481    }
1482    mQueue.clear();
1483    mInFlightQueue.clear();
1484
1485    mState = RELEASED;
1486    return OK;
1487}
1488
1489status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1490    buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
1491    ATRACE_CALL();
1492    // TODO: Some error checking here would be nice
1493    ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1494
1495    QueueEntry entry;
1496    entry.handle = handle;
1497    entry.releaseListener = releaseListener;
1498    mQueue.push_back(entry);
1499    return OK;
1500}
1501
1502status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
1503        const Vector<String16>& /*args*/) {
1504    ATRACE_CALL();
1505    String8 result =
1506            String8::format("      Reprocess stream %d: %d x %d, fmt 0x%x\n",
1507                    mId, mWidth, mHeight, mFormat);
1508    result.appendFormat("        acquired buffers: %d\n",
1509            mActiveBuffers);
1510    result.appendFormat("        frame count: %d\n",
1511            mFrameCount);
1512    write(fd, result.string(), result.size());
1513    return OK;
1514}
1515
1516const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1517    return static_cast<camera2_stream_in_ops *>(this);
1518}
1519
1520int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1521    const camera2_stream_in_ops_t *w,
1522        buffer_handle_t** buffer) {
1523    ATRACE_CALL();
1524
1525    ReprocessStreamAdapter* stream =
1526            const_cast<ReprocessStreamAdapter*>(
1527                static_cast<const ReprocessStreamAdapter*>(w));
1528    if (stream->mState != ACTIVE) {
1529        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1530        return INVALID_OPERATION;
1531    }
1532
1533    if (stream->mQueue.empty()) {
1534        *buffer = NULL;
1535        return OK;
1536    }
1537
1538    QueueEntry &entry = *(stream->mQueue.begin());
1539
1540    *buffer = entry.handle;
1541
1542    stream->mInFlightQueue.push_back(entry);
1543    stream->mQueue.erase(stream->mQueue.begin());
1544
1545    stream->mActiveBuffers++;
1546
1547    ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1548            (void*)(**buffer));
1549    return OK;
1550}
1551
1552int Camera2Device::ReprocessStreamAdapter::release_buffer(
1553    const camera2_stream_in_ops_t* w,
1554    buffer_handle_t* buffer) {
1555    ATRACE_CALL();
1556    ReprocessStreamAdapter *stream =
1557            const_cast<ReprocessStreamAdapter*>(
1558                static_cast<const ReprocessStreamAdapter*>(w) );
1559    stream->mFrameCount++;
1560    ALOGV("Reprocess stream %d release: Frame %d (%p)",
1561            stream->mId, stream->mFrameCount, (void*)*buffer);
1562    int state = stream->mState;
1563    if (state != ACTIVE) {
1564        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1565        return INVALID_OPERATION;
1566    }
1567    stream->mActiveBuffers--;
1568
1569    List<QueueEntry>::iterator s;
1570    for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1571        if ( s->handle == buffer ) break;
1572    }
1573    if (s == stream->mInFlightQueue.end()) {
1574        ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1575                buffer);
1576        return INVALID_OPERATION;
1577    }
1578
1579    sp<BufferReleasedListener> listener = s->releaseListener.promote();
1580    if (listener != 0) {
1581        listener->onBufferReleased(s->handle);
1582    } else {
1583        ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1584    }
1585    stream->mInFlightQueue.erase(s);
1586
1587    return OK;
1588}
1589
1590// camera 2 devices don't support reprocessing
1591status_t Camera2Device::createInputStream(
1592    uint32_t width, uint32_t height, int format, int *id) {
1593    ALOGE("%s: camera 2 devices don't support reprocessing", __FUNCTION__);
1594    return INVALID_OPERATION;
1595}
1596
1597// camera 2 devices don't support reprocessing
1598status_t Camera2Device::getInputBufferProducer(
1599        sp<IGraphicBufferProducer> *producer) {
1600    ALOGE("%s: camera 2 devices don't support reprocessing", __FUNCTION__);
1601    return INVALID_OPERATION;
1602}
1603
1604}; // namespace android
1605