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
21e5729fac81c8a984e984fefc90afc64135817d4fColin Cross#include <inttypes.h>
22e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
23e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin#include <utils/Log.h>
24e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin#include <utils/Trace.h>
25f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include "device3/Camera3IOStreamBase.h"
26f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include "device3/StatusTracker.h"
27e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
28e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinnamespace android {
29e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
30e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinnamespace camera3 {
31e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
32e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor MurashkinCamera3IOStreamBase::Camera3IOStreamBase(int id, camera3_stream_type_t type,
333d82c0d9ed2b3e956ad699a9ca2c8a70c9d24678Eino-Ville Talvala        uint32_t width, uint32_t height, size_t maxSize, int format,
34125684aba1a11b7adbf5f9d607ee2bcc9449081cZhijun He        android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId) :
35e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        Camera3Stream(id, type,
36125684aba1a11b7adbf5f9d607ee2bcc9449081cZhijun He                width, height, maxSize, format, dataSpace, rotation, setId),
37e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mTotalBufferCount(0),
386adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutTotalBufferCount(0),
396adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutOutputBufferCount(0),
40e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mFrameCount(0),
41e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mLastTimestamp(0) {
42e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
43e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mCombinedFence = new Fence();
44e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
45e9154ced1216ceb06a82140ed65051c0397e8abcYin-Chia Yeh    if (maxSize > 0 &&
46e9154ced1216ceb06a82140ed65051c0397e8abcYin-Chia Yeh            (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE)) {
47e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
48e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                format);
49e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mState = STATE_ERROR;
50e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
51e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
52e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
53e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor MurashkinCamera3IOStreamBase::~Camera3IOStreamBase() {
54e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    disconnectLocked();
55e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
56e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
57e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinbool Camera3IOStreamBase::hasOutstandingBuffersLocked() const {
58e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    nsecs_t signalTime = mCombinedFence->getSignalTime();
59e5729fac81c8a984e984fefc90afc64135817d4fColin Cross    ALOGV("%s: Stream %d: Has %zu outstanding buffers,"
60e5729fac81c8a984e984fefc90afc64135817d4fColin Cross            " buffer signal time is %" PRId64,
616adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He            __FUNCTION__, mId, mHandoutTotalBufferCount, signalTime);
626adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount > 0 || signalTime == INT64_MAX) {
63e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return true;
64e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
65e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return false;
66e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
67e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
68e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinvoid Camera3IOStreamBase::dump(int fd, const Vector<String16> &args) const {
69e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    (void) args;
70e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    String8 lines;
714d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala
724d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    uint32_t consumerUsage = 0;
734d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    status_t res = getEndpointUsage(&consumerUsage);
744d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    if (res != OK) consumerUsage = 0;
754d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala
76e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    lines.appendFormat("      State: %d\n", mState);
774d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    lines.appendFormat("      Dims: %d x %d, format 0x%x, dataspace 0x%x\n",
78e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            camera3_stream::width, camera3_stream::height,
794d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            camera3_stream::format, camera3_stream::data_space);
80377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT    lines.appendFormat("      Max size: %zu\n", mMaxSize);
814d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    lines.appendFormat("      Combined usage: %d, max HAL buffers: %d\n",
824d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            camera3_stream::usage | consumerUsage, camera3_stream::max_buffers);
83e5729fac81c8a984e984fefc90afc64135817d4fColin Cross    lines.appendFormat("      Frames produced: %d, last timestamp: %" PRId64 " ns\n",
84e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            mFrameCount, mLastTimestamp);
85377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT    lines.appendFormat("      Total buffers: %zu, currently dequeued: %zu\n",
866adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He            mTotalBufferCount, mHandoutTotalBufferCount);
87e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    write(fd, lines.string(), lines.size());
886c2f7aeb10fb2050c27afa0212a1e167ca2809ecShuzhen Wang
896c2f7aeb10fb2050c27afa0212a1e167ca2809ecShuzhen Wang    Camera3Stream::dump(fd, args);
90e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
91e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
92e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::configureQueueLocked() {
93e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
94e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
95e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    switch (mState) {
96e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_RECONFIG:
97e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            res = disconnectLocked();
98e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            if (res != OK) {
99e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                return res;
100e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            }
101e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
102e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_CONFIG:
103e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // OK
104e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
105e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        default:
106e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            ALOGE("%s: Bad state: %d", __FUNCTION__, mState);
107e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            return INVALID_OPERATION;
108e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
109e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
110e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
111e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
112e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
113e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinsize_t Camera3IOStreamBase::getBufferCountLocked() {
114e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return mTotalBufferCount;
115e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
116e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
1176adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun Hesize_t Camera3IOStreamBase::getHandoutOutputBufferCountLocked() {
1186adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    return mHandoutOutputBufferCount;
1196adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He}
1206adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
1216adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun Hesize_t Camera3IOStreamBase::getHandoutInputBufferCountLocked() {
1226adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    return (mHandoutTotalBufferCount - mHandoutOutputBufferCount);
1236adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He}
1246adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
125e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::disconnectLocked() {
126e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    switch (mState) {
127e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_RECONFIG:
128e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_CONFIGURED:
129ff51b47dae1c236291a0508b29e8f4e7d0780761Eino-Ville Talvala        case STATE_ABANDONED:
130e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // OK
131e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
132e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        default:
133e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // No connection, nothing to do
134e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin            ALOGV("%s: Stream %d: Already disconnected",
135e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin                  __FUNCTION__, mId);
136e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin            return -ENOTCONN;
137e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
138e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
1396adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount > 0) {
140e5729fac81c8a984e984fefc90afc64135817d4fColin Cross        ALOGE("%s: Can't disconnect with %zu buffers still dequeued!",
1416adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                __FUNCTION__, mHandoutTotalBufferCount);
142e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
143e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
144e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
145e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin   return OK;
146e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
147e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
148e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinvoid Camera3IOStreamBase::handoutBufferLocked(camera3_stream_buffer &buffer,
149e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              buffer_handle_t *handle,
150e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              int acquireFence,
151e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              int releaseFence,
1526adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                                              camera3_buffer_status_t status,
1536adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                                              bool output) {
154e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    /**
155e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     * Note that all fences are now owned by HAL.
156e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     */
157e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
158e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Handing out a raw pointer to this object. Increment internal refcount.
159e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    incStrong(this);
160e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.stream = this;
161e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.buffer = handle;
162e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.acquire_fence = acquireFence;
163e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.release_fence = releaseFence;
164e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.status = status;
165e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
166f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Inform tracker about becoming busy
1676adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
1684d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_IN_RECONFIG && mState != STATE_PREPARING) {
16913d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin        /**
17013d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers
17113d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * before/after register_stream_buffers during initial configuration
1724d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala         * or re-configuration, or during prepare pre-allocation
17313d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         */
174f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        sp<StatusTracker> statusTracker = mStatusTracker.promote();
175f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (statusTracker != 0) {
176f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            statusTracker->markComponentActive(mStatusId);
177f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
178f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
1796adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    mHandoutTotalBufferCount++;
1806adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
1816adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (output) {
1826adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutOutputBufferCount++;
1836adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    }
184e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
185e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
186e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::getBufferPreconditionCheckLocked() const {
1874d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    // Allow dequeue during IN_[RE]CONFIG for registration, in
1884d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    // PREPARING for pre-allocation
189e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mState != STATE_CONFIGURED &&
1904d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_IN_CONFIG && mState != STATE_IN_RECONFIG &&
1914d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_PREPARING) {
192e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: Can't get buffers in unconfigured state %d",
193e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                __FUNCTION__, mId, mState);
194e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
195e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
196e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
197e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
198e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
199e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
200e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::returnBufferPreconditionCheckLocked() const {
201e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Allow buffers to be returned in the error state, to allow for disconnect
202e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // and in the in-config states for registration
203e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mState == STATE_CONSTRUCTED) {
204e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: Can't return buffers in unconfigured state %d",
205e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                __FUNCTION__, mId, mState);
206e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
207e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
2086adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0) {
209e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: No buffers outstanding to return", __FUNCTION__,
210e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                mId);
211e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
212e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
213e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
214e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
215e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
216e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
217e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::returnAnyBufferLocked(
218e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        const camera3_stream_buffer &buffer,
219e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        nsecs_t timestamp,
220e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        bool output) {
221e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
222e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
223e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // returnBuffer may be called from a raw pointer, not a sp<>, and we'll be
224e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // decrementing the internal refcount next. In case this is the last ref, we
225e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // might get destructed on the decStrong(), so keep an sp around until the
226e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // end of the call - otherwise have to sprinkle the decStrong on all exit
227e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // points.
228e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    sp<Camera3IOStreamBase> keepAlive(this);
229e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    decStrong(this);
230e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
231e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if ((res = returnBufferPreconditionCheckLocked()) != OK) {
232e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return res;
233e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
234e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
235e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    sp<Fence> releaseFence;
236e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    res = returnBufferCheckedLocked(buffer, timestamp, output,
237e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                    &releaseFence);
23807d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // Res may be an error, but we still want to decrement our owned count
23907d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // to enable clean shutdown. So we'll just return the error but otherwise
24007d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // carry on
241e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
24207d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    if (releaseFence != 0) {
24307d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala        mCombinedFence = Fence::merge(mName, mCombinedFence, releaseFence);
24407d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    }
245e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
2466adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (output) {
2476adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutOutputBufferCount--;
2486adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    }
2496adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
2506adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    mHandoutTotalBufferCount--;
2516adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
2524d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_IN_RECONFIG && mState != STATE_PREPARING) {
25313d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin        /**
25413d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers
25513d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * before/after register_stream_buffers during initial configuration
2564d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala         * or re-configuration, or during prepare pre-allocation
25713d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         */
25807d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala        ALOGV("%s: Stream %d: All buffers returned; now idle", __FUNCTION__,
25907d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala                mId);
260f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        sp<StatusTracker> statusTracker = mStatusTracker.promote();
261f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (statusTracker != 0) {
262f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            statusTracker->markComponentIdle(mStatusId, mCombinedFence);
263f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
264f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
265f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
266e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mBufferReturnedSignal.signal();
267e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
268e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (output) {
269e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mLastTimestamp = timestamp;
270e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
271e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
27207d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    return res;
273e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
274e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
275e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
276e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
277e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}; // namespace camera3
278e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
279e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}; // namespace android
280