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());
88e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
89e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
90e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::configureQueueLocked() {
91e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
92e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
93e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    switch (mState) {
94e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_RECONFIG:
95e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            res = disconnectLocked();
96e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            if (res != OK) {
97e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                return res;
98e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            }
99e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
100e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_CONFIG:
101e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // OK
102e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
103e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        default:
104e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            ALOGE("%s: Bad state: %d", __FUNCTION__, mState);
105e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            return INVALID_OPERATION;
106e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
107e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
108e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
109e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
110e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
111e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinsize_t Camera3IOStreamBase::getBufferCountLocked() {
112e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return mTotalBufferCount;
113e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
114e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
1156adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun Hesize_t Camera3IOStreamBase::getHandoutOutputBufferCountLocked() {
1166adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    return mHandoutOutputBufferCount;
1176adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He}
1186adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
1196adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun Hesize_t Camera3IOStreamBase::getHandoutInputBufferCountLocked() {
1206adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    return (mHandoutTotalBufferCount - mHandoutOutputBufferCount);
1216adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He}
1226adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
123e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::disconnectLocked() {
124e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    switch (mState) {
125e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_RECONFIG:
126e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_CONFIGURED:
127ff51b47dae1c236291a0508b29e8f4e7d0780761Eino-Ville Talvala        case STATE_ABANDONED:
128e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // OK
129e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
130e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        default:
131e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // No connection, nothing to do
132e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin            ALOGV("%s: Stream %d: Already disconnected",
133e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin                  __FUNCTION__, mId);
134e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin            return -ENOTCONN;
135e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
136e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
1376adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount > 0) {
138e5729fac81c8a984e984fefc90afc64135817d4fColin Cross        ALOGE("%s: Can't disconnect with %zu buffers still dequeued!",
1396adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                __FUNCTION__, mHandoutTotalBufferCount);
140e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
141e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
142e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
143e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin   return OK;
144e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
145e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
146e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinvoid Camera3IOStreamBase::handoutBufferLocked(camera3_stream_buffer &buffer,
147e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              buffer_handle_t *handle,
148e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              int acquireFence,
149e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              int releaseFence,
1506adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                                              camera3_buffer_status_t status,
1516adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                                              bool output) {
152e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    /**
153e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     * Note that all fences are now owned by HAL.
154e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     */
155e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
156e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Handing out a raw pointer to this object. Increment internal refcount.
157e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    incStrong(this);
158e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.stream = this;
159e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.buffer = handle;
160e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.acquire_fence = acquireFence;
161e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.release_fence = releaseFence;
162e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.status = status;
163e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
164f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Inform tracker about becoming busy
1656adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
1664d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_IN_RECONFIG && mState != STATE_PREPARING) {
16713d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin        /**
16813d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers
16913d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * before/after register_stream_buffers during initial configuration
1704d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala         * or re-configuration, or during prepare pre-allocation
17113d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         */
172f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        sp<StatusTracker> statusTracker = mStatusTracker.promote();
173f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (statusTracker != 0) {
174f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            statusTracker->markComponentActive(mStatusId);
175f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
176f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
1776adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    mHandoutTotalBufferCount++;
1786adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
1796adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (output) {
1806adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutOutputBufferCount++;
1816adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    }
182e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
183e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
184e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::getBufferPreconditionCheckLocked() const {
1854d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    // Allow dequeue during IN_[RE]CONFIG for registration, in
1864d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    // PREPARING for pre-allocation
187e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mState != STATE_CONFIGURED &&
1884d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_IN_CONFIG && mState != STATE_IN_RECONFIG &&
1894d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_PREPARING) {
190e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: Can't get buffers in unconfigured state %d",
191e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                __FUNCTION__, mId, mState);
192e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
193e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
194e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
195e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
196e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
197e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
198e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::returnBufferPreconditionCheckLocked() const {
199e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Allow buffers to be returned in the error state, to allow for disconnect
200e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // and in the in-config states for registration
201e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mState == STATE_CONSTRUCTED) {
202e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: Can't return buffers in unconfigured state %d",
203e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                __FUNCTION__, mId, mState);
204e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
205e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
2066adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0) {
207e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: No buffers outstanding to return", __FUNCTION__,
208e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                mId);
209e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
210e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
211e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
212e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
213e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
214e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
215e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::returnAnyBufferLocked(
216e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        const camera3_stream_buffer &buffer,
217e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        nsecs_t timestamp,
218e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        bool output) {
219e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
220e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
221e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // returnBuffer may be called from a raw pointer, not a sp<>, and we'll be
222e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // decrementing the internal refcount next. In case this is the last ref, we
223e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // might get destructed on the decStrong(), so keep an sp around until the
224e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // end of the call - otherwise have to sprinkle the decStrong on all exit
225e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // points.
226e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    sp<Camera3IOStreamBase> keepAlive(this);
227e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    decStrong(this);
228e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
229e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if ((res = returnBufferPreconditionCheckLocked()) != OK) {
230e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return res;
231e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
232e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
233e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    sp<Fence> releaseFence;
234e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    res = returnBufferCheckedLocked(buffer, timestamp, output,
235e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                    &releaseFence);
23607d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // Res may be an error, but we still want to decrement our owned count
23707d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // to enable clean shutdown. So we'll just return the error but otherwise
23807d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // carry on
239e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
24007d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    if (releaseFence != 0) {
24107d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala        mCombinedFence = Fence::merge(mName, mCombinedFence, releaseFence);
24207d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    }
243e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
2446adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (output) {
2456adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutOutputBufferCount--;
2466adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    }
2476adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
2486adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    mHandoutTotalBufferCount--;
2496adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
2504d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_IN_RECONFIG && mState != STATE_PREPARING) {
25113d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin        /**
25213d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers
25313d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * before/after register_stream_buffers during initial configuration
2544d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala         * or re-configuration, or during prepare pre-allocation
25513d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         */
25607d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala        ALOGV("%s: Stream %d: All buffers returned; now idle", __FUNCTION__,
25707d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala                mId);
258f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        sp<StatusTracker> statusTracker = mStatusTracker.promote();
259f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (statusTracker != 0) {
260f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            statusTracker->markComponentIdle(mStatusId, mCombinedFence);
261f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
262f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
263f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
264e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mBufferReturnedSignal.signal();
265e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
266e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (output) {
267e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mLastTimestamp = timestamp;
268e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
269e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
27007d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    return res;
271e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
272e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
273e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
274e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
275e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}; // namespace camera3
276e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
277e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}; // namespace android
278