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