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