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
218be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala#include <utils/Log.h>
228be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala#include <utils/Trace.h>
238be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala#include "Camera3ZslStream.h"
248be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
25ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkintypedef android::RingBufferConsumer::PinnedBufferItem PinnedBufferItem;
26ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
278be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvalanamespace android {
288be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
298be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvalanamespace camera3 {
308be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
31ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkinnamespace {
32ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkinstruct TimestampFinder : public RingBufferConsumer::RingBufferComparator {
33ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    typedef RingBufferConsumer::BufferInfo BufferInfo;
34ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
35ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    enum {
36ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        SELECT_I1 = -1,
37ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        SELECT_I2 = 1,
38ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        SELECT_NEITHER = 0,
39ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    };
40ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
41ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    TimestampFinder(nsecs_t timestamp) : mTimestamp(timestamp) {}
42ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    ~TimestampFinder() {}
43ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
44ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    template <typename T>
45ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    static void swap(T& a, T& b) {
46ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        T tmp = a;
47ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        a = b;
48ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        b = tmp;
49ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
50ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
51ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    /**
52ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * Try to find the best candidate for a ZSL buffer.
53ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * Match priority from best to worst:
54ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     *  1) Timestamps match.
55ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     *  2) Timestamp is closest to the needle (and lower).
56ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     *  3) Timestamp is closest to the needle (and higher).
57ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     *
58ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     */
59ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    virtual int compare(const BufferInfo *i1,
60ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                        const BufferInfo *i2) const {
61ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Try to select non-null object first.
62ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (i1 == NULL) {
63ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return SELECT_I2;
64ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        } else if (i2 == NULL) {
65ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return SELECT_I1;
66ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
67ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
68ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Best result: timestamp is identical
69ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (i1->mTimestamp == mTimestamp) {
70ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return SELECT_I1;
71ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        } else if (i2->mTimestamp == mTimestamp) {
72ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return SELECT_I2;
73ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
74ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
75ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        const BufferInfo* infoPtrs[2] = {
76ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            i1,
77ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            i2
78ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        };
79ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        int infoSelectors[2] = {
80ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            SELECT_I1,
81ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            SELECT_I2
82ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        };
83ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
84ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Order i1,i2 so that always i1.timestamp < i2.timestamp
85ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (i1->mTimestamp > i2->mTimestamp) {
86ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            swap(infoPtrs[0], infoPtrs[1]);
87ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            swap(infoSelectors[0], infoSelectors[1]);
88ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
89ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
90ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Second best: closest (lower) timestamp
91ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (infoPtrs[1]->mTimestamp < mTimestamp) {
92ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return infoSelectors[1];
93ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        } else if (infoPtrs[0]->mTimestamp < mTimestamp) {
94ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return infoSelectors[0];
95ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
96ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
97ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Worst: closest (higher) timestamp
98ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        return infoSelectors[0];
99ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
100ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        /**
101ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         * The above cases should cover all the possibilities,
102ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         * and we get an 'empty' result only if the ring buffer
103ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         * was empty itself
104ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         */
105ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
106ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
107ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    const nsecs_t mTimestamp;
108ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin}; // struct TimestampFinder
109ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin} // namespace anonymous
110ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
1118be20f50711a94426f1394ec113672e41c1224e8Eino-Ville TalvalaCamera3ZslStream::Camera3ZslStream(int id, uint32_t width, uint32_t height,
1128be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala        int depth) :
113ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin        Camera3OutputStream(id, CAMERA3_STREAM_BIDIRECTIONAL,
114ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                            width, height,
115ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                            HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED),
116deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian        mDepth(depth) {
117ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
118deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    sp<BufferQueue> bq = new BufferQueue();
119deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    mProducer = new RingBufferConsumer(bq, GRALLOC_USAGE_HW_CAMERA_ZSL, depth);
120deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    mConsumer = new Surface(bq);
1218be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}
1228be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
123ae3d0babb9c5d68b107b53d5a67193309020c556Igor MurashkinCamera3ZslStream::~Camera3ZslStream() {
1248be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}
1258be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
126ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkinstatus_t Camera3ZslStream::getInputBufferLocked(camera3_stream_buffer *buffer) {
127ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    ATRACE_CALL();
128ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
129ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    status_t res;
130ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
131ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    // TODO: potentially register from inputBufferLocked
132ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    // this should be ok, registerBuffersLocked only calls getBuffer for now
133ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    // register in output mode instead of input mode for ZSL streams.
134ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (mState == STATE_IN_CONFIG || mState == STATE_IN_RECONFIG) {
135ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        ALOGE("%s: Stream %d: Buffer registration for input streams"
136ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin              " not implemented (state %d)",
137ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin              __FUNCTION__, mId, mState);
138ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        return INVALID_OPERATION;
139ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
140ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
141ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    if ((res = getBufferPreconditionCheckLocked()) != OK) {
142ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin        return res;
143ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
144ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
145ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    ANativeWindowBuffer* anb;
146ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    int fenceFd;
147ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
148ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    assert(mProducer != 0);
149ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
150ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    sp<PinnedBufferItem> bufferItem;
151ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    {
152ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        List<sp<RingBufferConsumer::PinnedBufferItem> >::iterator it, end;
153ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        it = mInputBufferQueue.begin();
154ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        end = mInputBufferQueue.end();
155ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
156ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Need to call enqueueInputBufferByTimestamp as a prerequisite
157ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (it == end) {
158ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            ALOGE("%s: Stream %d: No input buffer was queued",
159ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                    __FUNCTION__, mId);
160ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            return INVALID_OPERATION;
161ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
162ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        bufferItem = *it;
163ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        mInputBufferQueue.erase(it);
164ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
165ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
166ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    anb = bufferItem->getBufferItem().mGraphicBuffer->getNativeBuffer();
167ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    assert(anb != NULL);
168ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    fenceFd = bufferItem->getBufferItem().mFence->dup();
169ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
170ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    /**
171ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * FenceFD now owned by HAL except in case of error,
172ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * in which case we reassign it to acquire_fence
173ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     */
174ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
175ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                         /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK);
176ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
177ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    mBuffersInFlight.push_back(bufferItem);
178ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
179ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    return OK;
1808be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}
1818be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
182ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkinstatus_t Camera3ZslStream::returnBufferCheckedLocked(
183ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin            const camera3_stream_buffer &buffer,
184ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin            nsecs_t timestamp,
185ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin            bool output,
186ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin            /*out*/
187ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin            sp<Fence> *releaseFenceOut) {
188ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
189ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    if (output) {
190ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin        // Output stream path
191ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin        return Camera3OutputStream::returnBufferCheckedLocked(buffer,
192ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                                                              timestamp,
193ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                                                              output,
194ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                                                              releaseFenceOut);
195ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
196ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
197ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    /**
198ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin     * Input stream path
199ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin     */
200ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    bool bufferFound = false;
201ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    sp<PinnedBufferItem> bufferItem;
202ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    {
203ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        // Find the buffer we are returning
204ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        Vector<sp<PinnedBufferItem> >::iterator it, end;
205ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        for (it = mBuffersInFlight.begin(), end = mBuffersInFlight.end();
206ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin             it != end;
207ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin             ++it) {
208ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
209ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            const sp<PinnedBufferItem>& tmp = *it;
210ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            ANativeWindowBuffer *anb =
211ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                    tmp->getBufferItem().mGraphicBuffer->getNativeBuffer();
212ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            if (anb != NULL && &(anb->handle) == buffer.buffer) {
213ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                bufferFound = true;
214ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                bufferItem = tmp;
215ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                mBuffersInFlight.erase(it);
216ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                break;
217ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            }
218ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
219ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
220ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (!bufferFound) {
221ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        ALOGE("%s: Stream %d: Can't return buffer that wasn't sent to HAL",
222ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin              __FUNCTION__, mId);
223ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        return INVALID_OPERATION;
224ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
225ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
226ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    int releaseFenceFd = buffer.release_fence;
227ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
228ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
229ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        if (buffer.release_fence != -1) {
230ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            ALOGE("%s: Stream %d: HAL should not set release_fence(%d) when "
231ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                  "there is an error", __FUNCTION__, mId, buffer.release_fence);
232ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            close(buffer.release_fence);
233ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        }
234ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
235ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        /**
236ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         * Reassign release fence as the acquire fence incase of error
237ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin         */
238ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        releaseFenceFd = buffer.acquire_fence;
239ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
240ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
241ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    /**
242ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * Unconditionally return buffer to the buffer queue.
243ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     * - Fwk takes over the release_fence ownership
244ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin     */
245ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    sp<Fence> releaseFence = new Fence(releaseFenceFd);
246ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    bufferItem->getBufferItem().mFence = releaseFence;
247ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    bufferItem.clear(); // dropping last reference unpins buffer
248ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
249ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    *releaseFenceOut = releaseFence;
250ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
251ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    return OK;
252ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin}
253ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin
254ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkinstatus_t Camera3ZslStream::returnInputBufferLocked(
255ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin        const camera3_stream_buffer &buffer) {
256ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    ATRACE_CALL();
257ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
258ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    status_t res = returnAnyBufferLocked(buffer, /*timestamp*/0,
259ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin                                         /*output*/false);
260ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin
261ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    return res;
2628be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}
2638be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
2648be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvalavoid Camera3ZslStream::dump(int fd, const Vector<String16> &args) const {
2658be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala    (void) args;
266ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
267ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    String8 lines;
268ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    lines.appendFormat("    Stream[%d]: ZSL\n", mId);
269ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    write(fd, lines.string(), lines.size());
270ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin
271ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    Camera3IOStreamBase::dump(fd, args);
272ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin
273ae3d0babb9c5d68b107b53d5a67193309020c556Igor Murashkin    lines = String8();
274ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    lines.appendFormat("      Input buffers pending: %d, in flight %d\n",
275ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            mInputBufferQueue.size(), mBuffersInFlight.size());
276ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    write(fd, lines.string(), lines.size());
277ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin}
278ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
279ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkinstatus_t Camera3ZslStream::enqueueInputBufferByTimestamp(
280ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        nsecs_t timestamp,
281ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        nsecs_t* actualTimestamp) {
282ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
283ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    Mutex::Autolock l(mLock);
284ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
285ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    TimestampFinder timestampFinder = TimestampFinder(timestamp);
286ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
287ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    sp<RingBufferConsumer::PinnedBufferItem> pinnedBuffer =
288ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin            mProducer->pinSelectedBuffer(timestampFinder,
289ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin                                        /*waitForFence*/false);
290ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
291ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (pinnedBuffer == 0) {
292ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        ALOGE("%s: No ZSL buffers were available yet", __FUNCTION__);
293ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        return NO_BUFFER_AVAILABLE;
294ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
295ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
296ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    nsecs_t actual = pinnedBuffer->getBufferItem().mTimestamp;
297ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
298ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (actual != timestamp) {
299ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        ALOGW("%s: ZSL buffer candidate search didn't find an exact match --"
300ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin              " requested timestamp = %lld, actual timestamp = %lld",
301ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin              __FUNCTION__, timestamp, actual);
302ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
303ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
304ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    mInputBufferQueue.push_back(pinnedBuffer);
305ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
306ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    if (actualTimestamp != NULL) {
307ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin        *actualTimestamp = actual;
308ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    }
309ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
310ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    return OK;
311ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin}
312ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
313ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkinstatus_t Camera3ZslStream::clearInputRingBuffer() {
314ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    Mutex::Autolock l(mLock);
315ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
316ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    mInputBufferQueue.clear();
317ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
318ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    return mProducer->clear();
319ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin}
320ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin
321ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkinstatus_t Camera3ZslStream::setTransform(int /*transform*/) {
322ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    ALOGV("%s: Not implemented", __FUNCTION__);
323ae500e53efa1d26eb7c13e62d0ecc8d75db2473aIgor Murashkin    return INVALID_OPERATION;
3248be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}
3258be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
3268be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}; // namespace camera3
3278be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala
3288be20f50711a94426f1394ec113672e41c1224e8Eino-Ville Talvala}; // namespace android
329