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