blob: c72114470fa162fc79b2d6feb7393bc83f93c09a [file] [log] [blame]
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -08001/*
2 * Copyright (C) 2013 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#define LOG_TAG "Camera3-OutputStream"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080021#include <utils/Log.h>
22#include <utils/Trace.h>
23#include "Camera3OutputStream.h"
24
25#ifndef container_of
26#define container_of(ptr, type, member) \
27 (type *)((char*)(ptr) - offsetof(type, member))
28#endif
29
30namespace android {
31
32namespace camera3 {
33
34Camera3OutputStream::Camera3OutputStream(int id,
Eino-Ville Talvala727d1722015-06-09 13:44:19 -070035 sp<Surface> consumer,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -080036 uint32_t width, uint32_t height, int format,
Zhijun He125684a2015-12-26 15:07:30 -080037 android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId) :
Igor Murashkine3a9f962013-05-08 18:03:15 -070038 Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height,
Zhijun He125684a2015-12-26 15:07:30 -080039 /*maxSize*/0, format, dataSpace, rotation, setId),
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080040 mConsumer(consumer),
Ruchit Sharmae0711f22014-08-18 13:48:24 -040041 mTransform(0),
Zhijun He125684a2015-12-26 15:07:30 -080042 mTraceFirstBuffer(true),
43 mUseBufferManager(false) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080044
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080045 if (mConsumer == NULL) {
46 ALOGE("%s: Consumer is NULL!", __FUNCTION__);
47 mState = STATE_ERROR;
48 }
Zhijun He125684a2015-12-26 15:07:30 -080049
50 if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
51 mBufferReleasedListener = new BufferReleasedListener(this);
52 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080053}
54
55Camera3OutputStream::Camera3OutputStream(int id,
Eino-Ville Talvala727d1722015-06-09 13:44:19 -070056 sp<Surface> consumer,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -080057 uint32_t width, uint32_t height, size_t maxSize, int format,
Zhijun He125684a2015-12-26 15:07:30 -080058 android_dataspace dataSpace, camera3_stream_rotation_t rotation, int setId) :
Igor Murashkine3a9f962013-05-08 18:03:15 -070059 Camera3IOStreamBase(id, CAMERA3_STREAM_OUTPUT, width, height, maxSize,
Zhijun He125684a2015-12-26 15:07:30 -080060 format, dataSpace, rotation, setId),
Igor Murashkina55b5452013-04-02 16:36:33 -070061 mConsumer(consumer),
Ruchit Sharmae0711f22014-08-18 13:48:24 -040062 mTransform(0),
Zhijun He125684a2015-12-26 15:07:30 -080063 mTraceFirstBuffer(true),
64 mUseBufferManager(false) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080065
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -080066 if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080067 ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
68 format);
69 mState = STATE_ERROR;
70 }
71
72 if (mConsumer == NULL) {
73 ALOGE("%s: Consumer is NULL!", __FUNCTION__);
74 mState = STATE_ERROR;
75 }
Zhijun He125684a2015-12-26 15:07:30 -080076
77 if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
78 mBufferReleasedListener = new BufferReleasedListener(this);
79 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080080}
81
Igor Murashkine3a9f962013-05-08 18:03:15 -070082Camera3OutputStream::Camera3OutputStream(int id, camera3_stream_type_t type,
83 uint32_t width, uint32_t height,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -080084 int format,
Yin-Chia Yehb97babb2015-03-12 13:42:44 -070085 android_dataspace dataSpace,
Zhijun He125684a2015-12-26 15:07:30 -080086 camera3_stream_rotation_t rotation,
87 int setId) :
Igor Murashkine3a9f962013-05-08 18:03:15 -070088 Camera3IOStreamBase(id, type, width, height,
89 /*maxSize*/0,
Zhijun He125684a2015-12-26 15:07:30 -080090 format, dataSpace, rotation, setId),
91 mTransform(0),
92 mTraceFirstBuffer(true),
93 mUseBufferManager(false) {
94
95 if (setId > CAMERA3_STREAM_SET_ID_INVALID) {
96 mBufferReleasedListener = new BufferReleasedListener(this);
97 }
Igor Murashkine3a9f962013-05-08 18:03:15 -070098
99 // Subclasses expected to initialize mConsumer themselves
100}
101
102
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800103Camera3OutputStream::~Camera3OutputStream() {
104 disconnectLocked();
105}
106
107status_t Camera3OutputStream::getBufferLocked(camera3_stream_buffer *buffer) {
108 ATRACE_CALL();
109 status_t res;
110
Igor Murashkine3a9f962013-05-08 18:03:15 -0700111 if ((res = getBufferPreconditionCheckLocked()) != OK) {
112 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800113 }
114
115 ANativeWindowBuffer* anb;
Zhijun He125684a2015-12-26 15:07:30 -0800116 int fenceFd = -1;
117 if (mUseBufferManager) {
118 sp<GraphicBuffer> gb;
119 res = mBufferManager->getBufferForStream(getId(), getStreamSetId(), &gb, &fenceFd);
120 if (res != OK) {
121 ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager: %s (%d)",
122 __FUNCTION__, mId, strerror(-res), res);
123 return res;
124 }
125 // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after a
126 // successful return.
127 anb = gb.get();
128 res = mConsumer->attachBuffer(anb);
129 if (res != OK) {
130 ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)",
131 __FUNCTION__, mId, strerror(-res), res);
132 return res;
133 }
134 } else {
135 /**
136 * Release the lock briefly to avoid deadlock for below scenario:
137 * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring().
138 * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock.
139 * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable().
140 * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock
141 * StreamingProcessor lock.
142 * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock
143 * and try to lock bufferQueue lock.
144 * Then there is circular locking dependency.
145 */
146 sp<ANativeWindow> currentConsumer = mConsumer;
147 mLock.unlock();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800148
Zhijun He125684a2015-12-26 15:07:30 -0800149 res = currentConsumer->dequeueBuffer(currentConsumer.get(), &anb, &fenceFd);
150 mLock.lock();
151 if (res != OK) {
152 ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
153 __FUNCTION__, mId, strerror(-res), res);
154 return res;
155 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800156 }
157
Igor Murashkine3a9f962013-05-08 18:03:15 -0700158 /**
159 * FenceFD now owned by HAL except in case of error,
160 * in which case we reassign it to acquire_fence
161 */
162 handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
Zhijun He6adc9cc2014-04-15 14:09:55 -0700163 /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800164
165 return OK;
166}
167
168status_t Camera3OutputStream::returnBufferLocked(
169 const camera3_stream_buffer &buffer,
170 nsecs_t timestamp) {
171 ATRACE_CALL();
Igor Murashkine3a9f962013-05-08 18:03:15 -0700172
173 status_t res = returnAnyBufferLocked(buffer, timestamp, /*output*/true);
174
175 if (res != OK) {
176 return res;
177 }
178
179 mLastTimestamp = timestamp;
180
181 return OK;
182}
183
184status_t Camera3OutputStream::returnBufferCheckedLocked(
185 const camera3_stream_buffer &buffer,
186 nsecs_t timestamp,
187 bool output,
188 /*out*/
189 sp<Fence> *releaseFenceOut) {
190
191 (void)output;
192 ALOG_ASSERT(output, "Expected output to be true");
193
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800194 status_t res;
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700195
Yin-Chia Yeh4c9736f2015-03-05 15:01:36 -0800196 // Fence management - always honor release fence from HAL
197 sp<Fence> releaseFence = new Fence(buffer.release_fence);
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700198 int anwReleaseFence = releaseFence->dup();
199
200 /**
Zhijun He124ccf42013-05-22 14:01:30 -0700201 * Release the lock briefly to avoid deadlock with
202 * StreamingProcessor::startStream -> Camera3Stream::isConfiguring (this
203 * thread will go into StreamingProcessor::onFrameAvailable) during
204 * queueBuffer
205 */
206 sp<ANativeWindow> currentConsumer = mConsumer;
207 mLock.unlock();
208
209 /**
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700210 * Return buffer back to ANativeWindow
211 */
212 if (buffer.status == CAMERA3_BUFFER_STATUS_ERROR) {
213 // Cancel buffer
Zhijun He124ccf42013-05-22 14:01:30 -0700214 res = currentConsumer->cancelBuffer(currentConsumer.get(),
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700215 container_of(buffer.buffer, ANativeWindowBuffer, handle),
216 anwReleaseFence);
217 if (res != OK) {
218 ALOGE("%s: Stream %d: Error cancelling buffer to native window:"
Igor Murashkine3a9f962013-05-08 18:03:15 -0700219 " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700220 }
221 } else {
Ruchit Sharmae0711f22014-08-18 13:48:24 -0400222 if (mTraceFirstBuffer && (stream_type == CAMERA3_STREAM_OUTPUT)) {
223 {
224 char traceLog[48];
225 snprintf(traceLog, sizeof(traceLog), "Stream %d: first full buffer\n", mId);
226 ATRACE_NAME(traceLog);
227 }
228 mTraceFirstBuffer = false;
229 }
230
Yin-Chia Yeh4c9736f2015-03-05 15:01:36 -0800231 res = native_window_set_buffers_timestamp(mConsumer.get(), timestamp);
232 if (res != OK) {
233 ALOGE("%s: Stream %d: Error setting timestamp: %s (%d)",
234 __FUNCTION__, mId, strerror(-res), res);
235 return res;
236 }
237
Zhijun He124ccf42013-05-22 14:01:30 -0700238 res = currentConsumer->queueBuffer(currentConsumer.get(),
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800239 container_of(buffer.buffer, ANativeWindowBuffer, handle),
240 anwReleaseFence);
241 if (res != OK) {
Igor Murashkine3a9f962013-05-08 18:03:15 -0700242 ALOGE("%s: Stream %d: Error queueing buffer to native window: "
243 "%s (%d)", __FUNCTION__, mId, strerror(-res), res);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800244 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800245 }
Zhijun He124ccf42013-05-22 14:01:30 -0700246 mLock.lock();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700247
248 // Once a valid buffer has been returned to the queue, can no longer
249 // dequeue all buffers for preallocation.
250 if (buffer.status != CAMERA3_BUFFER_STATUS_ERROR) {
251 mStreamUnpreparable = true;
252 }
253
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700254 if (res != OK) {
255 close(anwReleaseFence);
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700256 }
257
Igor Murashkine3a9f962013-05-08 18:03:15 -0700258 *releaseFenceOut = releaseFence;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800259
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700260 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800261}
262
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800263void Camera3OutputStream::dump(int fd, const Vector<String16> &args) const {
264 (void) args;
265 String8 lines;
266 lines.appendFormat(" Stream[%d]: Output\n", mId);
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700267 lines.appendFormat(" Consumer name: %s\n", mConsumerName.string());
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800268 write(fd, lines.string(), lines.size());
Igor Murashkine3a9f962013-05-08 18:03:15 -0700269
270 Camera3IOStreamBase::dump(fd, args);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800271}
272
273status_t Camera3OutputStream::setTransform(int transform) {
274 ATRACE_CALL();
275 Mutex::Autolock l(mLock);
276 return setTransformLocked(transform);
277}
278
279status_t Camera3OutputStream::setTransformLocked(int transform) {
280 status_t res = OK;
281 if (mState == STATE_ERROR) {
282 ALOGE("%s: Stream in error state", __FUNCTION__);
283 return INVALID_OPERATION;
284 }
285
286 mTransform = transform;
287 if (mState == STATE_CONFIGURED) {
288 res = native_window_set_buffers_transform(mConsumer.get(),
289 transform);
290 if (res != OK) {
291 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
292 __FUNCTION__, transform, strerror(-res), res);
293 }
294 }
295 return res;
296}
297
298status_t Camera3OutputStream::configureQueueLocked() {
299 status_t res;
300
Ruchit Sharmae0711f22014-08-18 13:48:24 -0400301 mTraceFirstBuffer = true;
Igor Murashkine3a9f962013-05-08 18:03:15 -0700302 if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) {
303 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800304 }
305
Igor Murashkine3a9f962013-05-08 18:03:15 -0700306 ALOG_ASSERT(mConsumer != 0, "mConsumer should never be NULL");
307
Zhijun He125684a2015-12-26 15:07:30 -0800308 // Configure consumer-side ANativeWindow interface. The listener may be used
309 // to notify buffer manager (if it is used) of the returned buffers.
310 res = mConsumer->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/mBufferReleasedListener);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800311 if (res != OK) {
312 ALOGE("%s: Unable to connect to native window for stream %d",
313 __FUNCTION__, mId);
314 return res;
315 }
316
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700317 mConsumerName = mConsumer->getConsumerName();
318
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800319 res = native_window_set_usage(mConsumer.get(), camera3_stream::usage);
320 if (res != OK) {
321 ALOGE("%s: Unable to configure usage %08x for stream %d",
322 __FUNCTION__, camera3_stream::usage, mId);
323 return res;
324 }
325
326 res = native_window_set_scaling_mode(mConsumer.get(),
327 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
328 if (res != OK) {
329 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
330 __FUNCTION__, strerror(-res), res);
331 return res;
332 }
333
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800334 if (mMaxSize == 0) {
335 // For buffers of known size
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -0700336 res = native_window_set_buffers_dimensions(mConsumer.get(),
337 camera3_stream::width, camera3_stream::height);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800338 } else {
339 // For buffers with bounded size
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -0700340 res = native_window_set_buffers_dimensions(mConsumer.get(),
341 mMaxSize, 1);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800342 }
343 if (res != OK) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -0700344 ALOGE("%s: Unable to configure stream buffer dimensions"
345 " %d x %d (maxSize %zu) for stream %d",
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800346 __FUNCTION__, camera3_stream::width, camera3_stream::height,
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -0700347 mMaxSize, mId);
348 return res;
349 }
350 res = native_window_set_buffers_format(mConsumer.get(),
351 camera3_stream::format);
352 if (res != OK) {
353 ALOGE("%s: Unable to configure stream buffer format %#x for stream %d",
354 __FUNCTION__, camera3_stream::format, mId);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800355 return res;
356 }
357
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800358 res = native_window_set_buffers_data_space(mConsumer.get(),
359 camera3_stream::data_space);
360 if (res != OK) {
361 ALOGE("%s: Unable to configure stream dataspace %#x for stream %d",
362 __FUNCTION__, camera3_stream::data_space, mId);
363 return res;
364 }
365
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800366 int maxConsumerBuffers;
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700367 res = static_cast<ANativeWindow*>(mConsumer.get())->query(
368 mConsumer.get(),
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800369 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
370 if (res != OK) {
371 ALOGE("%s: Unable to query consumer undequeued"
372 " buffer count for stream %d", __FUNCTION__, mId);
373 return res;
374 }
375
Alex Ray20cb3002013-05-28 20:18:22 -0700376 ALOGV("%s: Consumer wants %d buffers, HAL wants %d", __FUNCTION__,
377 maxConsumerBuffers, camera3_stream::max_buffers);
378 if (camera3_stream::max_buffers == 0) {
Zhijun He2ab500c2013-07-23 08:02:53 -0700379 ALOGE("%s: Camera HAL requested max_buffer count: %d, requires at least 1",
Alex Ray20cb3002013-05-28 20:18:22 -0700380 __FUNCTION__, camera3_stream::max_buffers);
381 return INVALID_OPERATION;
382 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800383
384 mTotalBufferCount = maxConsumerBuffers + camera3_stream::max_buffers;
Zhijun He6adc9cc2014-04-15 14:09:55 -0700385 mHandoutTotalBufferCount = 0;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800386 mFrameCount = 0;
387 mLastTimestamp = 0;
388
389 res = native_window_set_buffer_count(mConsumer.get(),
390 mTotalBufferCount);
391 if (res != OK) {
392 ALOGE("%s: Unable to set buffer count for stream %d",
393 __FUNCTION__, mId);
394 return res;
395 }
396
397 res = native_window_set_buffers_transform(mConsumer.get(),
398 mTransform);
399 if (res != OK) {
400 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
401 __FUNCTION__, mTransform, strerror(-res), res);
402 }
403
Zhijun He125684a2015-12-26 15:07:30 -0800404 /**
405 * Camera3 Buffer manager is only supported by HAL3.2 onwards, as the older HALs requires
406 * buffers to be statically allocated for internal static buffer registration, while the
407 * buffers provided by buffer manager are really dynamically allocated. Camera3Device only
408 * sets the mBufferManager if device version is >= HAL3.2, which guarantees that the buffer
409 * manager setup is skipped in below code.
410 */
411 if (mBufferManager != 0 && mSetId > CAMERA3_STREAM_SET_ID_INVALID) {
412 StreamInfo streamInfo(
413 getId(), getStreamSetId(), getWidth(), getHeight(), getFormat(), getDataSpace(),
414 camera3_stream::usage, mTotalBufferCount, /*isConfigured*/true);
415 res = mBufferManager->registerStream(streamInfo);
416 if (res == OK) {
417 // Disable buffer allocation for this BufferQueue, buffer manager will take over
418 // the buffer allocation responsibility.
419 mConsumer->getIGraphicBufferProducer()->allowAllocation(false);
420 mUseBufferManager = true;
421 } else {
422 ALOGE("%s: Unable to register stream %d to camera3 buffer manager, "
423 "(error %d %s), fall back to BufferQueue for buffer management!",
424 __FUNCTION__, mId, res, strerror(-res));
425 }
426 }
427
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800428 return OK;
429}
430
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800431status_t Camera3OutputStream::disconnectLocked() {
432 status_t res;
433
Igor Murashkine3a9f962013-05-08 18:03:15 -0700434 if ((res = Camera3IOStreamBase::disconnectLocked()) != OK) {
435 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800436 }
437
Zhijun He125684a2015-12-26 15:07:30 -0800438 ALOGV("%s: disconnecting stream %d from native window", __FUNCTION__, getId());
439
Igor Murashkine3a9f962013-05-08 18:03:15 -0700440 res = native_window_api_disconnect(mConsumer.get(),
441 NATIVE_WINDOW_API_CAMERA);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800442
443 /**
444 * This is not an error. if client calling process dies, the window will
445 * also die and all calls to it will return DEAD_OBJECT, thus it's already
446 * "disconnected"
447 */
448 if (res == DEAD_OBJECT) {
449 ALOGW("%s: While disconnecting stream %d from native window, the"
450 " native window died from under us", __FUNCTION__, mId);
451 }
452 else if (res != OK) {
Igor Murashkine3a9f962013-05-08 18:03:15 -0700453 ALOGE("%s: Unable to disconnect stream %d from native window "
454 "(error %d %s)",
455 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800456 mState = STATE_ERROR;
457 return res;
458 }
459
Zhijun He125684a2015-12-26 15:07:30 -0800460 // Since device is already idle, there is no getBuffer call to buffer manager, unregister the
461 // stream at this point should be safe.
462 if (mUseBufferManager) {
463 res = mBufferManager->unregisterStream(getId(), getStreamSetId());
464 if (res != OK) {
465 ALOGE("%s: Unable to unregister stream %d from buffer manager "
466 "(error %d %s)", __FUNCTION__, mId, res, strerror(-res));
467 mState = STATE_ERROR;
468 return res;
469 }
470 // Note that, to make prepare/teardown case work, we must not mBufferManager.clear(), as
471 // the stream is still in usable state after this call.
472 mUseBufferManager = false;
473 }
474
Igor Murashkine3a9f962013-05-08 18:03:15 -0700475 mState = (mState == STATE_IN_RECONFIG) ? STATE_IN_CONFIG
476 : STATE_CONSTRUCTED;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800477 return OK;
478}
479
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700480status_t Camera3OutputStream::getEndpointUsage(uint32_t *usage) const {
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700481
482 status_t res;
483 int32_t u = 0;
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700484 res = static_cast<ANativeWindow*>(mConsumer.get())->query(mConsumer.get(),
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700485 NATIVE_WINDOW_CONSUMER_USAGE_BITS, &u);
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700486
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700487 // If an opaque output stream's endpoint is ImageReader, add
488 // GRALLOC_USAGE_HW_CAMERA_ZSL to the usage so HAL knows it will be used
489 // for the ZSL use case.
490 // Assume it's for ImageReader if the consumer usage doesn't have any of these bits set:
491 // 1. GRALLOC_USAGE_HW_TEXTURE
492 // 2. GRALLOC_USAGE_HW_RENDER
493 // 3. GRALLOC_USAGE_HW_COMPOSER
494 // 4. GRALLOC_USAGE_HW_VIDEO_ENCODER
495 if (camera3_stream::format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
496 (u & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER |
497 GRALLOC_USAGE_HW_VIDEO_ENCODER)) == 0) {
498 u |= GRALLOC_USAGE_HW_CAMERA_ZSL;
499 }
500
501 *usage = u;
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700502 return res;
503}
504
Chien-Yu Chen85a64552015-08-28 15:46:12 -0700505bool Camera3OutputStream::isVideoStream() const {
506 uint32_t usage = 0;
507 status_t res = getEndpointUsage(&usage);
508 if (res != OK) {
509 ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
510 return false;
511 }
512
513 return (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) != 0;
514}
515
Zhijun He125684a2015-12-26 15:07:30 -0800516status_t Camera3OutputStream::setBufferManager(sp<Camera3BufferManager> bufferManager) {
517 Mutex::Autolock l(mLock);
518 if (mState != STATE_CONSTRUCTED) {
519 ALOGE("%s: this method can only be called when stream in in CONSTRUCTED state.",
520 __FUNCTION__);
521 return INVALID_OPERATION;
522 }
523 mBufferManager = bufferManager;
524
525 return OK;
526}
527
528void Camera3OutputStream::BufferReleasedListener::onBufferReleased() {
529 sp<Camera3OutputStream> stream = mParent.promote();
530 if (stream == nullptr) {
531 ALOGV("%s: Parent camera3 output stream was destroyed", __FUNCTION__);
532 return;
533 }
534
535 Mutex::Autolock l(stream->mLock);
536 if (!(stream->mUseBufferManager)) {
537 return;
538 }
539
540 sp<Fence> fence;
541 sp<GraphicBuffer> buffer;
542 int fenceFd = -1;
543 status_t res = stream->mConsumer->detachNextBuffer(&buffer, &fence);
544 if (res == NO_MEMORY) {
545 // This may rarely happen, which indicates that the released buffer was freed by other
546 // call (e.g., attachBuffer, dequeueBuffer etc.) before reaching here. We should notify the
547 // buffer manager that this buffer has been freed. It's not fatal, but should be avoided,
548 // therefore log a warning.
549 buffer = 0;
550 ALOGW("%s: the released buffer has already been freed by the buffer queue!", __FUNCTION__);
551 } else if (res != OK) {
552 // Other errors are fatal.
553 ALOGE("%s: detach next buffer failed: %s (%d).", __FUNCTION__, strerror(-res), res);
554 stream->mState = STATE_ERROR;
555 return;
556 }
557
558 if (fence!= 0 && fence->isValid()) {
559 fenceFd = fence->dup();
560 }
561 res = stream->mBufferManager->returnBufferForStream(stream->getId(), stream->getStreamSetId(),
562 buffer, fenceFd);
563 if (res != OK) {
564 ALOGE("%s: return buffer to buffer manager failed: %s (%d).", __FUNCTION__,
565 strerror(-res), res);
566 stream->mState = STATE_ERROR;
567 }
568}
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800569}; // namespace camera3
570
571}; // namespace android