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,
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),
376adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutTotalBufferCount(0),
386adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutOutputBufferCount(0),
39e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mFrameCount(0),
40e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mLastTimestamp(0) {
41e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
42e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mCombinedFence = new Fence();
43e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
44e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (maxSize > 0 && format != HAL_PIXEL_FORMAT_BLOB) {
45e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
46e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                format);
47e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mState = STATE_ERROR;
48e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
49e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
50e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
51e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor MurashkinCamera3IOStreamBase::~Camera3IOStreamBase() {
52e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    disconnectLocked();
53e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
54e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
55e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinbool Camera3IOStreamBase::hasOutstandingBuffersLocked() const {
56e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    nsecs_t signalTime = mCombinedFence->getSignalTime();
57e5729fac81c8a984e984fefc90afc64135817d4fColin Cross    ALOGV("%s: Stream %d: Has %zu outstanding buffers,"
58e5729fac81c8a984e984fefc90afc64135817d4fColin Cross            " buffer signal time is %" PRId64,
596adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He            __FUNCTION__, mId, mHandoutTotalBufferCount, signalTime);
606adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount > 0 || signalTime == INT64_MAX) {
61e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return true;
62e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
63e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return false;
64e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
65e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
66e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinvoid Camera3IOStreamBase::dump(int fd, const Vector<String16> &args) const {
67e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    (void) args;
68e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    String8 lines;
69e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    lines.appendFormat("      State: %d\n", mState);
70e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    lines.appendFormat("      Dims: %d x %d, format 0x%x\n",
71e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            camera3_stream::width, camera3_stream::height,
72e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            camera3_stream::format);
73377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT    lines.appendFormat("      Max size: %zu\n", mMaxSize);
74e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    lines.appendFormat("      Usage: %d, max HAL buffers: %d\n",
75e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            camera3_stream::usage, camera3_stream::max_buffers);
76e5729fac81c8a984e984fefc90afc64135817d4fColin Cross    lines.appendFormat("      Frames produced: %d, last timestamp: %" PRId64 " ns\n",
77e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            mFrameCount, mLastTimestamp);
78377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT    lines.appendFormat("      Total buffers: %zu, currently dequeued: %zu\n",
796adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He            mTotalBufferCount, mHandoutTotalBufferCount);
80e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    write(fd, lines.string(), lines.size());
81e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
82e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
83e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::configureQueueLocked() {
84e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
85e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
86e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    switch (mState) {
87e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_RECONFIG:
88e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            res = disconnectLocked();
89e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            if (res != OK) {
90e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                return res;
91e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            }
92e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
93e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_CONFIG:
94e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // OK
95e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
96e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        default:
97e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            ALOGE("%s: Bad state: %d", __FUNCTION__, mState);
98e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            return INVALID_OPERATION;
99e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
100e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
101e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
102e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
103e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
104e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinsize_t Camera3IOStreamBase::getBufferCountLocked() {
105e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return mTotalBufferCount;
106e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
107e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
1086adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun Hesize_t Camera3IOStreamBase::getHandoutOutputBufferCountLocked() {
1096adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    return mHandoutOutputBufferCount;
1106adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He}
1116adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
1126adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun Hesize_t Camera3IOStreamBase::getHandoutInputBufferCountLocked() {
1136adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    return (mHandoutTotalBufferCount - mHandoutOutputBufferCount);
1146adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He}
1156adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
116e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::disconnectLocked() {
117e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    switch (mState) {
118e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_RECONFIG:
119e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_CONFIGURED:
120e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // OK
121e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
122e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        default:
123e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // No connection, nothing to do
124e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin            ALOGV("%s: Stream %d: Already disconnected",
125e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin                  __FUNCTION__, mId);
126e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin            return -ENOTCONN;
127e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
128e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
1296adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount > 0) {
130e5729fac81c8a984e984fefc90afc64135817d4fColin Cross        ALOGE("%s: Can't disconnect with %zu buffers still dequeued!",
1316adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                __FUNCTION__, mHandoutTotalBufferCount);
132e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
133e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
134e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
135e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin   return OK;
136e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
137e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
138e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinvoid Camera3IOStreamBase::handoutBufferLocked(camera3_stream_buffer &buffer,
139e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              buffer_handle_t *handle,
140e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              int acquireFence,
141e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              int releaseFence,
1426adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                                              camera3_buffer_status_t status,
1436adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                                              bool output) {
144e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    /**
145e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     * Note that all fences are now owned by HAL.
146e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     */
147e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
148e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Handing out a raw pointer to this object. Increment internal refcount.
149e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    incStrong(this);
150e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.stream = this;
151e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.buffer = handle;
152e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.acquire_fence = acquireFence;
153e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.release_fence = releaseFence;
154e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.status = status;
155e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
156f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Inform tracker about becoming busy
1576adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
158f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mState != STATE_IN_RECONFIG) {
15913d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin        /**
16013d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers
16113d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * before/after register_stream_buffers during initial configuration
16213d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * or re-configuration.
16313d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         *
16413d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * TODO: IN_CONFIG and IN_RECONFIG checks only make sense for <HAL3.2
16513d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         */
166f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        sp<StatusTracker> statusTracker = mStatusTracker.promote();
167f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (statusTracker != 0) {
168f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            statusTracker->markComponentActive(mStatusId);
169f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
170f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
1716adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    mHandoutTotalBufferCount++;
1726adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
1736adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (output) {
1746adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutOutputBufferCount++;
1756adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    }
176e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
177e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
178e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::getBufferPreconditionCheckLocked() const {
179e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Allow dequeue during IN_[RE]CONFIG for registration
180e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mState != STATE_CONFIGURED &&
181e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            mState != STATE_IN_CONFIG && mState != STATE_IN_RECONFIG) {
182e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: Can't get buffers in unconfigured state %d",
183e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                __FUNCTION__, mId, mState);
184e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
185e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
186e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
187e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
188e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
189e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
190e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::returnBufferPreconditionCheckLocked() const {
191e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Allow buffers to be returned in the error state, to allow for disconnect
192e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // and in the in-config states for registration
193e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mState == STATE_CONSTRUCTED) {
194e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: Can't return buffers in unconfigured state %d",
195e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                __FUNCTION__, mId, mState);
196e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
197e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
1986adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0) {
199e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: No buffers outstanding to return", __FUNCTION__,
200e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                mId);
201e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
202e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
203e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
204e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
205e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
206e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
207e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::returnAnyBufferLocked(
208e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        const camera3_stream_buffer &buffer,
209e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        nsecs_t timestamp,
210e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        bool output) {
211e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
212e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
213e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // returnBuffer may be called from a raw pointer, not a sp<>, and we'll be
214e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // decrementing the internal refcount next. In case this is the last ref, we
215e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // might get destructed on the decStrong(), so keep an sp around until the
216e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // end of the call - otherwise have to sprinkle the decStrong on all exit
217e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // points.
218e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    sp<Camera3IOStreamBase> keepAlive(this);
219e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    decStrong(this);
220e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
221e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if ((res = returnBufferPreconditionCheckLocked()) != OK) {
222e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return res;
223e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
224e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
225e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    sp<Fence> releaseFence;
226e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    res = returnBufferCheckedLocked(buffer, timestamp, output,
227e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                    &releaseFence);
22807d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // Res may be an error, but we still want to decrement our owned count
22907d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // to enable clean shutdown. So we'll just return the error but otherwise
23007d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // carry on
231e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
23207d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    if (releaseFence != 0) {
23307d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala        mCombinedFence = Fence::merge(mName, mCombinedFence, releaseFence);
23407d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    }
235e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
2366adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (output) {
2376adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutOutputBufferCount--;
2386adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    }
2396adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
2406adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    mHandoutTotalBufferCount--;
2416adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
242f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            mState != STATE_IN_RECONFIG) {
24313d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin        /**
24413d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers
24513d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * before/after register_stream_buffers during initial configuration
24613d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * or re-configuration.
24713d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         *
24813d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * TODO: IN_CONFIG and IN_RECONFIG checks only make sense for <HAL3.2
24913d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         */
25007d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala        ALOGV("%s: Stream %d: All buffers returned; now idle", __FUNCTION__,
25107d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala                mId);
252f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        sp<StatusTracker> statusTracker = mStatusTracker.promote();
253f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (statusTracker != 0) {
254f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            statusTracker->markComponentIdle(mStatusId, mCombinedFence);
255f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
256f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
257f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
258e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mBufferReturnedSignal.signal();
259e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
260e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (output) {
261e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mLastTimestamp = timestamp;
262e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
263e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
26407d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    return res;
265e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
266e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
267e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
268e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
269e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}; // namespace camera3
270e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
271e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}; // namespace android
272