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,
34b97babb8c08969b55af3b6456d15f764c8873d3fYin-Chia Yeh        android_dataspace dataSpace, camera3_stream_rotation_t rotation) :
35e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        Camera3Stream(id, type,
36b97babb8c08969b55af3b6456d15f764c8873d3fYin-Chia Yeh                width, height, maxSize, format, dataSpace, rotation),
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
45e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (maxSize > 0 && format != HAL_PIXEL_FORMAT_BLOB) {
46e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
47e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                format);
48e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mState = STATE_ERROR;
49e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
50e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
51e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
52e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor MurashkinCamera3IOStreamBase::~Camera3IOStreamBase() {
53e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    disconnectLocked();
54e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
55e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
56e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinbool Camera3IOStreamBase::hasOutstandingBuffersLocked() const {
57e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    nsecs_t signalTime = mCombinedFence->getSignalTime();
58e5729fac81c8a984e984fefc90afc64135817d4fColin Cross    ALOGV("%s: Stream %d: Has %zu outstanding buffers,"
59e5729fac81c8a984e984fefc90afc64135817d4fColin Cross            " buffer signal time is %" PRId64,
606adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He            __FUNCTION__, mId, mHandoutTotalBufferCount, signalTime);
616adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount > 0 || signalTime == INT64_MAX) {
62e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return true;
63e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
64e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return false;
65e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
66e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
67e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinvoid Camera3IOStreamBase::dump(int fd, const Vector<String16> &args) const {
68e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    (void) args;
69e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    String8 lines;
704d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala
714d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    uint32_t consumerUsage = 0;
724d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    status_t res = getEndpointUsage(&consumerUsage);
734d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    if (res != OK) consumerUsage = 0;
744d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala
75e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    lines.appendFormat("      State: %d\n", mState);
764d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    lines.appendFormat("      Dims: %d x %d, format 0x%x, dataspace 0x%x\n",
77e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            camera3_stream::width, camera3_stream::height,
784d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            camera3_stream::format, camera3_stream::data_space);
79377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT    lines.appendFormat("      Max size: %zu\n", mMaxSize);
804d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    lines.appendFormat("      Combined usage: %d, max HAL buffers: %d\n",
814d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            camera3_stream::usage | consumerUsage, camera3_stream::max_buffers);
82e5729fac81c8a984e984fefc90afc64135817d4fColin Cross    lines.appendFormat("      Frames produced: %d, last timestamp: %" PRId64 " ns\n",
83e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            mFrameCount, mLastTimestamp);
84377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT    lines.appendFormat("      Total buffers: %zu, currently dequeued: %zu\n",
856adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He            mTotalBufferCount, mHandoutTotalBufferCount);
86e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    write(fd, lines.string(), lines.size());
87e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
88e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
89e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::configureQueueLocked() {
90e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
91e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
92e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    switch (mState) {
93e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_RECONFIG:
94e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            res = disconnectLocked();
95e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            if (res != OK) {
96e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                return res;
97e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            }
98e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
99e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_CONFIG:
100e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // OK
101e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
102e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        default:
103e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            ALOGE("%s: Bad state: %d", __FUNCTION__, mState);
104e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            return INVALID_OPERATION;
105e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
106e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
107e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
108e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
109e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
110e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinsize_t Camera3IOStreamBase::getBufferCountLocked() {
111e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return mTotalBufferCount;
112e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
113e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
1146adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun Hesize_t Camera3IOStreamBase::getHandoutOutputBufferCountLocked() {
1156adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    return mHandoutOutputBufferCount;
1166adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He}
1176adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
1186adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun Hesize_t Camera3IOStreamBase::getHandoutInputBufferCountLocked() {
1196adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    return (mHandoutTotalBufferCount - mHandoutOutputBufferCount);
1206adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He}
1216adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
122e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::disconnectLocked() {
123e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    switch (mState) {
124e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_IN_RECONFIG:
125e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        case STATE_CONFIGURED:
126e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // OK
127e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            break;
128e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        default:
129e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin            // No connection, nothing to do
130e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin            ALOGV("%s: Stream %d: Already disconnected",
131e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin                  __FUNCTION__, mId);
132e2172bed7e77ab1d922588cf727818b481400b53Igor Murashkin            return -ENOTCONN;
133e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
134e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
1356adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount > 0) {
136e5729fac81c8a984e984fefc90afc64135817d4fColin Cross        ALOGE("%s: Can't disconnect with %zu buffers still dequeued!",
1376adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                __FUNCTION__, mHandoutTotalBufferCount);
138e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
139e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
140e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
141e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin   return OK;
142e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
143e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
144e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinvoid Camera3IOStreamBase::handoutBufferLocked(camera3_stream_buffer &buffer,
145e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              buffer_handle_t *handle,
146e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              int acquireFence,
147e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                              int releaseFence,
1486adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                                              camera3_buffer_status_t status,
1496adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He                                              bool output) {
150e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    /**
151e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     * Note that all fences are now owned by HAL.
152e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin     */
153e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
154e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Handing out a raw pointer to this object. Increment internal refcount.
155e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    incStrong(this);
156e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.stream = this;
157e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.buffer = handle;
158e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.acquire_fence = acquireFence;
159e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.release_fence = releaseFence;
160e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    buffer.status = status;
161e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
162f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    // Inform tracker about becoming busy
1636adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
1644d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_IN_RECONFIG && mState != STATE_PREPARING) {
16513d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin        /**
16613d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers
16713d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * before/after register_stream_buffers during initial configuration
1684d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala         * or re-configuration, or during prepare pre-allocation
16913d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         */
170f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        sp<StatusTracker> statusTracker = mStatusTracker.promote();
171f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (statusTracker != 0) {
172f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            statusTracker->markComponentActive(mStatusId);
173f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
174f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
1756adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    mHandoutTotalBufferCount++;
1766adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
1776adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (output) {
1786adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutOutputBufferCount++;
1796adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    }
180e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
181e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
182e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::getBufferPreconditionCheckLocked() const {
1834d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    // Allow dequeue during IN_[RE]CONFIG for registration, in
1844d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala    // PREPARING for pre-allocation
185e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mState != STATE_CONFIGURED &&
1864d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_IN_CONFIG && mState != STATE_IN_RECONFIG &&
1874d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_PREPARING) {
188e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: Can't get buffers in unconfigured state %d",
189e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                __FUNCTION__, mId, mState);
190e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
191e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
192e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
193e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
194e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
195e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
196e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::returnBufferPreconditionCheckLocked() const {
197e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // Allow buffers to be returned in the error state, to allow for disconnect
198e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // and in the in-config states for registration
199e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (mState == STATE_CONSTRUCTED) {
200e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: Can't return buffers in unconfigured state %d",
201e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                __FUNCTION__, mId, mState);
202e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
203e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
2046adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0) {
205e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        ALOGE("%s: Stream %d: No buffers outstanding to return", __FUNCTION__,
206e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                mId);
207e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return INVALID_OPERATION;
208e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
209e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
210e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    return OK;
211e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
212e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
213e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkinstatus_t Camera3IOStreamBase::returnAnyBufferLocked(
214e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        const camera3_stream_buffer &buffer,
215e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        nsecs_t timestamp,
216e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        bool output) {
217e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    status_t res;
218e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
219e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // returnBuffer may be called from a raw pointer, not a sp<>, and we'll be
220e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // decrementing the internal refcount next. In case this is the last ref, we
221e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // might get destructed on the decStrong(), so keep an sp around until the
222e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // end of the call - otherwise have to sprinkle the decStrong on all exit
223e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    // points.
224e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    sp<Camera3IOStreamBase> keepAlive(this);
225e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    decStrong(this);
226e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
227e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if ((res = returnBufferPreconditionCheckLocked()) != OK) {
228e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        return res;
229e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
230e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
231e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    sp<Fence> releaseFence;
232e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    res = returnBufferCheckedLocked(buffer, timestamp, output,
233e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin                                    &releaseFence);
23407d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // Res may be an error, but we still want to decrement our owned count
23507d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // to enable clean shutdown. So we'll just return the error but otherwise
23607d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    // carry on
237e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
23807d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    if (releaseFence != 0) {
23907d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala        mCombinedFence = Fence::merge(mName, mCombinedFence, releaseFence);
24007d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    }
241e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
2426adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (output) {
2436adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He        mHandoutOutputBufferCount--;
2446adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    }
2456adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He
2466adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    mHandoutTotalBufferCount--;
2476adc9ccb2948d9421a0ed4b74f52b909bcec2037Zhijun He    if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
2484d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala            mState != STATE_IN_RECONFIG && mState != STATE_PREPARING) {
24913d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin        /**
25013d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers
25113d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         * before/after register_stream_buffers during initial configuration
2524d44cad22ea925a651463f2d51d6586c14d4b787Eino-Ville Talvala         * or re-configuration, or during prepare pre-allocation
25313d315eb8c0848ea0584b9fb1d27bab55bc8158bIgor Murashkin         */
25407d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala        ALOGV("%s: Stream %d: All buffers returned; now idle", __FUNCTION__,
25507d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala                mId);
256f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        sp<StatusTracker> statusTracker = mStatusTracker.promote();
257f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        if (statusTracker != 0) {
258f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala            statusTracker->markComponentIdle(mStatusId, mCombinedFence);
259f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        }
260f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    }
261f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala
262e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    mBufferReturnedSignal.signal();
263e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
264e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    if (output) {
265e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin        mLastTimestamp = timestamp;
266e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin    }
267e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
26807d2169d46f3536add6044dbf106967a1982252fEino-Ville Talvala    return res;
269e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}
270e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
271e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
272e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
273e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}; // namespace camera3
274e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin
275e3a9f964d7ebb6f269e6df2ba9c24b7c8b9ccefdIgor Murashkin}; // namespace android
276