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