blob: 2ae56601df1269c09b61b0a9d053bdd81224dc37 [file] [log] [blame]
Shuzhen Wang0129d522016-10-30 22:43:41 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "Camera3SharedOutputStream.h"
18
19namespace android {
20
21namespace camera3 {
22
23Camera3SharedOutputStream::Camera3SharedOutputStream(int id,
24 const std::vector<sp<Surface>>& surfaces,
Shuzhen Wang0129d522016-10-30 22:43:41 -070025 uint32_t width, uint32_t height, int format,
26 uint32_t consumerUsage, android_dataspace dataSpace,
27 camera3_stream_rotation_t rotation,
28 nsecs_t timestampOffset, int setId) :
29 Camera3OutputStream(id, CAMERA3_STREAM_OUTPUT, width, height,
30 format, dataSpace, rotation, consumerUsage,
31 timestampOffset, setId),
Shuzhen Wang758c2152017-01-10 18:26:18 -080032 mSurfaces(surfaces) {
Shuzhen Wang0129d522016-10-30 22:43:41 -070033}
34
35Camera3SharedOutputStream::~Camera3SharedOutputStream() {
36 disconnectLocked();
37}
38
39status_t Camera3SharedOutputStream::connectStreamSplitterLocked() {
40 status_t res = OK;
41
42 mStreamSplitter = new Camera3StreamSplitter();
43
44 uint32_t usage;
45 getEndpointUsage(&usage);
46
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -080047 res = mStreamSplitter->connect(mSurfaces, usage, camera3_stream::max_buffers, &mConsumer);
Shuzhen Wang0129d522016-10-30 22:43:41 -070048 if (res != OK) {
49 ALOGE("%s: Failed to connect to stream splitter: %s(%d)",
50 __FUNCTION__, strerror(-res), res);
51 return res;
52 }
53
54 return res;
55}
56
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -080057status_t Camera3SharedOutputStream::notifyBufferReleased(ANativeWindowBuffer *anwBuffer) {
Shuzhen Wang0129d522016-10-30 22:43:41 -070058 Mutex::Autolock l(mLock);
59 status_t res = OK;
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -080060 const sp<GraphicBuffer> buffer(static_cast<GraphicBuffer*>(anwBuffer));
Shuzhen Wang0129d522016-10-30 22:43:41 -070061
62 if (mStreamSplitter != nullptr) {
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -080063 res = mStreamSplitter->notifyBufferReleased(buffer);
Shuzhen Wang0129d522016-10-30 22:43:41 -070064 }
65
66 return res;
67}
68
69bool Camera3SharedOutputStream::isConsumerConfigurationDeferred(size_t surface_id) const {
70 Mutex::Autolock l(mLock);
Shuzhen Wang758c2152017-01-10 18:26:18 -080071 return (surface_id >= mSurfaces.size());
Shuzhen Wang0129d522016-10-30 22:43:41 -070072}
73
Shuzhen Wang758c2152017-01-10 18:26:18 -080074status_t Camera3SharedOutputStream::setConsumers(const std::vector<sp<Surface>>& surfaces) {
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -080075 Mutex::Autolock l(mLock);
Shuzhen Wang758c2152017-01-10 18:26:18 -080076 if (surfaces.size() == 0) {
77 ALOGE("%s: it's illegal to set zero consumer surfaces!", __FUNCTION__);
Shuzhen Wang0129d522016-10-30 22:43:41 -070078 return INVALID_OPERATION;
79 }
80
Shuzhen Wang758c2152017-01-10 18:26:18 -080081 status_t ret = OK;
82 for (auto& surface : surfaces) {
83 if (surface == nullptr) {
84 ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__);
85 return INVALID_OPERATION;
86 }
87
88 mSurfaces.push_back(surface);
89
90 // Only call addOutput if the splitter has been connected.
91 if (mStreamSplitter != nullptr) {
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -080092 ret = mStreamSplitter->addOutput(surface);
Shuzhen Wang758c2152017-01-10 18:26:18 -080093 if (ret != OK) {
94 ALOGE("%s: addOutput failed with error code %d", __FUNCTION__, ret);
95 return ret;
96
97 }
98 }
Shuzhen Wang0129d522016-10-30 22:43:41 -070099 }
Shuzhen Wang758c2152017-01-10 18:26:18 -0800100 return ret;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700101}
102
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800103status_t Camera3SharedOutputStream::getBufferLocked(camera3_stream_buffer *buffer,
104 const std::vector<size_t>& surface_ids) {
105 ANativeWindowBuffer* anb;
106 int fenceFd = -1;
107
108 status_t res;
109 res = getBufferLockedCommon(&anb, &fenceFd);
110 if (res != OK) {
111 return res;
112 }
113
114 // Attach the buffer to the splitter output queues. This could block if
115 // the output queue doesn't have any empty slot. So unlock during the course
116 // of attachBufferToOutputs.
117 sp<Camera3StreamSplitter> splitter = mStreamSplitter;
118 mLock.unlock();
119 res = splitter->attachBufferToOutputs(anb, surface_ids);
120 mLock.lock();
121 if (res != OK) {
122 ALOGE("%s: Stream %d: Cannot attach stream splitter buffer to outputs: %s (%d)",
123 __FUNCTION__, mId, strerror(-res), res);
124 // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
125 // let prepareNextBuffer handle the error.)
126 if (res == NO_INIT && mState == STATE_CONFIGURED) {
127 mState = STATE_ABANDONED;
128 }
129
130 return res;
131 }
132
133 /**
134 * FenceFD now owned by HAL except in case of error,
135 * in which case we reassign it to acquire_fence
136 */
137 handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
138 /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true);
139
140 return OK;
141}
142
143status_t Camera3SharedOutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer,
144 ANativeWindowBuffer* buffer, int anwReleaseFence) {
145 status_t res = consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
146
147 // After queuing buffer to the internal consumer queue, check whether the buffer is
148 // successfully queued to the output queues.
149 if (res == OK) {
150 res = mStreamSplitter->getOnFrameAvailableResult();
151 if (res != OK) {
152 ALOGE("%s: getOnFrameAvailable returns %d", __FUNCTION__, res);
153 }
154 } else {
155 ALOGE("%s: queueBufer failed %d", __FUNCTION__, res);
156 }
157
158 return res;
159}
160
Shuzhen Wang0129d522016-10-30 22:43:41 -0700161status_t Camera3SharedOutputStream::configureQueueLocked() {
162 status_t res;
163
164 if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) {
165 return res;
166 }
167
168 res = connectStreamSplitterLocked();
169 if (res != OK) {
170 ALOGE("Cannot connect to stream splitter: %s(%d)", strerror(-res), res);
171 return res;
172 }
173
174 res = configureConsumerQueueLocked();
175 if (res != OK) {
176 ALOGE("Failed to configureConsumerQueueLocked: %s(%d)", strerror(-res), res);
177 return res;
178 }
179
180 return OK;
181}
182
183status_t Camera3SharedOutputStream::disconnectLocked() {
184 status_t res;
185 res = Camera3OutputStream::disconnectLocked();
186
187 if (mStreamSplitter != nullptr) {
188 mStreamSplitter->disconnect();
189 }
190
191 return res;
192}
193
194status_t Camera3SharedOutputStream::getEndpointUsage(uint32_t *usage) const {
195
Shuzhen Wang758c2152017-01-10 18:26:18 -0800196 status_t res = OK;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700197 uint32_t u = 0;
198
199 if (mConsumer == nullptr) {
200 // Called before shared buffer queue is constructed.
201 *usage = getPresetConsumerUsage();
202
203 for (auto surface : mSurfaces) {
204 if (surface != nullptr) {
205 res = getEndpointUsageForSurface(&u, surface);
206 *usage |= u;
207 }
208 }
209 } else {
210 // Called after shared buffer queue is constructed.
211 res = getEndpointUsageForSurface(&u, mConsumer);
212 *usage |= u;
213 }
214
215 return res;
216}
217
218} // namespace camera3
219
220} // namespace android