Camera3IOStreamBase.cpp revision e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefd
1e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin/*
2e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin * Copyright (C) 2013 The Android Open Source Project
3e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin *
4e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin * Licensed under the Apache License, Version 2.0 (the "License");
5e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin * you may not use this file except in compliance with the License.
6e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin * You may obtain a copy of the License at
7e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin *
8e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin *      http://www.apache.org/licenses/LICENSE-2.0
9e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin *
10e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin * Unless required by applicable law or agreed to in writing, software
11e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin * distributed under the License is distributed on an "AS IS" BASIS,
12e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin * See the License for the specific language governing permissions and
14e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin * limitations under the License.
15e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin */
16e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
17e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin#define LOG_TAG "Camera3-IOStreamBase"
18e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin#define ATRACE_TAG ATRACE_TAG_CAMERA
19e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin//#define LOG_NDEBUG 0
20e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
21e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin// This is needed for stdint.h to define INT64_MAX in C++
22e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin#define __STDC_LIMIT_MACROS
23e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
24e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin#include <utils/Log.h>
25e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin#include <utils/Trace.h>
26e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin#include "Camera3IOStreamBase.h"
27e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
28e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinnamespace android {
29e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
30e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinnamespace camera3 {
31e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
32e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor MurashkinCamera3IOStreamBase::Camera3IOStreamBase(int id, camera3_stream_type_t type,
33e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        uint32_t width, uint32_t height, size_t maxSize, int format) :
34e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        Camera3Stream(id, type,
35e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                width, height, maxSize, format),
36e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mTotalBufferCount(0),
37e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mDequeuedBufferCount(0),
38e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mFrameCount(0),
39e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mLastTimestamp(0) {
40e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
41e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mCombinedFence = new Fence();
42e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
43e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (maxSize > 0 && format != HAL_PIXEL_FORMAT_BLOB) {
44e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
45e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                format);
46e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mState = STATE_ERROR;
47e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
48e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
49e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
50e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor MurashkinCamera3IOStreamBase::~Camera3IOStreamBase() {
51e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    disconnectLocked();
52e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
53e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
54e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinbool Camera3IOStreamBase::hasOutstandingBuffersLocked() const {
55e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    nsecs_t signalTime = mCombinedFence->getSignalTime();
56e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    ALOGV("%s: Stream %d: Has %d outstanding buffers,"
57e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            " buffer signal time is %lld",
58e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            __FUNCTION__, mId, mDequeuedBufferCount, signalTime);
59e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mDequeuedBufferCount > 0 || signalTime == INT64_MAX) {
60e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return true;
61e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
62e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return false;
63e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
64e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
65e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::waitUntilIdle(nsecs_t timeout) {
66e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
67e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    {
68e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        Mutex::Autolock l(mLock);
69e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        while (mDequeuedBufferCount > 0) {
70e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            if (timeout != TIMEOUT_NEVER) {
71e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                nsecs_t startTime = systemTime();
72e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                res = mBufferReturnedSignal.waitRelative(mLock, timeout);
73e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                if (res == TIMED_OUT) {
74e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                    return res;
75e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                } else if (res != OK) {
76e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                    ALOGE("%s: Error waiting for outstanding buffers: %s (%d)",
77e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                            __FUNCTION__, strerror(-res), res);
78e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                    return res;
79e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                }
80e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                nsecs_t deltaTime = systemTime() - startTime;
81e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                if (timeout <= deltaTime) {
82e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                    timeout = 0;
83e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                } else {
84e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                    timeout -= deltaTime;
85e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                }
86e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            } else {
87e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                res = mBufferReturnedSignal.wait(mLock);
88e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                if (res != OK) {
89e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                    ALOGE("%s: Error waiting for outstanding buffers: %s (%d)",
90e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                            __FUNCTION__, strerror(-res), res);
91e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                    return res;
92e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                }
93e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            }
94e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        }
95e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
96e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
97e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // No lock
98e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
99e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    unsigned int timeoutMs;
100e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (timeout == TIMEOUT_NEVER) {
101e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        timeoutMs = Fence::TIMEOUT_NEVER;
102e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    } else if (timeout == 0) {
103e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        timeoutMs = 0;
104e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    } else {
105e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        // Round up to wait at least 1 ms
106e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        timeoutMs = (timeout + 999999) / 1000000;
107e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
108e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
109e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return mCombinedFence->wait(timeoutMs);
110e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
111e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
112e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinvoid Camera3IOStreamBase::dump(int fd, const Vector<String16> &args) const {
113e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    (void) args;
114e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    String8 lines;
115e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    lines.appendFormat("      State: %d\n", mState);
116e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    lines.appendFormat("      Dims: %d x %d, format 0x%x\n",
117e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            camera3_stream::width, camera3_stream::height,
118e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            camera3_stream::format);
119e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    lines.appendFormat("      Max size: %d\n", mMaxSize);
120e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    lines.appendFormat("      Usage: %d, max HAL buffers: %d\n",
121e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            camera3_stream::usage, camera3_stream::max_buffers);
122e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    lines.appendFormat("      Frames produced: %d, last timestamp: %lld ns\n",
123e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            mFrameCount, mLastTimestamp);
124e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    lines.appendFormat("      Total buffers: %d, currently dequeued: %d\n",
125e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            mTotalBufferCount, mDequeuedBufferCount);
126e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    write(fd, lines.string(), lines.size());
127e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
128e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
129e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::configureQueueLocked() {
130e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
131e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
132e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    switch (mState) {
133e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_RECONFIG:
134e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            res = disconnectLocked();
135e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            if (res != OK) {
136e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                return res;
137e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            }
138e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
139e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_CONFIG:
140e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // OK
141e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
142e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        default:
143e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            ALOGE("%s: Bad state: %d", __FUNCTION__, mState);
144e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            return INVALID_OPERATION;
145e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
146e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
147e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
148e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
149e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
150e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinsize_t Camera3IOStreamBase::getBufferCountLocked() {
151e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return mTotalBufferCount;
152e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
153e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
154e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::disconnectLocked() {
155e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    switch (mState) {
156e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_RECONFIG:
157e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_CONFIGURED:
158e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // OK
159e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
160e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        default:
161e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // No connection, nothing to do
162e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            return OK;
163e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
164e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
165e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mDequeuedBufferCount > 0) {
166e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Can't disconnect with %d buffers still dequeued!",
167e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                __FUNCTION__, mDequeuedBufferCount);
168e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
169e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
170e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
171e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin   return OK;
172e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
173e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
174e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinvoid Camera3IOStreamBase::handoutBufferLocked(camera3_stream_buffer &buffer,
175e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              buffer_handle_t *handle,
176e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              int acquireFence,
177e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              int releaseFence,
178e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              camera3_buffer_status_t status) {
179e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    /**
180e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     * Note that all fences are now owned by HAL.
181e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     */
182e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
183e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Handing out a raw pointer to this object. Increment internal refcount.
184e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    incStrong(this);
185e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.stream = this;
186e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.buffer = handle;
187e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.acquire_fence = acquireFence;
188e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.release_fence = releaseFence;
189e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.status = status;
190e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
191e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mDequeuedBufferCount++;
192e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
193e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
194e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::getBufferPreconditionCheckLocked() const {
195e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Allow dequeue during IN_[RE]CONFIG for registration
196e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mState != STATE_CONFIGURED &&
197e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            mState != STATE_IN_CONFIG && mState != STATE_IN_RECONFIG) {
198e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: Can't get buffers in unconfigured state %d",
199e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                __FUNCTION__, mId, mState);
200e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
201e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
202e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
203e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Only limit dequeue amount when fully configured
204e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mState == STATE_CONFIGURED &&
205e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            mDequeuedBufferCount == camera3_stream::max_buffers) {
206e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: Already dequeued maximum number of simultaneous"
207e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                " buffers (%d)", __FUNCTION__, mId,
208e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                camera3_stream::max_buffers);
209e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
210e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
211e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
212e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
213e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
214e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
215e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::returnBufferPreconditionCheckLocked() const {
216e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Allow buffers to be returned in the error state, to allow for disconnect
217e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // and in the in-config states for registration
218e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mState == STATE_CONSTRUCTED) {
219e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: Can't return buffers in unconfigured state %d",
220e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                __FUNCTION__, mId, mState);
221e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
222e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
223e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mDequeuedBufferCount == 0) {
224e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: No buffers outstanding to return", __FUNCTION__,
225e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                mId);
226e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
227e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
228e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
229e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
230e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
231e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
232e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::returnAnyBufferLocked(
233e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        const camera3_stream_buffer &buffer,
234e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        nsecs_t timestamp,
235e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        bool output) {
236e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
237e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
238e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // returnBuffer may be called from a raw pointer, not a sp<>, and we'll be
239e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // decrementing the internal refcount next. In case this is the last ref, we
240e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // might get destructed on the decStrong(), so keep an sp around until the
241e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // end of the call - otherwise have to sprinkle the decStrong on all exit
242e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // points.
243e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    sp<Camera3IOStreamBase> keepAlive(this);
244e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    decStrong(this);
245e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
246e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if ((res = returnBufferPreconditionCheckLocked()) != OK) {
247e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return res;
248e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
249e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
250e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    sp<Fence> releaseFence;
251e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    res = returnBufferCheckedLocked(buffer, timestamp, output,
252e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                    &releaseFence);
253e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (res != OK) {
254e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return res;
255e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
256e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
257e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mCombinedFence = Fence::merge(mName, mCombinedFence, releaseFence);
258e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
259e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mDequeuedBufferCount--;
260e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mBufferReturnedSignal.signal();
261e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
262e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (output) {
263e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mLastTimestamp = timestamp;
264e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
265e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
266e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
267e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
268e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
269e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
270e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
271e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}; // namespace camera3
272e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
273e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}; // namespace android
274