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