18be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala/*
28be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala * Copyright (C) 2013 The Android Open Source Project
38be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala *
48be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License");
58be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala * you may not use this file except in compliance with the License.
68be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala * You may obtain a copy of the License at
78be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala *
88be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala *      http://www.apache.org/licenses/LICENSE-2.0
98be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala *
108be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software
118be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS,
128be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala * See the License for the specific language governing permissions and
148be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala * limitations under the License.
158be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala */
168be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
178be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala#define LOG_TAG "Camera3-ZslStream"
188be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala#define ATRACE_TAG ATRACE_TAG_CAMERA
198be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala//#define LOG_NDEBUG 0
208be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
21e5729fac81c8a984e984fefc90afc64135817d4fColin Cross#include <inttypes.h>
22e5729fac81c8a984e984fefc90afc64135817d4fColin Cross
238be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala#include <utils/Log.h>
248be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala#include <utils/Trace.h>
258be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala#include "Camera3ZslStream.h"
268be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
27ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkintypedef android::RingBufferConsumer::PinnedBufferItem PinnedBufferItem;
28ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
298be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvalanamespace android {
308be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
318be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvalanamespace camera3 {
328be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
33ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkinnamespace {
34ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkinstruct TimestampFinder : public RingBufferConsumer::RingBufferComparator {
35ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    typedef RingBufferConsumer::BufferInfo BufferInfo;
36ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
37ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    enum {
38ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        SELECT_I1 = -1,
39ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        SELECT_I2 = 1,
40ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        SELECT_NEITHER = 0,
41ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    };
42ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
43ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    TimestampFinder(nsecs_t timestamp) : mTimestamp(timestamp) {}
44ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    ~TimestampFinder() {}
45ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
46ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    template <typename T>
47ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    static void swap(T& a, T& b) {
48ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        T tmp = a;
49ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        a = b;
50ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        b = tmp;
51ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
52ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
53ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    /**
54ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * Try to find the best candidate for a ZSL buffer.
55ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * Match priority from best to worst:
56ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     *  1) Timestamps match.
57ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     *  2) Timestamp is closest to the needle (and lower).
58ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     *  3) Timestamp is closest to the needle (and higher).
59ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     *
60ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     */
61ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    virtual int compare(const BufferInfo *i1,
62ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                        const BufferInfo *i2) const {
63ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Try to select non-null object first.
64ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (i1 == NULL) {
65ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return SELECT_I2;
66ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        } else if (i2 == NULL) {
67ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return SELECT_I1;
68ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
69ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
70ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Best result: timestamp is identical
71ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (i1->mTimestamp == mTimestamp) {
72ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return SELECT_I1;
73ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        } else if (i2->mTimestamp == mTimestamp) {
74ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return SELECT_I2;
75ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
76ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
77ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        const BufferInfo* infoPtrs[2] = {
78ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            i1,
79ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            i2
80ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        };
81ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        int infoSelectors[2] = {
82ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            SELECT_I1,
83ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            SELECT_I2
84ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        };
85ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
86ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Order i1,i2 so that always i1.timestamp < i2.timestamp
87ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (i1->mTimestamp > i2->mTimestamp) {
88ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            swap(infoPtrs[0], infoPtrs[1]);
89ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            swap(infoSelectors[0], infoSelectors[1]);
90ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
91ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
92ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Second best: closest (lower) timestamp
93ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (infoPtrs[1]->mTimestamp < mTimestamp) {
94ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return infoSelectors[1];
95ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        } else if (infoPtrs[0]->mTimestamp < mTimestamp) {
96ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return infoSelectors[0];
97ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
98ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
99ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Worst: closest (higher) timestamp
100ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        return infoSelectors[0];
101ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
102ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        /**
103ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         * The above cases should cover all the possibilities,
104ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         * and we get an 'empty' result only if the ring buffer
105ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         * was empty itself
106ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         */
107ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
108ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
109ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    const nsecs_t mTimestamp;
110ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin}; // struct TimestampFinder
111ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin} // namespace anonymous
112ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
1138be20f50711a94426f1394ec113672e41c1224e8Eino-Ville TalvalaCamera3ZslStream::Camera3ZslStream(int id, uint32_t width, uint32_t height,
114054aab3479a094b0a04d48db9cb8f325ea5be162Igor Murashkin        int bufferCount) :
115ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin        Camera3OutputStream(id, CAMERA3_STREAM_BIDIRECTIONAL,
116ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                            width, height,
117ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED),
118054aab3479a094b0a04d48db9cb8f325ea5be162Igor Murashkin        mDepth(bufferCount) {
119ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
1208aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza    sp<IGraphicBufferProducer> producer;
1218aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza    sp<IGraphicBufferConsumer> consumer;
1228aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
1238aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza    mProducer = new RingBufferConsumer(consumer, GRALLOC_USAGE_HW_CAMERA_ZSL, bufferCount);
1248aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza    mConsumer = new Surface(producer);
1258be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}
1268be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
127ae3d0babb9c5d68b107b53d5a67193309020c556Igor MurashkinCamera3ZslStream::~Camera3ZslStream() {
1288be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}
1298be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
130ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkinstatus_t Camera3ZslStream::getInputBufferLocked(camera3_stream_buffer *buffer) {
131ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    ATRACE_CALL();
132ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
133ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    status_t res;
134ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
135ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    // TODO: potentially register from inputBufferLocked
136ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    // this should be ok, registerBuffersLocked only calls getBuffer for now
137ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    // register in output mode instead of input mode for ZSL streams.
138ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (mState == STATE_IN_CONFIG || mState == STATE_IN_RECONFIG) {
139ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        ALOGE("%s: Stream %d: Buffer registration for input streams"
140ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin              " not implemented (state %d)",
141ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin              __FUNCTION__, mId, mState);
142ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        return INVALID_OPERATION;
143ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
144ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
145ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    if ((res = getBufferPreconditionCheckLocked()) != OK) {
146ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin        return res;
147ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
148ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
149ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    ANativeWindowBuffer* anb;
150ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    int fenceFd;
151ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
152ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    assert(mProducer != 0);
153ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
154ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    sp<PinnedBufferItem> bufferItem;
155ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    {
156ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        List<sp<RingBufferConsumer::PinnedBufferItem> >::iterator it, end;
157ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        it = mInputBufferQueue.begin();
158ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        end = mInputBufferQueue.end();
159ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
160ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Need to call enqueueInputBufferByTimestamp as a prerequisite
161ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (it == end) {
162ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            ALOGE("%s: Stream %d: No input buffer was queued",
163ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                    __FUNCTION__, mId);
164ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return INVALID_OPERATION;
165ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
166ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        bufferItem = *it;
167ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        mInputBufferQueue.erase(it);
168ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
169ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
170ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    anb = bufferItem->getBufferItem().mGraphicBuffer->getNativeBuffer();
171ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    assert(anb != NULL);
172ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    fenceFd = bufferItem->getBufferItem().mFence->dup();
173ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
174ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    /**
175ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * FenceFD now owned by HAL except in case of error,
176ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * in which case we reassign it to acquire_fence
177ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     */
178ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
1796adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                         /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/false);
180ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
181ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    mBuffersInFlight.push_back(bufferItem);
182ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
183ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    return OK;
1848be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}
1858be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
186ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkinstatus_t Camera3ZslStream::returnBufferCheckedLocked(
187ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin            const camera3_stream_buffer &buffer,
188ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin            nsecs_t timestamp,
189ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin            bool output,
190ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin            /*out*/
191ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin            sp<Fence> *releaseFenceOut) {
192ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
193ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    if (output) {
194ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin        // Output stream path
195ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin        return Camera3OutputStream::returnBufferCheckedLocked(buffer,
196ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                                                              timestamp,
197ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                                                              output,
198ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                                                              releaseFenceOut);
199ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
200ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
201ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    /**
202ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin     * Input stream path
203ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin     */
204ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    bool bufferFound = false;
205ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    sp<PinnedBufferItem> bufferItem;
206ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    {
207ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Find the buffer we are returning
208ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        Vector<sp<PinnedBufferItem> >::iterator it, end;
209ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        for (it = mBuffersInFlight.begin(), end = mBuffersInFlight.end();
210ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin             it != end;
211ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin             ++it) {
212ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
213ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            const sp<PinnedBufferItem>& tmp = *it;
214ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            ANativeWindowBuffer *anb =
215ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                    tmp->getBufferItem().mGraphicBuffer->getNativeBuffer();
216ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            if (anb != NULL && &(anb->handle) == buffer.buffer) {
217ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                bufferFound = true;
218ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                bufferItem = tmp;
219ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                mBuffersInFlight.erase(it);
220ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                break;
221ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            }
222ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
223ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
224ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (!bufferFound) {
225ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        ALOGE("%s: Stream %d: Can't return buffer that wasn't sent to HAL",
226ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin              __FUNCTION__, mId);
227ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        return INVALID_OPERATION;
228ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
229ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
230ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    int releaseFenceFd = buffer.release_fence;
231ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
232ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
233ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (buffer.release_fence != -1) {
234ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            ALOGE("%s: Stream %d: HAL should not set release_fence(%d) when "
235ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                  "there is an error", __FUNCTION__, mId, buffer.release_fence);
236ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            close(buffer.release_fence);
237ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
238ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
239ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        /**
240ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         * Reassign release fence as the acquire fence incase of error
241ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         */
242ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        releaseFenceFd = buffer.acquire_fence;
243ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
244ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
245ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    /**
246ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * Unconditionally return buffer to the buffer queue.
247ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * - Fwk takes over the release_fence ownership
248ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     */
249ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    sp<Fence> releaseFence = new Fence(releaseFenceFd);
250ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    bufferItem->getBufferItem().mFence = releaseFence;
251ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    bufferItem.clear(); // dropping last reference unpins buffer
252ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
253ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    *releaseFenceOut = releaseFence;
254ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
255ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    return OK;
256ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin}
257ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin
258ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkinstatus_t Camera3ZslStream::returnInputBufferLocked(
259ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin        const camera3_stream_buffer &buffer) {
260ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    ATRACE_CALL();
261ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
262ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    status_t res = returnAnyBufferLocked(buffer, /*timestamp*/0,
263ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                                         /*output*/false);
264ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin
265ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    return res;
2668be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}
2678be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
2688be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvalavoid Camera3ZslStream::dump(int fd, const Vector<String16> &args) const {
2698be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala    (void) args;
270ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
271ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    String8 lines;
272ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    lines.appendFormat("    Stream[%d]: ZSL\n", mId);
273ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    write(fd, lines.string(), lines.size());
274ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin
275ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    Camera3IOStreamBase::dump(fd, args);
276ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin
277ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    lines = String8();
278377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT    lines.appendFormat("      Input buffers pending: %zu, in flight %zu\n",
279ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            mInputBufferQueue.size(), mBuffersInFlight.size());
280ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    write(fd, lines.string(), lines.size());
281ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin}
282ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
283ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkinstatus_t Camera3ZslStream::enqueueInputBufferByTimestamp(
284ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        nsecs_t timestamp,
285ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        nsecs_t* actualTimestamp) {
286ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
287ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    Mutex::Autolock l(mLock);
288ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
289ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    TimestampFinder timestampFinder = TimestampFinder(timestamp);
290ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
291ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    sp<RingBufferConsumer::PinnedBufferItem> pinnedBuffer =
292ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            mProducer->pinSelectedBuffer(timestampFinder,
293ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                                        /*waitForFence*/false);
294ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
295ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (pinnedBuffer == 0) {
296ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        ALOGE("%s: No ZSL buffers were available yet", __FUNCTION__);
297ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        return NO_BUFFER_AVAILABLE;
298ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
299ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
300ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    nsecs_t actual = pinnedBuffer->getBufferItem().mTimestamp;
301ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
302ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (actual != timestamp) {
303f0d962a6737eb8eec002d6804d9ffbe7bee672a0Zhijun He        // TODO: this is problematic, we'll end up with using wrong result for this pinned buffer.
304ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        ALOGW("%s: ZSL buffer candidate search didn't find an exact match --"
305e5729fac81c8a984e984fefc90afc64135817d4fColin Cross              " requested timestamp = %" PRId64 ", actual timestamp = %" PRId64,
306ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin              __FUNCTION__, timestamp, actual);
307ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
308ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
309ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    mInputBufferQueue.push_back(pinnedBuffer);
310ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
311ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (actualTimestamp != NULL) {
312ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        *actualTimestamp = actual;
313ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
314ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
315ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    return OK;
316ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin}
317ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
3186b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yehstatus_t Camera3ZslStream::clearInputRingBuffer(nsecs_t* latestTimestamp) {
319ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    Mutex::Autolock l(mLock);
320ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
3216b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh    return clearInputRingBufferLocked(latestTimestamp);
3220a21051b91c2e07e49eb6fa568c505aee967ab9dZhijun He}
3230a21051b91c2e07e49eb6fa568c505aee967ab9dZhijun He
3246b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yehstatus_t Camera3ZslStream::clearInputRingBufferLocked(nsecs_t* latestTimestamp) {
3256b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh
3266b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh    if (latestTimestamp) {
3276b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh        *latestTimestamp = mProducer->getLatestTimestamp();
3286b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh    }
329ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    mInputBufferQueue.clear();
330ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
331ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    return mProducer->clear();
332ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin}
333ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
3340a21051b91c2e07e49eb6fa568c505aee967ab9dZhijun Hestatus_t Camera3ZslStream::disconnectLocked() {
3356b7a2294b9e4da784cfe4b562ee1720ad606c852Yin-Chia Yeh    clearInputRingBufferLocked(NULL);
3360a21051b91c2e07e49eb6fa568c505aee967ab9dZhijun He
3370a21051b91c2e07e49eb6fa568c505aee967ab9dZhijun He    return Camera3OutputStream::disconnectLocked();
3380a21051b91c2e07e49eb6fa568c505aee967ab9dZhijun He}
3390a21051b91c2e07e49eb6fa568c505aee967ab9dZhijun He
340ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkinstatus_t Camera3ZslStream::setTransform(int /*transform*/) {
341ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    ALOGV("%s: Not implemented", __FUNCTION__);
342ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    return INVALID_OPERATION;
3438be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}
3448be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
3458be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}; // namespace camera3
3468be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
3478be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}; // namespace android
348