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