Camera2Device.cpp revision f1e98d857ec377f2c9b916073d40732e6ebb7ced
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                // TODO: Only needed for camera2 API, which is unsupported
468                // by HAL2 directly.
469                // nsecs_t timestamp = (nsecs_t)ext2 | ((nsecs_t)(ext3) << 32 );
470                // listener->notifyShutter(requestId, timestamp);
471                break;
472            }
473            case CAMERA2_MSG_AUTOFOCUS:
474                listener->notifyAutoFocus(ext1, ext2);
475                break;
476            case CAMERA2_MSG_AUTOEXPOSURE:
477                listener->notifyAutoExposure(ext1, ext2);
478                break;
479            case CAMERA2_MSG_AUTOWB:
480                listener->notifyAutoWhitebalance(ext1, ext2);
481                break;
482            default:
483                ALOGE("%s: Unknown notification %d (arguments %d, %d, %d)!",
484                        __FUNCTION__, msg_type, ext1, ext2, ext3);
485        }
486    }
487}
488
489status_t Camera2Device::waitForNextFrame(nsecs_t timeout) {
490    return mFrameQueue.waitForBuffer(timeout);
491}
492
493status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
494    ATRACE_CALL();
495    status_t res;
496    camera_metadata_t *rawFrame;
497    res = mFrameQueue.dequeue(&rawFrame);
498    if (rawFrame  == NULL) {
499        return NOT_ENOUGH_DATA;
500    } else if (res == OK) {
501        frame->acquire(rawFrame);
502    }
503    return res;
504}
505
506status_t Camera2Device::triggerAutofocus(uint32_t id) {
507    ATRACE_CALL();
508    status_t res;
509    ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
510    res = mHal2Device->ops->trigger_action(mHal2Device,
511            CAMERA2_TRIGGER_AUTOFOCUS, id, 0);
512    if (res != OK) {
513        ALOGE("%s: Error triggering autofocus (id %d)",
514                __FUNCTION__, id);
515    }
516    return res;
517}
518
519status_t Camera2Device::triggerCancelAutofocus(uint32_t id) {
520    ATRACE_CALL();
521    status_t res;
522    ALOGV("%s: Canceling autofocus, id %d", __FUNCTION__, id);
523    res = mHal2Device->ops->trigger_action(mHal2Device,
524            CAMERA2_TRIGGER_CANCEL_AUTOFOCUS, id, 0);
525    if (res != OK) {
526        ALOGE("%s: Error canceling autofocus (id %d)",
527                __FUNCTION__, id);
528    }
529    return res;
530}
531
532status_t Camera2Device::triggerPrecaptureMetering(uint32_t id) {
533    ATRACE_CALL();
534    status_t res;
535    ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
536    res = mHal2Device->ops->trigger_action(mHal2Device,
537            CAMERA2_TRIGGER_PRECAPTURE_METERING, id, 0);
538    if (res != OK) {
539        ALOGE("%s: Error triggering precapture metering (id %d)",
540                __FUNCTION__, id);
541    }
542    return res;
543}
544
545status_t Camera2Device::pushReprocessBuffer(int reprocessStreamId,
546        buffer_handle_t *buffer, wp<BufferReleasedListener> listener) {
547    ATRACE_CALL();
548    ALOGV("%s: E", __FUNCTION__);
549    bool found = false;
550    status_t res = OK;
551    for (ReprocessStreamList::iterator streamI = mReprocessStreams.begin();
552         streamI != mReprocessStreams.end(); streamI++) {
553        if ((*streamI)->getId() == reprocessStreamId) {
554            res = (*streamI)->pushIntoStream(buffer, listener);
555            if (res != OK) {
556                ALOGE("%s: Unable to push buffer to reprocess stream %d: %s (%d)",
557                        __FUNCTION__, reprocessStreamId, strerror(-res), res);
558                return res;
559            }
560            found = true;
561            break;
562        }
563    }
564    if (!found) {
565        ALOGE("%s: Camera %d: Unable to find reprocess stream %d",
566                __FUNCTION__, mId, reprocessStreamId);
567        res = BAD_VALUE;
568    }
569    return res;
570}
571
572status_t Camera2Device::flush() {
573    ATRACE_CALL();
574
575    mRequestQueue.clear();
576    return waitUntilDrained();
577}
578
579/**
580 * Camera2Device::MetadataQueue
581 */
582
583Camera2Device::MetadataQueue::MetadataQueue():
584            mHal2Device(NULL),
585            mFrameCount(0),
586            mLatestRequestId(0),
587            mCount(0),
588            mStreamSlotCount(0),
589            mSignalConsumer(true)
590{
591    ATRACE_CALL();
592    camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
593    camera2_request_queue_src_ops::request_count = consumer_buffer_count;
594    camera2_request_queue_src_ops::free_request = consumer_free;
595
596    camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
597    camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
598    camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
599}
600
601Camera2Device::MetadataQueue::~MetadataQueue() {
602    ATRACE_CALL();
603    clear();
604}
605
606// Connect to camera2 HAL as consumer (input requests/reprocessing)
607status_t Camera2Device::MetadataQueue::setConsumerDevice(camera2_device_t *d) {
608    ATRACE_CALL();
609    status_t res;
610    res = d->ops->set_request_queue_src_ops(d,
611            this);
612    if (res != OK) return res;
613    mHal2Device = d;
614    return OK;
615}
616
617status_t Camera2Device::MetadataQueue::setProducerDevice(camera2_device_t *d) {
618    ATRACE_CALL();
619    status_t res;
620    res = d->ops->set_frame_queue_dst_ops(d,
621            this);
622    return res;
623}
624
625// Real interfaces
626status_t Camera2Device::MetadataQueue::enqueue(camera_metadata_t *buf) {
627    ATRACE_CALL();
628    ALOGVV("%s: E", __FUNCTION__);
629    Mutex::Autolock l(mMutex);
630
631    mCount++;
632    mEntries.push_back(buf);
633
634    return signalConsumerLocked();
635}
636
637int Camera2Device::MetadataQueue::getBufferCount() {
638    ATRACE_CALL();
639    Mutex::Autolock l(mMutex);
640    if (mStreamSlotCount > 0) {
641        return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
642    }
643    return mCount;
644}
645
646status_t Camera2Device::MetadataQueue::dequeue(camera_metadata_t **buf,
647        bool incrementCount)
648{
649    ATRACE_CALL();
650    ALOGVV("%s: E", __FUNCTION__);
651    status_t res;
652    Mutex::Autolock l(mMutex);
653
654    if (mCount == 0) {
655        if (mStreamSlotCount == 0) {
656            ALOGVV("%s: Empty", __FUNCTION__);
657            *buf = NULL;
658            mSignalConsumer = true;
659            return OK;
660        }
661        ALOGVV("%s: Streaming %d frames to queue", __FUNCTION__,
662              mStreamSlotCount);
663
664        for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
665                slotEntry != mStreamSlot.end();
666                slotEntry++ ) {
667            size_t entries = get_camera_metadata_entry_count(*slotEntry);
668            size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
669
670            camera_metadata_t *copy =
671                    allocate_camera_metadata(entries, dataBytes);
672            append_camera_metadata(copy, *slotEntry);
673            mEntries.push_back(copy);
674        }
675        mCount = mStreamSlotCount;
676    }
677    ALOGVV("MetadataQueue: deque (%d buffers)", mCount);
678    camera_metadata_t *b = *(mEntries.begin());
679    mEntries.erase(mEntries.begin());
680
681    if (incrementCount) {
682        ATRACE_INT("cam2_request", mFrameCount);
683        camera_metadata_entry_t frameCount;
684        res = find_camera_metadata_entry(b,
685                ANDROID_REQUEST_FRAME_COUNT,
686                &frameCount);
687        if (res != OK) {
688            ALOGE("%s: Unable to add frame count: %s (%d)",
689                    __FUNCTION__, strerror(-res), res);
690        } else {
691            *frameCount.data.i32 = mFrameCount;
692        }
693        mFrameCount++;
694    }
695
696    // Check for request ID, and if present, signal waiters.
697    camera_metadata_entry_t requestId;
698    res = find_camera_metadata_entry(b,
699            ANDROID_REQUEST_ID,
700            &requestId);
701    if (res == OK) {
702        mLatestRequestId = requestId.data.i32[0];
703        mNewRequestId.signal();
704    }
705
706    *buf = b;
707    mCount--;
708
709    return OK;
710}
711
712status_t Camera2Device::MetadataQueue::waitForBuffer(nsecs_t timeout)
713{
714    Mutex::Autolock l(mMutex);
715    status_t res;
716    while (mCount == 0) {
717        res = notEmpty.waitRelative(mMutex,timeout);
718        if (res != OK) return res;
719    }
720    return OK;
721}
722
723status_t Camera2Device::MetadataQueue::waitForDequeue(int32_t id,
724        nsecs_t timeout) {
725    Mutex::Autolock l(mMutex);
726    status_t res;
727    while (mLatestRequestId != id) {
728        nsecs_t startTime = systemTime();
729
730        res = mNewRequestId.waitRelative(mMutex, timeout);
731        if (res != OK) return res;
732
733        timeout -= (systemTime() - startTime);
734    }
735
736    return OK;
737}
738
739status_t Camera2Device::MetadataQueue::setStreamSlot(camera_metadata_t *buf)
740{
741    ATRACE_CALL();
742    ALOGV("%s: E", __FUNCTION__);
743    Mutex::Autolock l(mMutex);
744    if (buf == NULL) {
745        freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
746        mStreamSlotCount = 0;
747        return OK;
748    }
749    camera_metadata_t *buf2 = clone_camera_metadata(buf);
750    if (!buf2) {
751        ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
752        return NO_MEMORY;
753    }
754
755    if (mStreamSlotCount > 1) {
756        List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
757        freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
758        mStreamSlotCount = 1;
759    }
760    if (mStreamSlotCount == 1) {
761        free_camera_metadata( *(mStreamSlot.begin()) );
762        *(mStreamSlot.begin()) = buf2;
763    } else {
764        mStreamSlot.push_front(buf2);
765        mStreamSlotCount = 1;
766    }
767    return signalConsumerLocked();
768}
769
770status_t Camera2Device::MetadataQueue::setStreamSlot(
771        const List<camera_metadata_t*> &bufs)
772{
773    ATRACE_CALL();
774    ALOGV("%s: E", __FUNCTION__);
775    Mutex::Autolock l(mMutex);
776
777    if (mStreamSlotCount > 0) {
778        freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
779    }
780    mStreamSlotCount = 0;
781    for (List<camera_metadata_t*>::const_iterator r = bufs.begin();
782         r != bufs.end(); r++) {
783        camera_metadata_t *r2 = clone_camera_metadata(*r);
784        if (!r2) {
785            ALOGE("%s: Unable to clone metadata buffer!", __FUNCTION__);
786            return NO_MEMORY;
787        }
788        mStreamSlot.push_back(r2);
789        mStreamSlotCount++;
790    }
791    return signalConsumerLocked();
792}
793
794status_t Camera2Device::MetadataQueue::clear()
795{
796    ATRACE_CALL();
797    ALOGV("%s: E", __FUNCTION__);
798
799    Mutex::Autolock l(mMutex);
800
801    // Clear streaming slot
802    freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
803    mStreamSlotCount = 0;
804
805    // Clear request queue
806    freeBuffers(mEntries.begin(), mEntries.end());
807    mCount = 0;
808    return OK;
809}
810
811status_t Camera2Device::MetadataQueue::dump(int fd,
812        const Vector<String16>& /*args*/) {
813    ATRACE_CALL();
814    String8 result;
815    status_t notLocked;
816    notLocked = mMutex.tryLock();
817    if (notLocked) {
818        result.append("    (Unable to lock queue mutex)\n");
819    }
820    result.appendFormat("      Current frame number: %d\n", mFrameCount);
821    if (mStreamSlotCount == 0) {
822        result.append("      Stream slot: Empty\n");
823        write(fd, result.string(), result.size());
824    } else {
825        result.appendFormat("      Stream slot: %d entries\n",
826                mStreamSlot.size());
827        int i = 0;
828        for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
829             r != mStreamSlot.end(); r++) {
830            result = String8::format("       Stream slot buffer %d:\n", i);
831            write(fd, result.string(), result.size());
832            dump_indented_camera_metadata(*r, fd, 2, 10);
833            i++;
834        }
835    }
836    if (mEntries.size() == 0) {
837        result = "      Main queue is empty\n";
838        write(fd, result.string(), result.size());
839    } else {
840        result = String8::format("      Main queue has %d entries:\n",
841                mEntries.size());
842        int i = 0;
843        for (List<camera_metadata_t*>::iterator r = mEntries.begin();
844             r != mEntries.end(); r++) {
845            result = String8::format("       Queue entry %d:\n", i);
846            write(fd, result.string(), result.size());
847            dump_indented_camera_metadata(*r, fd, 2, 10);
848            i++;
849        }
850    }
851
852    if (notLocked == 0) {
853        mMutex.unlock();
854    }
855
856    return OK;
857}
858
859status_t Camera2Device::MetadataQueue::signalConsumerLocked() {
860    ATRACE_CALL();
861    status_t res = OK;
862    notEmpty.signal();
863    if (mSignalConsumer && mHal2Device != NULL) {
864        mSignalConsumer = false;
865
866        mMutex.unlock();
867        ALOGV("%s: Signaling consumer", __FUNCTION__);
868        res = mHal2Device->ops->notify_request_queue_not_empty(mHal2Device);
869        mMutex.lock();
870    }
871    return res;
872}
873
874status_t Camera2Device::MetadataQueue::freeBuffers(
875        List<camera_metadata_t*>::iterator start,
876        List<camera_metadata_t*>::iterator end)
877{
878    ATRACE_CALL();
879    while (start != end) {
880        free_camera_metadata(*start);
881        start = mStreamSlot.erase(start);
882    }
883    return OK;
884}
885
886Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
887        const camera2_request_queue_src_ops_t *q)
888{
889    const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
890    return const_cast<MetadataQueue*>(cmq);
891}
892
893Camera2Device::MetadataQueue* Camera2Device::MetadataQueue::getInstance(
894        const camera2_frame_queue_dst_ops_t *q)
895{
896    const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
897    return const_cast<MetadataQueue*>(cmq);
898}
899
900int Camera2Device::MetadataQueue::consumer_buffer_count(
901        const camera2_request_queue_src_ops_t *q)
902{
903    MetadataQueue *queue = getInstance(q);
904    return queue->getBufferCount();
905}
906
907int Camera2Device::MetadataQueue::consumer_dequeue(
908        const camera2_request_queue_src_ops_t *q,
909        camera_metadata_t **buffer)
910{
911    MetadataQueue *queue = getInstance(q);
912    return queue->dequeue(buffer, true);
913}
914
915int Camera2Device::MetadataQueue::consumer_free(
916        const camera2_request_queue_src_ops_t *q,
917        camera_metadata_t *old_buffer)
918{
919    ATRACE_CALL();
920    MetadataQueue *queue = getInstance(q);
921    (void)queue;
922    free_camera_metadata(old_buffer);
923    return OK;
924}
925
926int Camera2Device::MetadataQueue::producer_dequeue(
927        const camera2_frame_queue_dst_ops_t * /*q*/,
928        size_t entries, size_t bytes,
929        camera_metadata_t **buffer)
930{
931    ATRACE_CALL();
932    camera_metadata_t *new_buffer =
933            allocate_camera_metadata(entries, bytes);
934    if (new_buffer == NULL) return NO_MEMORY;
935    *buffer = new_buffer;
936        return OK;
937}
938
939int Camera2Device::MetadataQueue::producer_cancel(
940        const camera2_frame_queue_dst_ops_t * /*q*/,
941        camera_metadata_t *old_buffer)
942{
943    ATRACE_CALL();
944    free_camera_metadata(old_buffer);
945    return OK;
946}
947
948int Camera2Device::MetadataQueue::producer_enqueue(
949        const camera2_frame_queue_dst_ops_t *q,
950        camera_metadata_t *filled_buffer)
951{
952    MetadataQueue *queue = getInstance(q);
953    return queue->enqueue(filled_buffer);
954}
955
956/**
957 * Camera2Device::StreamAdapter
958 */
959
960#ifndef container_of
961#define container_of(ptr, type, member) \
962    (type *)((char*)(ptr) - offsetof(type, member))
963#endif
964
965Camera2Device::StreamAdapter::StreamAdapter(camera2_device_t *d):
966        mState(RELEASED),
967        mHal2Device(d),
968        mId(-1),
969        mWidth(0), mHeight(0), mFormat(0), mSize(0), mUsage(0),
970        mMaxProducerBuffers(0), mMaxConsumerBuffers(0),
971        mTotalBuffers(0),
972        mFormatRequested(0),
973        mActiveBuffers(0),
974        mFrameCount(0),
975        mLastTimestamp(0)
976{
977    camera2_stream_ops::dequeue_buffer = dequeue_buffer;
978    camera2_stream_ops::enqueue_buffer = enqueue_buffer;
979    camera2_stream_ops::cancel_buffer = cancel_buffer;
980    camera2_stream_ops::set_crop = set_crop;
981}
982
983Camera2Device::StreamAdapter::~StreamAdapter() {
984    ATRACE_CALL();
985    if (mState != RELEASED) {
986        release();
987    }
988}
989
990status_t Camera2Device::StreamAdapter::connectToDevice(
991        sp<ANativeWindow> consumer,
992        uint32_t width, uint32_t height, int format, size_t size) {
993    ATRACE_CALL();
994    status_t res;
995    ALOGV("%s: E", __FUNCTION__);
996
997    if (mState != RELEASED) return INVALID_OPERATION;
998    if (consumer == NULL) {
999        ALOGE("%s: Null consumer passed to stream adapter", __FUNCTION__);
1000        return BAD_VALUE;
1001    }
1002
1003    ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
1004            __FUNCTION__, width, height, format, size);
1005
1006    mConsumerInterface = consumer;
1007    mWidth = width;
1008    mHeight = height;
1009    mSize = (format == HAL_PIXEL_FORMAT_BLOB) ? size : 0;
1010    mFormatRequested = format;
1011
1012    // Allocate device-side stream interface
1013
1014    uint32_t id;
1015    uint32_t formatActual;
1016    uint32_t usage;
1017    uint32_t maxBuffers = 2;
1018    res = mHal2Device->ops->allocate_stream(mHal2Device,
1019            mWidth, mHeight, mFormatRequested, getStreamOps(),
1020            &id, &formatActual, &usage, &maxBuffers);
1021    if (res != OK) {
1022        ALOGE("%s: Device stream allocation failed: %s (%d)",
1023                __FUNCTION__, strerror(-res), res);
1024        return res;
1025    }
1026
1027    ALOGV("%s: Allocated stream id %d, actual format 0x%x, "
1028            "usage 0x%x, producer wants %d buffers", __FUNCTION__,
1029            id, formatActual, usage, maxBuffers);
1030
1031    mId = id;
1032    mFormat = formatActual;
1033    mUsage = usage;
1034    mMaxProducerBuffers = maxBuffers;
1035
1036    mState = ALLOCATED;
1037
1038    // Configure consumer-side ANativeWindow interface
1039    res = native_window_api_connect(mConsumerInterface.get(),
1040            NATIVE_WINDOW_API_CAMERA);
1041    if (res != OK) {
1042        ALOGE("%s: Unable to connect to native window for stream %d",
1043                __FUNCTION__, mId);
1044
1045        return res;
1046    }
1047
1048    mState = CONNECTED;
1049
1050    res = native_window_set_usage(mConsumerInterface.get(), mUsage);
1051    if (res != OK) {
1052        ALOGE("%s: Unable to configure usage %08x for stream %d",
1053                __FUNCTION__, mUsage, mId);
1054        return res;
1055    }
1056
1057    res = native_window_set_scaling_mode(mConsumerInterface.get(),
1058            NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
1059    if (res != OK) {
1060        ALOGE("%s: Unable to configure stream scaling: %s (%d)",
1061                __FUNCTION__, strerror(-res), res);
1062        return res;
1063    }
1064
1065    res = setTransform(0);
1066    if (res != OK) {
1067        return res;
1068    }
1069
1070    if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
1071        res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1072                mSize, 1, mFormat);
1073        if (res != OK) {
1074            ALOGE("%s: Unable to configure compressed stream buffer geometry"
1075                    " %d x %d, size %d for stream %d",
1076                    __FUNCTION__, mWidth, mHeight, mSize, mId);
1077            return res;
1078        }
1079    } else {
1080        res = native_window_set_buffers_geometry(mConsumerInterface.get(),
1081                mWidth, mHeight, mFormat);
1082        if (res != OK) {
1083            ALOGE("%s: Unable to configure stream buffer geometry"
1084                    " %d x %d, format 0x%x for stream %d",
1085                    __FUNCTION__, mWidth, mHeight, mFormat, mId);
1086            return res;
1087        }
1088    }
1089
1090    int maxConsumerBuffers;
1091    res = mConsumerInterface->query(mConsumerInterface.get(),
1092            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
1093    if (res != OK) {
1094        ALOGE("%s: Unable to query consumer undequeued"
1095                " buffer count for stream %d", __FUNCTION__, mId);
1096        return res;
1097    }
1098    mMaxConsumerBuffers = maxConsumerBuffers;
1099
1100    ALOGV("%s: Consumer wants %d buffers", __FUNCTION__,
1101            mMaxConsumerBuffers);
1102
1103    mTotalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
1104    mActiveBuffers = 0;
1105    mFrameCount = 0;
1106    mLastTimestamp = 0;
1107
1108    res = native_window_set_buffer_count(mConsumerInterface.get(),
1109            mTotalBuffers);
1110    if (res != OK) {
1111        ALOGE("%s: Unable to set buffer count for stream %d",
1112                __FUNCTION__, mId);
1113        return res;
1114    }
1115
1116    // Register allocated buffers with HAL device
1117    buffer_handle_t *buffers = new buffer_handle_t[mTotalBuffers];
1118    ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[mTotalBuffers];
1119    uint32_t bufferIdx = 0;
1120    for (; bufferIdx < mTotalBuffers; bufferIdx++) {
1121        res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
1122                &anwBuffers[bufferIdx]);
1123        if (res != OK) {
1124            ALOGE("%s: Unable to dequeue buffer %d for initial registration for "
1125                    "stream %d", __FUNCTION__, bufferIdx, mId);
1126            goto cleanUpBuffers;
1127        }
1128
1129        buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
1130        ALOGV("%s: Buffer %p allocated", __FUNCTION__, (void*)buffers[bufferIdx]);
1131    }
1132
1133    ALOGV("%s: Registering %d buffers with camera HAL", __FUNCTION__, mTotalBuffers);
1134    res = mHal2Device->ops->register_stream_buffers(mHal2Device,
1135            mId,
1136            mTotalBuffers,
1137            buffers);
1138    if (res != OK) {
1139        ALOGE("%s: Unable to register buffers with HAL device for stream %d",
1140                __FUNCTION__, mId);
1141    } else {
1142        mState = ACTIVE;
1143    }
1144
1145cleanUpBuffers:
1146    ALOGV("%s: Cleaning up %d buffers", __FUNCTION__, bufferIdx);
1147    for (uint32_t i = 0; i < bufferIdx; i++) {
1148        res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
1149                anwBuffers[i], -1);
1150        if (res != OK) {
1151            ALOGE("%s: Unable to cancel buffer %d after registration",
1152                    __FUNCTION__, i);
1153        }
1154    }
1155    delete[] anwBuffers;
1156    delete[] buffers;
1157
1158    return res;
1159}
1160
1161status_t Camera2Device::StreamAdapter::release() {
1162    ATRACE_CALL();
1163    status_t res;
1164    ALOGV("%s: Releasing stream %d (%d x %d, format %d)", __FUNCTION__, mId,
1165            mWidth, mHeight, mFormat);
1166    if (mState >= ALLOCATED) {
1167        res = mHal2Device->ops->release_stream(mHal2Device, mId);
1168        if (res != OK) {
1169            ALOGE("%s: Unable to release stream %d",
1170                    __FUNCTION__, mId);
1171            return res;
1172        }
1173    }
1174    if (mState >= CONNECTED) {
1175        res = native_window_api_disconnect(mConsumerInterface.get(),
1176                NATIVE_WINDOW_API_CAMERA);
1177
1178        /* this is not an error. if client calling process dies,
1179           the window will also die and all calls to it will return
1180           DEAD_OBJECT, thus it's already "disconnected" */
1181        if (res == DEAD_OBJECT) {
1182            ALOGW("%s: While disconnecting stream %d from native window, the"
1183                  " native window died from under us", __FUNCTION__, mId);
1184        }
1185        else if (res != OK) {
1186            ALOGE("%s: Unable to disconnect stream %d from native window (error %d %s)",
1187                    __FUNCTION__, mId, res, strerror(-res));
1188            return res;
1189        }
1190    }
1191    mId = -1;
1192    mState = RELEASED;
1193    return OK;
1194}
1195
1196status_t Camera2Device::StreamAdapter::setTransform(int transform) {
1197    ATRACE_CALL();
1198    status_t res;
1199    if (mState < CONNECTED) {
1200        ALOGE("%s: Cannot set transform on unconnected stream", __FUNCTION__);
1201        return INVALID_OPERATION;
1202    }
1203    res = native_window_set_buffers_transform(mConsumerInterface.get(),
1204                                              transform);
1205    if (res != OK) {
1206        ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
1207                __FUNCTION__, transform, strerror(-res), res);
1208    }
1209    return res;
1210}
1211
1212status_t Camera2Device::StreamAdapter::dump(int fd,
1213        const Vector<String16>& /*args*/) {
1214    ATRACE_CALL();
1215    String8 result = String8::format("      Stream %d: %d x %d, format 0x%x\n",
1216            mId, mWidth, mHeight, mFormat);
1217    result.appendFormat("        size %d, usage 0x%x, requested format 0x%x\n",
1218            mSize, mUsage, mFormatRequested);
1219    result.appendFormat("        total buffers: %d, dequeued buffers: %d\n",
1220            mTotalBuffers, mActiveBuffers);
1221    result.appendFormat("        frame count: %d, last timestamp %lld\n",
1222            mFrameCount, mLastTimestamp);
1223    write(fd, result.string(), result.size());
1224    return OK;
1225}
1226
1227const camera2_stream_ops *Camera2Device::StreamAdapter::getStreamOps() {
1228    return static_cast<camera2_stream_ops *>(this);
1229}
1230
1231ANativeWindow* Camera2Device::StreamAdapter::toANW(
1232        const camera2_stream_ops_t *w) {
1233    return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
1234}
1235
1236int Camera2Device::StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
1237        buffer_handle_t** buffer) {
1238    ATRACE_CALL();
1239    int res;
1240    StreamAdapter* stream =
1241            const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1242    if (stream->mState != ACTIVE) {
1243        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1244        return INVALID_OPERATION;
1245    }
1246
1247    ANativeWindow *a = toANW(w);
1248    ANativeWindowBuffer* anb;
1249    res = native_window_dequeue_buffer_and_wait(a, &anb);
1250    if (res != OK) {
1251        ALOGE("Stream %d dequeue: Error from native_window: %s (%d)", stream->mId,
1252                strerror(-res), res);
1253        return res;
1254    }
1255
1256    *buffer = &(anb->handle);
1257    stream->mActiveBuffers++;
1258
1259    ALOGVV("Stream %d dequeue: Buffer %p dequeued", stream->mId, (void*)(**buffer));
1260    return res;
1261}
1262
1263int Camera2Device::StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
1264        int64_t timestamp,
1265        buffer_handle_t* buffer) {
1266    ATRACE_CALL();
1267    StreamAdapter *stream =
1268            const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1269    stream->mFrameCount++;
1270    ALOGVV("Stream %d enqueue: Frame %d (%p) captured at %lld ns",
1271            stream->mId, stream->mFrameCount, (void*)(*buffer), timestamp);
1272    int state = stream->mState;
1273    if (state != ACTIVE) {
1274        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1275        return INVALID_OPERATION;
1276    }
1277    ANativeWindow *a = toANW(w);
1278    status_t err;
1279
1280    err = native_window_set_buffers_timestamp(a, timestamp);
1281    if (err != OK) {
1282        ALOGE("%s: Error setting timestamp on native window: %s (%d)",
1283                __FUNCTION__, strerror(-err), err);
1284        return err;
1285    }
1286    err = a->queueBuffer(a,
1287            container_of(buffer, ANativeWindowBuffer, handle), -1);
1288    if (err != OK) {
1289        ALOGE("%s: Error queueing buffer to native window: %s (%d)",
1290                __FUNCTION__, strerror(-err), err);
1291        return err;
1292    }
1293
1294    stream->mActiveBuffers--;
1295    stream->mLastTimestamp = timestamp;
1296    return OK;
1297}
1298
1299int Camera2Device::StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
1300        buffer_handle_t* buffer) {
1301    ATRACE_CALL();
1302    StreamAdapter *stream =
1303            const_cast<StreamAdapter*>(static_cast<const StreamAdapter*>(w));
1304    ALOGVV("Stream %d cancel: Buffer %p",
1305            stream->mId, (void*)(*buffer));
1306    if (stream->mState != ACTIVE) {
1307        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1308        return INVALID_OPERATION;
1309    }
1310
1311    ANativeWindow *a = toANW(w);
1312    int err = a->cancelBuffer(a,
1313            container_of(buffer, ANativeWindowBuffer, handle), -1);
1314    if (err != OK) {
1315        ALOGE("%s: Error canceling buffer to native window: %s (%d)",
1316                __FUNCTION__, strerror(-err), err);
1317        return err;
1318    }
1319
1320    stream->mActiveBuffers--;
1321    return OK;
1322}
1323
1324int Camera2Device::StreamAdapter::set_crop(const camera2_stream_ops_t* w,
1325        int left, int top, int right, int bottom) {
1326    ATRACE_CALL();
1327    int state = static_cast<const StreamAdapter*>(w)->mState;
1328    if (state != ACTIVE) {
1329        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1330        return INVALID_OPERATION;
1331    }
1332    ANativeWindow *a = toANW(w);
1333    android_native_rect_t crop = { left, top, right, bottom };
1334    return native_window_set_crop(a, &crop);
1335}
1336
1337/**
1338 * Camera2Device::ReprocessStreamAdapter
1339 */
1340
1341#ifndef container_of
1342#define container_of(ptr, type, member) \
1343    (type *)((char*)(ptr) - offsetof(type, member))
1344#endif
1345
1346Camera2Device::ReprocessStreamAdapter::ReprocessStreamAdapter(camera2_device_t *d):
1347        mState(RELEASED),
1348        mHal2Device(d),
1349        mId(-1),
1350        mWidth(0), mHeight(0), mFormat(0),
1351        mActiveBuffers(0),
1352        mFrameCount(0)
1353{
1354    ATRACE_CALL();
1355    camera2_stream_in_ops::acquire_buffer = acquire_buffer;
1356    camera2_stream_in_ops::release_buffer = release_buffer;
1357}
1358
1359Camera2Device::ReprocessStreamAdapter::~ReprocessStreamAdapter() {
1360    ATRACE_CALL();
1361    if (mState != RELEASED) {
1362        release();
1363    }
1364}
1365
1366status_t Camera2Device::ReprocessStreamAdapter::connectToDevice(
1367        const sp<StreamAdapter> &outputStream) {
1368    ATRACE_CALL();
1369    status_t res;
1370    ALOGV("%s: E", __FUNCTION__);
1371
1372    if (mState != RELEASED) return INVALID_OPERATION;
1373    if (outputStream == NULL) {
1374        ALOGE("%s: Null base stream passed to reprocess stream adapter",
1375                __FUNCTION__);
1376        return BAD_VALUE;
1377    }
1378
1379    mBaseStream = outputStream;
1380    mWidth = outputStream->getWidth();
1381    mHeight = outputStream->getHeight();
1382    mFormat = outputStream->getFormat();
1383
1384    ALOGV("%s: New reprocess stream parameters %d x %d, format 0x%x",
1385            __FUNCTION__, mWidth, mHeight, mFormat);
1386
1387    // Allocate device-side stream interface
1388
1389    uint32_t id;
1390    res = mHal2Device->ops->allocate_reprocess_stream_from_stream(mHal2Device,
1391            outputStream->getId(), getStreamOps(),
1392            &id);
1393    if (res != OK) {
1394        ALOGE("%s: Device reprocess stream allocation failed: %s (%d)",
1395                __FUNCTION__, strerror(-res), res);
1396        return res;
1397    }
1398
1399    ALOGV("%s: Allocated reprocess stream id %d based on stream %d",
1400            __FUNCTION__, id, outputStream->getId());
1401
1402    mId = id;
1403
1404    mState = ACTIVE;
1405
1406    return OK;
1407}
1408
1409status_t Camera2Device::ReprocessStreamAdapter::release() {
1410    ATRACE_CALL();
1411    status_t res;
1412    ALOGV("%s: Releasing stream %d", __FUNCTION__, mId);
1413    if (mState >= ACTIVE) {
1414        res = mHal2Device->ops->release_reprocess_stream(mHal2Device, mId);
1415        if (res != OK) {
1416            ALOGE("%s: Unable to release stream %d",
1417                    __FUNCTION__, mId);
1418            return res;
1419        }
1420    }
1421
1422    List<QueueEntry>::iterator s;
1423    for (s = mQueue.begin(); s != mQueue.end(); s++) {
1424        sp<BufferReleasedListener> listener = s->releaseListener.promote();
1425        if (listener != 0) listener->onBufferReleased(s->handle);
1426    }
1427    for (s = mInFlightQueue.begin(); s != mInFlightQueue.end(); s++) {
1428        sp<BufferReleasedListener> listener = s->releaseListener.promote();
1429        if (listener != 0) listener->onBufferReleased(s->handle);
1430    }
1431    mQueue.clear();
1432    mInFlightQueue.clear();
1433
1434    mState = RELEASED;
1435    return OK;
1436}
1437
1438status_t Camera2Device::ReprocessStreamAdapter::pushIntoStream(
1439    buffer_handle_t *handle, const wp<BufferReleasedListener> &releaseListener) {
1440    ATRACE_CALL();
1441    // TODO: Some error checking here would be nice
1442    ALOGV("%s: Pushing buffer %p to stream", __FUNCTION__, (void*)(*handle));
1443
1444    QueueEntry entry;
1445    entry.handle = handle;
1446    entry.releaseListener = releaseListener;
1447    mQueue.push_back(entry);
1448    return OK;
1449}
1450
1451status_t Camera2Device::ReprocessStreamAdapter::dump(int fd,
1452        const Vector<String16>& /*args*/) {
1453    ATRACE_CALL();
1454    String8 result =
1455            String8::format("      Reprocess stream %d: %d x %d, fmt 0x%x\n",
1456                    mId, mWidth, mHeight, mFormat);
1457    result.appendFormat("        acquired buffers: %d\n",
1458            mActiveBuffers);
1459    result.appendFormat("        frame count: %d\n",
1460            mFrameCount);
1461    write(fd, result.string(), result.size());
1462    return OK;
1463}
1464
1465const camera2_stream_in_ops *Camera2Device::ReprocessStreamAdapter::getStreamOps() {
1466    return static_cast<camera2_stream_in_ops *>(this);
1467}
1468
1469int Camera2Device::ReprocessStreamAdapter::acquire_buffer(
1470    const camera2_stream_in_ops_t *w,
1471        buffer_handle_t** buffer) {
1472    ATRACE_CALL();
1473
1474    ReprocessStreamAdapter* stream =
1475            const_cast<ReprocessStreamAdapter*>(
1476                static_cast<const ReprocessStreamAdapter*>(w));
1477    if (stream->mState != ACTIVE) {
1478        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, stream->mState);
1479        return INVALID_OPERATION;
1480    }
1481
1482    if (stream->mQueue.empty()) {
1483        *buffer = NULL;
1484        return OK;
1485    }
1486
1487    QueueEntry &entry = *(stream->mQueue.begin());
1488
1489    *buffer = entry.handle;
1490
1491    stream->mInFlightQueue.push_back(entry);
1492    stream->mQueue.erase(stream->mQueue.begin());
1493
1494    stream->mActiveBuffers++;
1495
1496    ALOGV("Stream %d acquire: Buffer %p acquired", stream->mId,
1497            (void*)(**buffer));
1498    return OK;
1499}
1500
1501int Camera2Device::ReprocessStreamAdapter::release_buffer(
1502    const camera2_stream_in_ops_t* w,
1503    buffer_handle_t* buffer) {
1504    ATRACE_CALL();
1505    ReprocessStreamAdapter *stream =
1506            const_cast<ReprocessStreamAdapter*>(
1507                static_cast<const ReprocessStreamAdapter*>(w) );
1508    stream->mFrameCount++;
1509    ALOGV("Reprocess stream %d release: Frame %d (%p)",
1510            stream->mId, stream->mFrameCount, (void*)*buffer);
1511    int state = stream->mState;
1512    if (state != ACTIVE) {
1513        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
1514        return INVALID_OPERATION;
1515    }
1516    stream->mActiveBuffers--;
1517
1518    List<QueueEntry>::iterator s;
1519    for (s = stream->mInFlightQueue.begin(); s != stream->mInFlightQueue.end(); s++) {
1520        if ( s->handle == buffer ) break;
1521    }
1522    if (s == stream->mInFlightQueue.end()) {
1523        ALOGE("%s: Can't find buffer %p in in-flight list!", __FUNCTION__,
1524                buffer);
1525        return INVALID_OPERATION;
1526    }
1527
1528    sp<BufferReleasedListener> listener = s->releaseListener.promote();
1529    if (listener != 0) {
1530        listener->onBufferReleased(s->handle);
1531    } else {
1532        ALOGE("%s: Can't free buffer - missing listener", __FUNCTION__);
1533    }
1534    stream->mInFlightQueue.erase(s);
1535
1536    return OK;
1537}
1538
1539}; // namespace android
1540