blob: d52d1e3f6efd29f677fe6376d5e363dfcf8bfd86 [file] [log] [blame]
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -08001/*
Shuzhen Wangc28189a2017-11-27 23:05:10 -08002 * Copyright (C) 2013-2018 The Android Open Source Project
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -08003 *
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
Shuzhen Wangabbcb6b2020-12-09 22:32:44 -080021#include <ctime>
22#include <fstream>
23
24#include <android-base/unique_fd.h>
Shuzhen Wange4adddb2021-09-21 15:24:44 -070025#include <cutils/properties.h>
Shuzhen Wangabbcb6b2020-12-09 22:32:44 -080026#include <ui/GraphicBuffer.h>
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080027#include <utils/Log.h>
28#include <utils/Trace.h>
Shuzhen Wangabbcb6b2020-12-09 22:32:44 -080029
30#include "api1/client2/JpegProcessor.h"
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080031#include "Camera3OutputStream.h"
Jayant Chowdharyd4776262020-06-23 23:45:57 -070032#include "utils/TraceHFR.h"
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080033
34#ifndef container_of
35#define container_of(ptr, type, member) \
36 (type *)((char*)(ptr) - offsetof(type, member))
37#endif
38
39namespace android {
40
41namespace camera3 {
42
43Camera3OutputStream::Camera3OutputStream(int id,
Eino-Ville Talvala727d1722015-06-09 13:44:19 -070044 sp<Surface> consumer,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -080045 uint32_t width, uint32_t height, int format,
Emilian Peevf4816702020-04-03 15:44:51 -070046 android_dataspace dataSpace, camera_stream_rotation_t rotation,
Shuzhen Wangc28189a2017-11-27 23:05:10 -080047 nsecs_t timestampOffset, const String8& physicalCameraId,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080048 const std::unordered_set<int32_t> &sensorPixelModesUsed,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -080049 int setId, bool isMultiResolution, int dynamicRangeProfile,
50 int streamUseCase) :
Emilian Peevf4816702020-04-03 15:44:51 -070051 Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
Shuzhen Wangc28189a2017-11-27 23:05:10 -080052 /*maxSize*/0, format, dataSpace, rotation,
Emilian Peev2295df72021-11-12 18:14:10 -080053 physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -080054 dynamicRangeProfile, streamUseCase),
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080055 mConsumer(consumer),
Ruchit Sharmae0711f22014-08-18 13:48:24 -040056 mTransform(0),
Zhijun He125684a2015-12-26 15:07:30 -080057 mTraceFirstBuffer(true),
Shuzhen Wangc28dccc2016-02-11 23:48:46 -080058 mUseBufferManager(false),
Zhijun He5d677d12016-05-29 16:52:39 -070059 mTimestampOffset(timestampOffset),
Shuzhen Wang686f6442017-06-20 16:16:04 -070060 mConsumerUsage(0),
Chien-Yu Chena936ac22017-10-23 15:59:49 -070061 mDropBuffers(false),
Shuzhen Wang686f6442017-06-20 16:16:04 -070062 mDequeueBufferLatency(kDequeueLatencyBinSize) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080063
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080064 if (mConsumer == NULL) {
65 ALOGE("%s: Consumer is NULL!", __FUNCTION__);
66 mState = STATE_ERROR;
67 }
Zhijun He125684a2015-12-26 15:07:30 -080068
Shuzhen Wang0160ddd2019-08-15 09:11:56 -070069 bool needsReleaseNotify = setId > CAMERA3_STREAM_SET_ID_INVALID;
70 mBufferProducerListener = new BufferProducerListener(this, needsReleaseNotify);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080071}
72
73Camera3OutputStream::Camera3OutputStream(int id,
Eino-Ville Talvala727d1722015-06-09 13:44:19 -070074 sp<Surface> consumer,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -080075 uint32_t width, uint32_t height, size_t maxSize, int format,
Emilian Peevf4816702020-04-03 15:44:51 -070076 android_dataspace dataSpace, camera_stream_rotation_t rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080077 nsecs_t timestampOffset, const String8& physicalCameraId,
78 const std::unordered_set<int32_t> &sensorPixelModesUsed,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -080079 int setId, bool isMultiResolution, int dynamicRangeProfile,
80 int streamUseCase) :
Emilian Peevf4816702020-04-03 15:44:51 -070081 Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height, maxSize,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080082 format, dataSpace, rotation, physicalCameraId, sensorPixelModesUsed,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -080083 setId, isMultiResolution, dynamicRangeProfile, streamUseCase),
Igor Murashkina55b5452013-04-02 16:36:33 -070084 mConsumer(consumer),
Ruchit Sharmae0711f22014-08-18 13:48:24 -040085 mTransform(0),
Zhijun He125684a2015-12-26 15:07:30 -080086 mTraceFirstBuffer(true),
Shuzhen Wangc28dccc2016-02-11 23:48:46 -080087 mUseMonoTimestamp(false),
88 mUseBufferManager(false),
Zhijun He5d677d12016-05-29 16:52:39 -070089 mTimestampOffset(timestampOffset),
Shuzhen Wang686f6442017-06-20 16:16:04 -070090 mConsumerUsage(0),
Chien-Yu Chena936ac22017-10-23 15:59:49 -070091 mDropBuffers(false),
Shuzhen Wang686f6442017-06-20 16:16:04 -070092 mDequeueBufferLatency(kDequeueLatencyBinSize) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080093
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -080094 if (format != HAL_PIXEL_FORMAT_BLOB && format != HAL_PIXEL_FORMAT_RAW_OPAQUE) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080095 ALOGE("%s: Bad format for size-only stream: %d", __FUNCTION__,
96 format);
97 mState = STATE_ERROR;
98 }
99
100 if (mConsumer == NULL) {
101 ALOGE("%s: Consumer is NULL!", __FUNCTION__);
102 mState = STATE_ERROR;
103 }
Zhijun He125684a2015-12-26 15:07:30 -0800104
Shuzhen Wang0160ddd2019-08-15 09:11:56 -0700105 bool needsReleaseNotify = setId > CAMERA3_STREAM_SET_ID_INVALID;
106 mBufferProducerListener = new BufferProducerListener(this, needsReleaseNotify);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800107}
108
Zhijun He5d677d12016-05-29 16:52:39 -0700109Camera3OutputStream::Camera3OutputStream(int id,
110 uint32_t width, uint32_t height, int format,
Emilian Peev050f5dc2017-05-18 14:43:56 +0100111 uint64_t consumerUsage, android_dataspace dataSpace,
Emilian Peevf4816702020-04-03 15:44:51 -0700112 camera_stream_rotation_t rotation, nsecs_t timestampOffset,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800113 const String8& physicalCameraId,
114 const std::unordered_set<int32_t> &sensorPixelModesUsed,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800115 int setId, bool isMultiResolution, int dynamicRangeProfile,
116 int streamUseCase) :
Emilian Peevf4816702020-04-03 15:44:51 -0700117 Camera3IOStreamBase(id, CAMERA_STREAM_OUTPUT, width, height,
Shuzhen Wangc28189a2017-11-27 23:05:10 -0800118 /*maxSize*/0, format, dataSpace, rotation,
Emilian Peev2295df72021-11-12 18:14:10 -0800119 physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800120 dynamicRangeProfile, streamUseCase),
Zhijun He5d677d12016-05-29 16:52:39 -0700121 mConsumer(nullptr),
122 mTransform(0),
123 mTraceFirstBuffer(true),
124 mUseBufferManager(false),
125 mTimestampOffset(timestampOffset),
Shuzhen Wang686f6442017-06-20 16:16:04 -0700126 mConsumerUsage(consumerUsage),
Chien-Yu Chena936ac22017-10-23 15:59:49 -0700127 mDropBuffers(false),
Shuzhen Wang686f6442017-06-20 16:16:04 -0700128 mDequeueBufferLatency(kDequeueLatencyBinSize) {
Zhijun He5d677d12016-05-29 16:52:39 -0700129 // Deferred consumer only support preview surface format now.
130 if (format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
131 ALOGE("%s: Deferred consumer only supports IMPLEMENTATION_DEFINED format now!",
132 __FUNCTION__);
133 mState = STATE_ERROR;
134 }
135
Ivan Lozanoc0ad82f2020-07-30 09:32:57 -0400136 // Validation check for the consumer usage flag.
Zhijun He5d677d12016-05-29 16:52:39 -0700137 if ((consumerUsage & GraphicBuffer::USAGE_HW_TEXTURE) == 0 &&
138 (consumerUsage & GraphicBuffer::USAGE_HW_COMPOSER) == 0) {
Emilian Peev050f5dc2017-05-18 14:43:56 +0100139 ALOGE("%s: Deferred consumer usage flag is illegal %" PRIu64 "!",
140 __FUNCTION__, consumerUsage);
Zhijun He5d677d12016-05-29 16:52:39 -0700141 mState = STATE_ERROR;
142 }
143
144 mConsumerName = String8("Deferred");
Shuzhen Wang0160ddd2019-08-15 09:11:56 -0700145 bool needsReleaseNotify = setId > CAMERA3_STREAM_SET_ID_INVALID;
146 mBufferProducerListener = new BufferProducerListener(this, needsReleaseNotify);
Zhijun He5d677d12016-05-29 16:52:39 -0700147}
148
Emilian Peevf4816702020-04-03 15:44:51 -0700149Camera3OutputStream::Camera3OutputStream(int id, camera_stream_type_t type,
Igor Murashkine3a9f962013-05-08 18:03:15 -0700150 uint32_t width, uint32_t height,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800151 int format,
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700152 android_dataspace dataSpace,
Emilian Peevf4816702020-04-03 15:44:51 -0700153 camera_stream_rotation_t rotation,
Shuzhen Wangc28189a2017-11-27 23:05:10 -0800154 const String8& physicalCameraId,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800155 const std::unordered_set<int32_t> &sensorPixelModesUsed,
Emilian Peev050f5dc2017-05-18 14:43:56 +0100156 uint64_t consumerUsage, nsecs_t timestampOffset,
Emilian Peev2295df72021-11-12 18:14:10 -0800157 int setId, bool isMultiResolution,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800158 int dynamicRangeProfile, int streamUseCase) :
Igor Murashkine3a9f962013-05-08 18:03:15 -0700159 Camera3IOStreamBase(id, type, width, height,
160 /*maxSize*/0,
Shuzhen Wangc28189a2017-11-27 23:05:10 -0800161 format, dataSpace, rotation,
Emilian Peev2295df72021-11-12 18:14:10 -0800162 physicalCameraId, sensorPixelModesUsed, setId, isMultiResolution,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800163 dynamicRangeProfile, streamUseCase),
Zhijun He125684a2015-12-26 15:07:30 -0800164 mTransform(0),
165 mTraceFirstBuffer(true),
Shuzhen Wangc28dccc2016-02-11 23:48:46 -0800166 mUseMonoTimestamp(false),
Zhijun He5d677d12016-05-29 16:52:39 -0700167 mUseBufferManager(false),
Shuzhen Wang0129d522016-10-30 22:43:41 -0700168 mTimestampOffset(timestampOffset),
Shuzhen Wang686f6442017-06-20 16:16:04 -0700169 mConsumerUsage(consumerUsage),
Chien-Yu Chena936ac22017-10-23 15:59:49 -0700170 mDropBuffers(false),
Shuzhen Wang686f6442017-06-20 16:16:04 -0700171 mDequeueBufferLatency(kDequeueLatencyBinSize) {
Zhijun He125684a2015-12-26 15:07:30 -0800172
Shuzhen Wang0160ddd2019-08-15 09:11:56 -0700173 bool needsReleaseNotify = setId > CAMERA3_STREAM_SET_ID_INVALID;
174 mBufferProducerListener = new BufferProducerListener(this, needsReleaseNotify);
Igor Murashkine3a9f962013-05-08 18:03:15 -0700175
176 // Subclasses expected to initialize mConsumer themselves
177}
178
179
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800180Camera3OutputStream::~Camera3OutputStream() {
181 disconnectLocked();
182}
183
Emilian Peevf4816702020-04-03 15:44:51 -0700184status_t Camera3OutputStream::getBufferLocked(camera_stream_buffer *buffer,
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800185 const std::vector<size_t>&) {
Jayant Chowdharyd4776262020-06-23 23:45:57 -0700186 ATRACE_HFR_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800187
188 ANativeWindowBuffer* anb;
Zhijun He125684a2015-12-26 15:07:30 -0800189 int fenceFd = -1;
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -0700190
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800191 status_t res;
192 res = getBufferLockedCommon(&anb, &fenceFd);
193 if (res != OK) {
194 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800195 }
196
Igor Murashkine3a9f962013-05-08 18:03:15 -0700197 /**
198 * FenceFD now owned by HAL except in case of error,
199 * in which case we reassign it to acquire_fence
200 */
201 handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
Emilian Peevf4816702020-04-03 15:44:51 -0700202 /*releaseFence*/-1, CAMERA_BUFFER_STATUS_OK, /*output*/true);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800203
204 return OK;
205}
206
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800207status_t Camera3OutputStream::getBuffersLocked(std::vector<OutstandingBuffer>* outBuffers) {
208 status_t res;
209
210 if ((res = getBufferPreconditionCheckLocked()) != OK) {
211 return res;
212 }
213
214 if (mUseBufferManager) {
215 ALOGE("%s: stream %d is managed by buffer manager and does not support batch operation",
216 __FUNCTION__, mId);
217 return INVALID_OPERATION;
218 }
219
220 sp<Surface> consumer = mConsumer;
221 /**
222 * Release the lock briefly to avoid deadlock for below scenario:
223 * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring().
224 * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock.
225 * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable().
226 * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock
227 * StreamingProcessor lock.
228 * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock
229 * and try to lock bufferQueue lock.
230 * Then there is circular locking dependency.
231 */
232 mLock.unlock();
233
234 size_t numBuffersRequested = outBuffers->size();
235 std::vector<Surface::BatchBuffer> buffers(numBuffersRequested);
236
237 nsecs_t dequeueStart = systemTime(SYSTEM_TIME_MONOTONIC);
238 res = consumer->dequeueBuffers(&buffers);
239 nsecs_t dequeueEnd = systemTime(SYSTEM_TIME_MONOTONIC);
240 mDequeueBufferLatency.add(dequeueStart, dequeueEnd);
241
242 mLock.lock();
243
244 if (res != OK) {
245 if (shouldLogError(res, mState)) {
246 ALOGE("%s: Stream %d: Can't dequeue %zu output buffers: %s (%d)",
247 __FUNCTION__, mId, numBuffersRequested, strerror(-res), res);
248 }
249 checkRetAndSetAbandonedLocked(res);
250 return res;
251 }
252 checkRemovedBuffersLocked();
253
254 /**
255 * FenceFD now owned by HAL except in case of error,
256 * in which case we reassign it to acquire_fence
257 */
258 for (size_t i = 0; i < numBuffersRequested; i++) {
259 handoutBufferLocked(*(outBuffers->at(i).outBuffer),
260 &(buffers[i].buffer->handle), /*acquireFence*/buffers[i].fenceFd,
261 /*releaseFence*/-1, CAMERA_BUFFER_STATUS_OK, /*output*/true);
262 }
263 return OK;
264}
265
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800266status_t Camera3OutputStream::queueBufferToConsumer(sp<ANativeWindow>& consumer,
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -0700267 ANativeWindowBuffer* buffer, int anwReleaseFence,
268 const std::vector<size_t>&) {
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800269 return consumer->queueBuffer(consumer.get(), buffer, anwReleaseFence);
270}
271
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800272status_t Camera3OutputStream::returnBufferLocked(
Emilian Peevf4816702020-04-03 15:44:51 -0700273 const camera_stream_buffer &buffer,
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700274 nsecs_t timestamp, nsecs_t readoutTimestamp,
275 int32_t transform, const std::vector<size_t>& surface_ids) {
Jayant Chowdharyd4776262020-06-23 23:45:57 -0700276 ATRACE_HFR_CALL();
Igor Murashkine3a9f962013-05-08 18:03:15 -0700277
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800278 if (mHandoutTotalBufferCount == 1) {
279 returnPrefetchedBuffersLocked();
280 }
281
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700282 status_t res = returnAnyBufferLocked(buffer, timestamp, readoutTimestamp,
283 /*output*/true, transform, surface_ids);
Igor Murashkine3a9f962013-05-08 18:03:15 -0700284
285 if (res != OK) {
286 return res;
287 }
288
289 mLastTimestamp = timestamp;
Eino-Ville Talvalac31dc7e2017-01-31 17:35:41 -0800290 mFrameCount++;
Igor Murashkine3a9f962013-05-08 18:03:15 -0700291
292 return OK;
293}
294
295status_t Camera3OutputStream::returnBufferCheckedLocked(
Emilian Peevf4816702020-04-03 15:44:51 -0700296 const camera_stream_buffer &buffer,
Igor Murashkine3a9f962013-05-08 18:03:15 -0700297 nsecs_t timestamp,
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700298 nsecs_t readoutTimestamp,
Igor Murashkine3a9f962013-05-08 18:03:15 -0700299 bool output,
Emilian Peev5104fe92021-10-21 14:27:09 -0700300 int32_t transform,
Yin-Chia Yeh58b1b4e2018-10-15 12:18:36 -0700301 const std::vector<size_t>& surface_ids,
Igor Murashkine3a9f962013-05-08 18:03:15 -0700302 /*out*/
303 sp<Fence> *releaseFenceOut) {
304
305 (void)output;
306 ALOG_ASSERT(output, "Expected output to be true");
307
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800308 status_t res;
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700309
Yin-Chia Yeh4c9736f2015-03-05 15:01:36 -0800310 // Fence management - always honor release fence from HAL
311 sp<Fence> releaseFence = new Fence(buffer.release_fence);
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700312 int anwReleaseFence = releaseFence->dup();
313
314 /**
Zhijun He124ccf42013-05-22 14:01:30 -0700315 * Release the lock briefly to avoid deadlock with
316 * StreamingProcessor::startStream -> Camera3Stream::isConfiguring (this
317 * thread will go into StreamingProcessor::onFrameAvailable) during
318 * queueBuffer
319 */
320 sp<ANativeWindow> currentConsumer = mConsumer;
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -0700321 StreamState state = mState;
Zhijun He124ccf42013-05-22 14:01:30 -0700322 mLock.unlock();
323
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800324 ANativeWindowBuffer *anwBuffer = container_of(buffer.buffer, ANativeWindowBuffer, handle);
Zhijun He124ccf42013-05-22 14:01:30 -0700325 /**
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700326 * Return buffer back to ANativeWindow
327 */
Emilian Peevf4816702020-04-03 15:44:51 -0700328 if (buffer.status == CAMERA_BUFFER_STATUS_ERROR || mDropBuffers || timestamp == 0) {
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700329 // Cancel buffer
Chien-Yu Chena936ac22017-10-23 15:59:49 -0700330 if (mDropBuffers) {
331 ALOGV("%s: Dropping a frame for stream %d.", __FUNCTION__, mId);
Emilian Peevf4816702020-04-03 15:44:51 -0700332 } else if (buffer.status == CAMERA_BUFFER_STATUS_ERROR) {
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -0700333 ALOGV("%s: A frame is dropped for stream %d due to buffer error.", __FUNCTION__, mId);
Shuzhen Wangf0c4a6b2018-09-05 09:36:14 -0700334 } else {
335 ALOGE("%s: Stream %d: timestamp shouldn't be 0", __FUNCTION__, mId);
Chien-Yu Chena936ac22017-10-23 15:59:49 -0700336 }
337
Zhijun He124ccf42013-05-22 14:01:30 -0700338 res = currentConsumer->cancelBuffer(currentConsumer.get(),
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800339 anwBuffer,
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700340 anwReleaseFence);
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -0700341 if (shouldLogError(res, state)) {
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700342 ALOGE("%s: Stream %d: Error cancelling buffer to native window:"
Igor Murashkine3a9f962013-05-08 18:03:15 -0700343 " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700344 }
Zhijun He1ff811b2016-01-26 14:39:51 -0800345
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800346 notifyBufferReleased(anwBuffer);
Zhijun He1ff811b2016-01-26 14:39:51 -0800347 if (mUseBufferManager) {
348 // Return this buffer back to buffer manager.
Shuzhen Wang0160ddd2019-08-15 09:11:56 -0700349 mBufferProducerListener->onBufferReleased();
Zhijun He1ff811b2016-01-26 14:39:51 -0800350 }
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700351 } else {
Emilian Peevf4816702020-04-03 15:44:51 -0700352 if (mTraceFirstBuffer && (stream_type == CAMERA_STREAM_OUTPUT)) {
Ruchit Sharmae0711f22014-08-18 13:48:24 -0400353 {
354 char traceLog[48];
355 snprintf(traceLog, sizeof(traceLog), "Stream %d: first full buffer\n", mId);
356 ATRACE_NAME(traceLog);
357 }
358 mTraceFirstBuffer = false;
359 }
360
Shuzhen Wangabbcb6b2020-12-09 22:32:44 -0800361 // If this is a JPEG output, and image dump mask is set, save image to
362 // disk.
363 if (getFormat() == HAL_PIXEL_FORMAT_BLOB && getDataSpace() == HAL_DATASPACE_V0_JFIF &&
364 mImageDumpMask) {
365 dumpImageToDisk(timestamp, anwBuffer, anwReleaseFence);
366 }
Yin-Chia Yeh4c9736f2015-03-05 15:01:36 -0800367
Shuzhen Wange4adddb2021-09-21 15:24:44 -0700368 /* Certain consumers (such as AudioSource or HardwareComposer) use
369 * MONOTONIC time, causing time misalignment if camera timestamp is
370 * in BOOTTIME. Do the conversion if necessary. */
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700371 nsecs_t t = mPreviewFrameScheduler != nullptr ? readoutTimestamp : timestamp;
372 nsecs_t adjustedTs = mUseMonoTimestamp ? t - mTimestampOffset : t;
Shuzhen Wange4adddb2021-09-21 15:24:44 -0700373 if (mPreviewFrameScheduler != nullptr) {
374 res = mPreviewFrameScheduler->queuePreviewBuffer(adjustedTs, transform,
375 anwBuffer, anwReleaseFence);
376 if (res != OK) {
377 ALOGE("%s: Stream %d: Error queuing buffer to preview buffer scheduler: %s (%d)",
378 __FUNCTION__, mId, strerror(-res), res);
379 return res;
380 }
381 } else {
382 setTransform(transform);
383 res = native_window_set_buffers_timestamp(mConsumer.get(), adjustedTs);
384 if (res != OK) {
385 ALOGE("%s: Stream %d: Error setting timestamp: %s (%d)",
386 __FUNCTION__, mId, strerror(-res), res);
387 return res;
388 }
Emilian Peev2295df72021-11-12 18:14:10 -0800389
390 queueHDRMetadata(anwBuffer->handle, currentConsumer, dynamic_range_profile);
391
Shuzhen Wange4adddb2021-09-21 15:24:44 -0700392 res = queueBufferToConsumer(currentConsumer, anwBuffer, anwReleaseFence, surface_ids);
393 if (shouldLogError(res, state)) {
394 ALOGE("%s: Stream %d: Error queueing buffer to native window:"
395 " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
396 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800397 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800398 }
Zhijun He124ccf42013-05-22 14:01:30 -0700399 mLock.lock();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700400
401 // Once a valid buffer has been returned to the queue, can no longer
402 // dequeue all buffers for preallocation.
Emilian Peevf4816702020-04-03 15:44:51 -0700403 if (buffer.status != CAMERA_BUFFER_STATUS_ERROR) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700404 mStreamUnpreparable = true;
405 }
406
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700407 if (res != OK) {
408 close(anwReleaseFence);
Igor Murashkin5a1798a2013-05-07 10:58:13 -0700409 }
410
Igor Murashkine3a9f962013-05-08 18:03:15 -0700411 *releaseFenceOut = releaseFence;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800412
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700413 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800414}
415
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800416void Camera3OutputStream::dump(int fd, const Vector<String16> &args) const {
417 (void) args;
418 String8 lines;
419 lines.appendFormat(" Stream[%d]: Output\n", mId);
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700420 lines.appendFormat(" Consumer name: %s\n", mConsumerName.string());
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800421 write(fd, lines.string(), lines.size());
Igor Murashkine3a9f962013-05-08 18:03:15 -0700422
423 Camera3IOStreamBase::dump(fd, args);
Shuzhen Wang686f6442017-06-20 16:16:04 -0700424
425 mDequeueBufferLatency.dump(fd,
426 " DequeueBuffer latency histogram:");
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800427}
428
429status_t Camera3OutputStream::setTransform(int transform) {
430 ATRACE_CALL();
431 Mutex::Autolock l(mLock);
432 return setTransformLocked(transform);
433}
434
435status_t Camera3OutputStream::setTransformLocked(int transform) {
436 status_t res = OK;
Shuzhen Wange4adddb2021-09-21 15:24:44 -0700437
438 if (transform == -1) return res;
439
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800440 if (mState == STATE_ERROR) {
441 ALOGE("%s: Stream in error state", __FUNCTION__);
442 return INVALID_OPERATION;
443 }
444
445 mTransform = transform;
446 if (mState == STATE_CONFIGURED) {
447 res = native_window_set_buffers_transform(mConsumer.get(),
448 transform);
449 if (res != OK) {
450 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
451 __FUNCTION__, transform, strerror(-res), res);
452 }
453 }
454 return res;
455}
456
457status_t Camera3OutputStream::configureQueueLocked() {
458 status_t res;
459
Ruchit Sharmae0711f22014-08-18 13:48:24 -0400460 mTraceFirstBuffer = true;
Igor Murashkine3a9f962013-05-08 18:03:15 -0700461 if ((res = Camera3IOStreamBase::configureQueueLocked()) != OK) {
462 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800463 }
464
Shuzhen Wange4adddb2021-09-21 15:24:44 -0700465 if ((res = configureConsumerQueueLocked(true /*allowPreviewScheduler*/)) != OK) {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700466 return res;
467 }
468
469 // Set dequeueBuffer/attachBuffer timeout if the consumer is not hw composer or hw texture.
470 // We need skip these cases as timeout will disable the non-blocking (async) mode.
471 if (!(isConsumedByHWComposer() || isConsumedByHWTexture())) {
Yin-Chia Yehbf1b8b92019-03-06 14:56:08 -0800472 if (mUseBufferManager) {
473 // When buffer manager is handling the buffer, we should have available buffers in
474 // buffer queue before we calls into dequeueBuffer because buffer manager is tracking
475 // free buffers.
476 // There are however some consumer side feature (ImageReader::discardFreeBuffers) that
477 // can discard free buffers without notifying buffer manager. We want the timeout to
478 // happen immediately here so buffer manager can try to update its internal state and
479 // try to allocate a buffer instead of waiting.
480 mConsumer->setDequeueTimeout(0);
481 } else {
482 mConsumer->setDequeueTimeout(kDequeueBufferTimeout);
483 }
Shuzhen Wang0129d522016-10-30 22:43:41 -0700484 }
485
486 return OK;
487}
488
Shuzhen Wange4adddb2021-09-21 15:24:44 -0700489status_t Camera3OutputStream::configureConsumerQueueLocked(bool allowPreviewScheduler) {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700490 status_t res;
491
492 mTraceFirstBuffer = true;
493
Igor Murashkine3a9f962013-05-08 18:03:15 -0700494 ALOG_ASSERT(mConsumer != 0, "mConsumer should never be NULL");
495
Zhijun He125684a2015-12-26 15:07:30 -0800496 // Configure consumer-side ANativeWindow interface. The listener may be used
497 // to notify buffer manager (if it is used) of the returned buffers.
Yin-Chia Yeh017d49c2017-03-31 19:11:00 -0700498 res = mConsumer->connect(NATIVE_WINDOW_API_CAMERA,
Shuzhen Wang0160ddd2019-08-15 09:11:56 -0700499 /*reportBufferRemoval*/true,
500 /*listener*/mBufferProducerListener);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800501 if (res != OK) {
502 ALOGE("%s: Unable to connect to native window for stream %d",
503 __FUNCTION__, mId);
504 return res;
505 }
506
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700507 mConsumerName = mConsumer->getConsumerName();
508
Emilian Peev050f5dc2017-05-18 14:43:56 +0100509 res = native_window_set_usage(mConsumer.get(), mUsage);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800510 if (res != OK) {
Emilian Peev050f5dc2017-05-18 14:43:56 +0100511 ALOGE("%s: Unable to configure usage %" PRIu64 " for stream %d",
512 __FUNCTION__, mUsage, mId);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800513 return res;
514 }
515
516 res = native_window_set_scaling_mode(mConsumer.get(),
517 NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
518 if (res != OK) {
519 ALOGE("%s: Unable to configure stream scaling: %s (%d)",
520 __FUNCTION__, strerror(-res), res);
521 return res;
522 }
523
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800524 if (mMaxSize == 0) {
525 // For buffers of known size
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -0700526 res = native_window_set_buffers_dimensions(mConsumer.get(),
Emilian Peevf4816702020-04-03 15:44:51 -0700527 camera_stream::width, camera_stream::height);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800528 } else {
529 // For buffers with bounded size
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -0700530 res = native_window_set_buffers_dimensions(mConsumer.get(),
531 mMaxSize, 1);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800532 }
533 if (res != OK) {
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -0700534 ALOGE("%s: Unable to configure stream buffer dimensions"
535 " %d x %d (maxSize %zu) for stream %d",
Emilian Peevf4816702020-04-03 15:44:51 -0700536 __FUNCTION__, camera_stream::width, camera_stream::height,
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -0700537 mMaxSize, mId);
538 return res;
539 }
540 res = native_window_set_buffers_format(mConsumer.get(),
Emilian Peevf4816702020-04-03 15:44:51 -0700541 camera_stream::format);
Eino-Ville Talvala7d70c5e2014-07-24 18:10:23 -0700542 if (res != OK) {
543 ALOGE("%s: Unable to configure stream buffer format %#x for stream %d",
Emilian Peevf4816702020-04-03 15:44:51 -0700544 __FUNCTION__, camera_stream::format, mId);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800545 return res;
546 }
547
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800548 res = native_window_set_buffers_data_space(mConsumer.get(),
Emilian Peevf4816702020-04-03 15:44:51 -0700549 camera_stream::data_space);
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800550 if (res != OK) {
551 ALOGE("%s: Unable to configure stream dataspace %#x for stream %d",
Emilian Peevf4816702020-04-03 15:44:51 -0700552 __FUNCTION__, camera_stream::data_space, mId);
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800553 return res;
554 }
555
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800556 int maxConsumerBuffers;
Eino-Ville Talvala727d1722015-06-09 13:44:19 -0700557 res = static_cast<ANativeWindow*>(mConsumer.get())->query(
558 mConsumer.get(),
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800559 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
560 if (res != OK) {
561 ALOGE("%s: Unable to query consumer undequeued"
562 " buffer count for stream %d", __FUNCTION__, mId);
563 return res;
564 }
565
Alex Ray20cb3002013-05-28 20:18:22 -0700566 ALOGV("%s: Consumer wants %d buffers, HAL wants %d", __FUNCTION__,
Emilian Peevf4816702020-04-03 15:44:51 -0700567 maxConsumerBuffers, camera_stream::max_buffers);
568 if (camera_stream::max_buffers == 0) {
Zhijun He2ab500c2013-07-23 08:02:53 -0700569 ALOGE("%s: Camera HAL requested max_buffer count: %d, requires at least 1",
Emilian Peevf4816702020-04-03 15:44:51 -0700570 __FUNCTION__, camera_stream::max_buffers);
Alex Ray20cb3002013-05-28 20:18:22 -0700571 return INVALID_OPERATION;
572 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800573
Emilian Peevf4816702020-04-03 15:44:51 -0700574 mTotalBufferCount = maxConsumerBuffers + camera_stream::max_buffers;
Shuzhen Wange4adddb2021-09-21 15:24:44 -0700575 if (allowPreviewScheduler && isConsumedByHWComposer()) {
576 // We cannot distinguish between a SurfaceView and an ImageReader of
577 // preview buffer format. The PreviewFrameScheduler needs to handle both.
578 if (!property_get_bool("camera.disable_preview_scheduler", false)) {
579 mPreviewFrameScheduler = std::make_unique<PreviewFrameScheduler>(*this, mConsumer);
580 mTotalBufferCount += PreviewFrameScheduler::kQueueDepthWatermark;
581 }
582 }
583
Zhijun He6adc9cc2014-04-15 14:09:55 -0700584 mHandoutTotalBufferCount = 0;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800585 mFrameCount = 0;
586 mLastTimestamp = 0;
Shuzhen Wangc28dccc2016-02-11 23:48:46 -0800587 mUseMonoTimestamp = (isConsumedByHWComposer() | isVideoStream());
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800588
589 res = native_window_set_buffer_count(mConsumer.get(),
590 mTotalBufferCount);
591 if (res != OK) {
592 ALOGE("%s: Unable to set buffer count for stream %d",
593 __FUNCTION__, mId);
594 return res;
595 }
596
597 res = native_window_set_buffers_transform(mConsumer.get(),
598 mTransform);
599 if (res != OK) {
600 ALOGE("%s: Unable to configure stream transform to %x: %s (%d)",
601 __FUNCTION__, mTransform, strerror(-res), res);
Shuzhen Wang0129d522016-10-30 22:43:41 -0700602 return res;
Zhijun Hef0645c12016-08-02 00:58:11 -0700603 }
604
Zhijun He125684a2015-12-26 15:07:30 -0800605 /**
Zhijun Heedd41ae2016-02-03 14:45:53 -0800606 * Camera3 Buffer manager is only supported by HAL3.3 onwards, as the older HALs requires
Zhijun He125684a2015-12-26 15:07:30 -0800607 * buffers to be statically allocated for internal static buffer registration, while the
608 * buffers provided by buffer manager are really dynamically allocated. Camera3Device only
Zhijun Heedd41ae2016-02-03 14:45:53 -0800609 * sets the mBufferManager if device version is > HAL3.2, which guarantees that the buffer
610 * manager setup is skipped in below code. Note that HAL3.2 is also excluded here, as some
611 * HAL3.2 devices may not support the dynamic buffer registeration.
Yin-Chia Yehb6578902019-04-16 13:36:16 -0700612 * Also Camera3BufferManager does not support display/texture streams as they have its own
613 * buffer management logic.
Zhijun He125684a2015-12-26 15:07:30 -0800614 */
Yin-Chia Yehb6578902019-04-16 13:36:16 -0700615 if (mBufferManager != 0 && mSetId > CAMERA3_STREAM_SET_ID_INVALID &&
616 !(isConsumedByHWComposer() || isConsumedByHWTexture())) {
Emilian Peev050f5dc2017-05-18 14:43:56 +0100617 uint64_t consumerUsage = 0;
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -0700618 getEndpointUsage(&consumerUsage);
Shuzhen Wang83bff122020-11-20 15:51:39 -0800619 uint32_t width = (mMaxSize == 0) ? getWidth() : mMaxSize;
620 uint32_t height = (mMaxSize == 0) ? getHeight() : 1;
Zhijun He125684a2015-12-26 15:07:30 -0800621 StreamInfo streamInfo(
Shuzhen Wang83bff122020-11-20 15:51:39 -0800622 getId(), getStreamSetId(), width, height, getFormat(), getDataSpace(),
Emilian Peev050f5dc2017-05-18 14:43:56 +0100623 mUsage | consumerUsage, mTotalBufferCount,
Shuzhen Wang83bff122020-11-20 15:51:39 -0800624 /*isConfigured*/true, isMultiResolution());
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -0700625 wp<Camera3OutputStream> weakThis(this);
626 res = mBufferManager->registerStream(weakThis,
627 streamInfo);
Zhijun He125684a2015-12-26 15:07:30 -0800628 if (res == OK) {
629 // Disable buffer allocation for this BufferQueue, buffer manager will take over
630 // the buffer allocation responsibility.
631 mConsumer->getIGraphicBufferProducer()->allowAllocation(false);
632 mUseBufferManager = true;
633 } else {
634 ALOGE("%s: Unable to register stream %d to camera3 buffer manager, "
635 "(error %d %s), fall back to BufferQueue for buffer management!",
636 __FUNCTION__, mId, res, strerror(-res));
637 }
638 }
639
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800640 return OK;
641}
642
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800643status_t Camera3OutputStream::getBufferLockedCommon(ANativeWindowBuffer** anb, int* fenceFd) {
Jayant Chowdharyd4776262020-06-23 23:45:57 -0700644 ATRACE_HFR_CALL();
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800645 status_t res;
646
647 if ((res = getBufferPreconditionCheckLocked()) != OK) {
648 return res;
649 }
650
651 bool gotBufferFromManager = false;
652
653 if (mUseBufferManager) {
654 sp<GraphicBuffer> gb;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800655 res = mBufferManager->getBufferForStream(getId(), getStreamSetId(),
656 isMultiResolution(), &gb, fenceFd);
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800657 if (res == OK) {
658 // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after a
659 // successful return.
660 *anb = gb.get();
661 res = mConsumer->attachBuffer(*anb);
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -0700662 if (shouldLogError(res, mState)) {
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800663 ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)",
664 __FUNCTION__, mId, strerror(-res), res);
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -0700665 }
666 if (res != OK) {
Yin-Chia Yehbf1b8b92019-03-06 14:56:08 -0800667 checkRetAndSetAbandonedLocked(res);
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800668 return res;
669 }
670 gotBufferFromManager = true;
671 ALOGV("Stream %d: Attached new buffer", getId());
672 } else if (res == ALREADY_EXISTS) {
673 // Have sufficient free buffers already attached, can just
674 // dequeue from buffer queue
675 ALOGV("Stream %d: Reusing attached buffer", getId());
676 gotBufferFromManager = false;
677 } else if (res != OK) {
678 ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager: %s (%d)",
679 __FUNCTION__, mId, strerror(-res), res);
680 return res;
681 }
682 }
683 if (!gotBufferFromManager) {
684 /**
685 * Release the lock briefly to avoid deadlock for below scenario:
686 * Thread 1: StreamingProcessor::startStream -> Camera3Stream::isConfiguring().
687 * This thread acquired StreamingProcessor lock and try to lock Camera3Stream lock.
688 * Thread 2: Camera3Stream::returnBuffer->StreamingProcessor::onFrameAvailable().
689 * This thread acquired Camera3Stream lock and bufferQueue lock, and try to lock
690 * StreamingProcessor lock.
691 * Thread 3: Camera3Stream::getBuffer(). This thread acquired Camera3Stream lock
692 * and try to lock bufferQueue lock.
693 * Then there is circular locking dependency.
694 */
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800695 sp<Surface> consumer = mConsumer;
Shuzhen Wang6c14e312021-07-05 16:20:33 -0700696 size_t remainingBuffers = (mState == STATE_PREPARING ? mTotalBufferCount :
697 camera_stream::max_buffers) - mHandoutTotalBufferCount;
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800698 mLock.unlock();
699
Shuzhen Wang686f6442017-06-20 16:16:04 -0700700 nsecs_t dequeueStart = systemTime(SYSTEM_TIME_MONOTONIC);
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800701
Shuzhen Wangc7629462021-07-12 15:02:58 -0700702 size_t batchSize = mBatchSize.load();
703 if (batchSize == 1) {
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800704 sp<ANativeWindow> anw = consumer;
705 res = anw->dequeueBuffer(anw.get(), anb, fenceFd);
706 } else {
Shuzhen Wangc7629462021-07-12 15:02:58 -0700707 std::unique_lock<std::mutex> batchLock(mBatchLock);
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800708 res = OK;
709 if (mBatchedBuffers.size() == 0) {
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800710 if (remainingBuffers == 0) {
711 ALOGE("%s: cannot get buffer while all buffers are handed out", __FUNCTION__);
712 return INVALID_OPERATION;
713 }
714 if (batchSize > remainingBuffers) {
715 batchSize = remainingBuffers;
716 }
Shuzhen Wangc7629462021-07-12 15:02:58 -0700717 batchLock.unlock();
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800718 // Refill batched buffers
Shuzhen Wangc7629462021-07-12 15:02:58 -0700719 std::vector<Surface::BatchBuffer> batchedBuffers;
720 batchedBuffers.resize(batchSize);
721 res = consumer->dequeueBuffers(&batchedBuffers);
722 batchLock.lock();
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800723 if (res != OK) {
724 ALOGE("%s: batch dequeueBuffers call failed! %s (%d)",
725 __FUNCTION__, strerror(-res), res);
Shuzhen Wangc7629462021-07-12 15:02:58 -0700726 } else {
727 mBatchedBuffers = std::move(batchedBuffers);
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800728 }
729 }
730
731 if (res == OK) {
732 // Dispatch batch buffers
733 *anb = mBatchedBuffers.back().buffer;
734 *fenceFd = mBatchedBuffers.back().fenceFd;
735 mBatchedBuffers.pop_back();
736 }
737 }
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800738
Shuzhen Wang686f6442017-06-20 16:16:04 -0700739 nsecs_t dequeueEnd = systemTime(SYSTEM_TIME_MONOTONIC);
740 mDequeueBufferLatency.add(dequeueStart, dequeueEnd);
741
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800742 mLock.lock();
Yin-Chia Yehbf1b8b92019-03-06 14:56:08 -0800743
744 if (mUseBufferManager && res == TIMED_OUT) {
745 checkRemovedBuffersLocked();
746
747 sp<GraphicBuffer> gb;
748 res = mBufferManager->getBufferForStream(
Shuzhen Wang83bff122020-11-20 15:51:39 -0800749 getId(), getStreamSetId(), isMultiResolution(),
750 &gb, fenceFd, /*noFreeBuffer*/true);
Yin-Chia Yehbf1b8b92019-03-06 14:56:08 -0800751
752 if (res == OK) {
753 // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after
754 // a successful return.
755 *anb = gb.get();
756 res = mConsumer->attachBuffer(*anb);
757 gotBufferFromManager = true;
758 ALOGV("Stream %d: Attached new buffer", getId());
759
760 if (res != OK) {
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -0700761 if (shouldLogError(res, mState)) {
762 ALOGE("%s: Stream %d: Can't attach the output buffer to this surface:"
763 " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
764 }
Yin-Chia Yehbf1b8b92019-03-06 14:56:08 -0800765 checkRetAndSetAbandonedLocked(res);
766 return res;
767 }
768 } else {
769 ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager:"
770 " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
771 return res;
772 }
773 } else if (res != OK) {
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -0700774 if (shouldLogError(res, mState)) {
775 ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
776 __FUNCTION__, mId, strerror(-res), res);
777 }
Yin-Chia Yehbf1b8b92019-03-06 14:56:08 -0800778 checkRetAndSetAbandonedLocked(res);
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800779 return res;
780 }
781 }
782
Yin-Chia Yeh017d49c2017-03-31 19:11:00 -0700783 if (res == OK) {
Yin-Chia Yehbf1b8b92019-03-06 14:56:08 -0800784 checkRemovedBuffersLocked();
Yin-Chia Yeh017d49c2017-03-31 19:11:00 -0700785 }
786
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800787 return res;
788}
789
Yin-Chia Yehbf1b8b92019-03-06 14:56:08 -0800790void Camera3OutputStream::checkRemovedBuffersLocked(bool notifyBufferManager) {
791 std::vector<sp<GraphicBuffer>> removedBuffers;
792 status_t res = mConsumer->getAndFlushRemovedBuffers(&removedBuffers);
793 if (res == OK) {
794 onBuffersRemovedLocked(removedBuffers);
795
796 if (notifyBufferManager && mUseBufferManager && removedBuffers.size() > 0) {
Shuzhen Wang83bff122020-11-20 15:51:39 -0800797 mBufferManager->onBuffersRemoved(getId(), getStreamSetId(), isMultiResolution(),
798 removedBuffers.size());
Yin-Chia Yehbf1b8b92019-03-06 14:56:08 -0800799 }
800 }
801}
802
803void Camera3OutputStream::checkRetAndSetAbandonedLocked(status_t res) {
804 // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is
805 // STATE_PREPARING, let prepareNextBuffer handle the error.)
806 if ((res == NO_INIT || res == DEAD_OBJECT) && mState == STATE_CONFIGURED) {
807 mState = STATE_ABANDONED;
808 }
809}
810
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -0700811bool Camera3OutputStream::shouldLogError(status_t res, StreamState state) {
812 if (res == OK) {
813 return false;
814 }
815 if ((res == DEAD_OBJECT || res == NO_INIT) && state == STATE_ABANDONED) {
816 return false;
817 }
818 return true;
819}
820
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800821status_t Camera3OutputStream::disconnectLocked() {
822 status_t res;
823
Igor Murashkine3a9f962013-05-08 18:03:15 -0700824 if ((res = Camera3IOStreamBase::disconnectLocked()) != OK) {
825 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800826 }
827
Zhijun He5d677d12016-05-29 16:52:39 -0700828 // Stream configuration was not finished (can only be in STATE_IN_CONFIG or STATE_CONSTRUCTED
829 // state), don't need change the stream state, return OK.
830 if (mConsumer == nullptr) {
831 return OK;
832 }
833
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800834 returnPrefetchedBuffersLocked();
835
Zhijun He125684a2015-12-26 15:07:30 -0800836 ALOGV("%s: disconnecting stream %d from native window", __FUNCTION__, getId());
837
Igor Murashkine3a9f962013-05-08 18:03:15 -0700838 res = native_window_api_disconnect(mConsumer.get(),
839 NATIVE_WINDOW_API_CAMERA);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800840 /**
841 * This is not an error. if client calling process dies, the window will
842 * also die and all calls to it will return DEAD_OBJECT, thus it's already
843 * "disconnected"
844 */
845 if (res == DEAD_OBJECT) {
846 ALOGW("%s: While disconnecting stream %d from native window, the"
847 " native window died from under us", __FUNCTION__, mId);
848 }
849 else if (res != OK) {
Igor Murashkine3a9f962013-05-08 18:03:15 -0700850 ALOGE("%s: Unable to disconnect stream %d from native window "
851 "(error %d %s)",
852 __FUNCTION__, mId, res, strerror(-res));
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800853 mState = STATE_ERROR;
854 return res;
855 }
856
Zhijun He125684a2015-12-26 15:07:30 -0800857 // Since device is already idle, there is no getBuffer call to buffer manager, unregister the
858 // stream at this point should be safe.
859 if (mUseBufferManager) {
Shuzhen Wang83bff122020-11-20 15:51:39 -0800860 res = mBufferManager->unregisterStream(getId(), getStreamSetId(), isMultiResolution());
Zhijun He125684a2015-12-26 15:07:30 -0800861 if (res != OK) {
862 ALOGE("%s: Unable to unregister stream %d from buffer manager "
863 "(error %d %s)", __FUNCTION__, mId, res, strerror(-res));
864 mState = STATE_ERROR;
865 return res;
866 }
867 // Note that, to make prepare/teardown case work, we must not mBufferManager.clear(), as
868 // the stream is still in usable state after this call.
869 mUseBufferManager = false;
870 }
871
Igor Murashkine3a9f962013-05-08 18:03:15 -0700872 mState = (mState == STATE_IN_RECONFIG) ? STATE_IN_CONFIG
873 : STATE_CONSTRUCTED;
Shuzhen Wang686f6442017-06-20 16:16:04 -0700874
875 mDequeueBufferLatency.log("Stream %d dequeueBuffer latency histogram", mId);
876 mDequeueBufferLatency.reset();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800877 return OK;
878}
879
Emilian Peev050f5dc2017-05-18 14:43:56 +0100880status_t Camera3OutputStream::getEndpointUsage(uint64_t *usage) const {
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700881
882 status_t res;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700883
Zhijun He5d677d12016-05-29 16:52:39 -0700884 if (mConsumer == nullptr) {
885 // mConsumerUsage was sanitized before the Camera3OutputStream was constructed.
886 *usage = mConsumerUsage;
887 return OK;
888 }
889
Shuzhen Wang0129d522016-10-30 22:43:41 -0700890 res = getEndpointUsageForSurface(usage, mConsumer);
891
892 return res;
893}
894
Emilian Peev35ae8262018-11-08 13:11:32 +0000895void Camera3OutputStream::applyZSLUsageQuirk(int format, uint64_t *consumerUsage /*inout*/) {
896 if (consumerUsage == nullptr) {
897 return;
898 }
Shuzhen Wang0129d522016-10-30 22:43:41 -0700899
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700900 // If an opaque output stream's endpoint is ImageReader, add
Yin-Chia Yeh47cf8e62017-04-04 13:00:03 -0700901 // GRALLOC_USAGE_HW_CAMERA_ZSL to the usage so HAL knows it will be used
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700902 // for the ZSL use case.
903 // Assume it's for ImageReader if the consumer usage doesn't have any of these bits set:
904 // 1. GRALLOC_USAGE_HW_TEXTURE
905 // 2. GRALLOC_USAGE_HW_RENDER
906 // 3. GRALLOC_USAGE_HW_COMPOSER
907 // 4. GRALLOC_USAGE_HW_VIDEO_ENCODER
Emilian Peev35ae8262018-11-08 13:11:32 +0000908 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED &&
909 (*consumerUsage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
Shuzhen Wang0129d522016-10-30 22:43:41 -0700910 GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_VIDEO_ENCODER)) == 0) {
Emilian Peev35ae8262018-11-08 13:11:32 +0000911 *consumerUsage |= GRALLOC_USAGE_HW_CAMERA_ZSL;
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700912 }
Emilian Peev35ae8262018-11-08 13:11:32 +0000913}
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700914
Emilian Peev35ae8262018-11-08 13:11:32 +0000915status_t Camera3OutputStream::getEndpointUsageForSurface(uint64_t *usage,
916 const sp<Surface>& surface) const {
917 status_t res;
918 uint64_t u = 0;
919
920 res = native_window_get_consumer_usage(static_cast<ANativeWindow*>(surface.get()), &u);
Emilian Peevf4816702020-04-03 15:44:51 -0700921 applyZSLUsageQuirk(camera_stream::format, &u);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700922 *usage = u;
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700923 return res;
924}
925
Chien-Yu Chen85a64552015-08-28 15:46:12 -0700926bool Camera3OutputStream::isVideoStream() const {
Emilian Peev050f5dc2017-05-18 14:43:56 +0100927 uint64_t usage = 0;
Chien-Yu Chen85a64552015-08-28 15:46:12 -0700928 status_t res = getEndpointUsage(&usage);
929 if (res != OK) {
930 ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
931 return false;
932 }
933
934 return (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) != 0;
935}
936
Zhijun He125684a2015-12-26 15:07:30 -0800937status_t Camera3OutputStream::setBufferManager(sp<Camera3BufferManager> bufferManager) {
938 Mutex::Autolock l(mLock);
939 if (mState != STATE_CONSTRUCTED) {
Zhijun He5d677d12016-05-29 16:52:39 -0700940 ALOGE("%s: this method can only be called when stream in CONSTRUCTED state.",
Zhijun He125684a2015-12-26 15:07:30 -0800941 __FUNCTION__);
942 return INVALID_OPERATION;
943 }
944 mBufferManager = bufferManager;
945
946 return OK;
947}
948
Emilian Peev40ead602017-09-26 15:46:36 +0100949status_t Camera3OutputStream::updateStream(const std::vector<sp<Surface>> &/*outputSurfaces*/,
950 const std::vector<OutputStreamInfo> &/*outputInfo*/,
951 const std::vector<size_t> &/*removedSurfaceIds*/,
952 KeyedVector<sp<Surface>, size_t> * /*outputMapo*/) {
953 ALOGE("%s: this method is not supported!", __FUNCTION__);
954 return INVALID_OPERATION;
955}
956
Shuzhen Wang0160ddd2019-08-15 09:11:56 -0700957void Camera3OutputStream::BufferProducerListener::onBufferReleased() {
Zhijun He125684a2015-12-26 15:07:30 -0800958 sp<Camera3OutputStream> stream = mParent.promote();
959 if (stream == nullptr) {
960 ALOGV("%s: Parent camera3 output stream was destroyed", __FUNCTION__);
961 return;
962 }
963
964 Mutex::Autolock l(stream->mLock);
965 if (!(stream->mUseBufferManager)) {
966 return;
967 }
968
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -0700969 ALOGV("Stream %d: Buffer released", stream->getId());
Yin-Chia Yeh89954d92017-05-21 17:28:53 -0700970 bool shouldFreeBuffer = false;
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -0700971 status_t res = stream->mBufferManager->onBufferReleased(
Shuzhen Wang83bff122020-11-20 15:51:39 -0800972 stream->getId(), stream->getStreamSetId(), stream->isMultiResolution(),
973 &shouldFreeBuffer);
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -0700974 if (res != OK) {
975 ALOGE("%s: signaling buffer release to buffer manager failed: %s (%d).", __FUNCTION__,
976 strerror(-res), res);
977 stream->mState = STATE_ERROR;
978 }
Yin-Chia Yeh89954d92017-05-21 17:28:53 -0700979
980 if (shouldFreeBuffer) {
981 sp<GraphicBuffer> buffer;
982 // Detach and free a buffer (when buffer goes out of scope)
983 stream->detachBufferLocked(&buffer, /*fenceFd*/ nullptr);
984 if (buffer.get() != nullptr) {
985 stream->mBufferManager->notifyBufferRemoved(
Shuzhen Wang83bff122020-11-20 15:51:39 -0800986 stream->getId(), stream->getStreamSetId(), stream->isMultiResolution());
Yin-Chia Yeh89954d92017-05-21 17:28:53 -0700987 }
988 }
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -0700989}
990
Shuzhen Wang0160ddd2019-08-15 09:11:56 -0700991void Camera3OutputStream::BufferProducerListener::onBuffersDiscarded(
992 const std::vector<sp<GraphicBuffer>>& buffers) {
993 sp<Camera3OutputStream> stream = mParent.promote();
994 if (stream == nullptr) {
995 ALOGV("%s: Parent camera3 output stream was destroyed", __FUNCTION__);
996 return;
997 }
998
999 if (buffers.size() > 0) {
1000 Mutex::Autolock l(stream->mLock);
1001 stream->onBuffersRemovedLocked(buffers);
1002 if (stream->mUseBufferManager) {
1003 stream->mBufferManager->onBuffersRemoved(stream->getId(),
Shuzhen Wang83bff122020-11-20 15:51:39 -08001004 stream->getStreamSetId(), stream->isMultiResolution(), buffers.size());
Shuzhen Wang0160ddd2019-08-15 09:11:56 -07001005 }
1006 ALOGV("Stream %d: %zu Buffers discarded.", stream->getId(), buffers.size());
1007 }
1008}
1009
Yin-Chia Yeh017d49c2017-03-31 19:11:00 -07001010void Camera3OutputStream::onBuffersRemovedLocked(
1011 const std::vector<sp<GraphicBuffer>>& removedBuffers) {
Yin-Chia Yehdb1e8642017-07-14 15:19:30 -07001012 sp<Camera3StreamBufferFreedListener> callback = mBufferFreedListener.promote();
Yin-Chia Yeh017d49c2017-03-31 19:11:00 -07001013 if (callback != nullptr) {
Chih-Hung Hsieh48fc6192017-08-04 14:37:31 -07001014 for (const auto& gb : removedBuffers) {
Yin-Chia Yeh017d49c2017-03-31 19:11:00 -07001015 callback->onBufferFreed(mId, gb->handle);
1016 }
1017 }
1018}
1019
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07001020status_t Camera3OutputStream::detachBuffer(sp<GraphicBuffer>* buffer, int* fenceFd) {
1021 Mutex::Autolock l(mLock);
Yin-Chia Yeh89954d92017-05-21 17:28:53 -07001022 return detachBufferLocked(buffer, fenceFd);
1023}
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07001024
Yin-Chia Yeh89954d92017-05-21 17:28:53 -07001025status_t Camera3OutputStream::detachBufferLocked(sp<GraphicBuffer>* buffer, int* fenceFd) {
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07001026 ALOGV("Stream %d: detachBuffer", getId());
1027 if (buffer == nullptr) {
1028 return BAD_VALUE;
1029 }
1030
Zhijun He125684a2015-12-26 15:07:30 -08001031 sp<Fence> fence;
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07001032 status_t res = mConsumer->detachNextBuffer(buffer, &fence);
Zhijun He125684a2015-12-26 15:07:30 -08001033 if (res == NO_MEMORY) {
1034 // This may rarely happen, which indicates that the released buffer was freed by other
1035 // call (e.g., attachBuffer, dequeueBuffer etc.) before reaching here. We should notify the
1036 // buffer manager that this buffer has been freed. It's not fatal, but should be avoided,
1037 // therefore log a warning.
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07001038 *buffer = 0;
Zhijun He125684a2015-12-26 15:07:30 -08001039 ALOGW("%s: the released buffer has already been freed by the buffer queue!", __FUNCTION__);
1040 } else if (res != OK) {
Eino-Ville Talvalaff51b472016-06-28 15:26:19 -07001041 // Treat other errors as abandonment
Yin-Chia Yeha1b56c82019-03-27 15:50:39 -07001042 if (shouldLogError(res, mState)) {
1043 ALOGE("%s: detach next buffer failed: %s (%d).", __FUNCTION__, strerror(-res), res);
1044 }
Eino-Ville Talvalaff51b472016-06-28 15:26:19 -07001045 mState = STATE_ABANDONED;
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07001046 return res;
Zhijun He125684a2015-12-26 15:07:30 -08001047 }
1048
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07001049 if (fenceFd != nullptr) {
1050 if (fence!= 0 && fence->isValid()) {
1051 *fenceFd = fence->dup();
1052 } else {
1053 *fenceFd = -1;
1054 }
Zhijun He125684a2015-12-26 15:07:30 -08001055 }
Eino-Ville Talvala77c1a352016-06-13 12:32:43 -07001056
Yin-Chia Yehbf1b8b92019-03-06 14:56:08 -08001057 // Here we assume detachBuffer is called by buffer manager so it doesn't need to be notified
1058 checkRemovedBuffersLocked(/*notifyBufferManager*/false);
Yin-Chia Yeh017d49c2017-03-31 19:11:00 -07001059 return res;
Zhijun He125684a2015-12-26 15:07:30 -08001060}
Shuzhen Wang13a69632016-01-26 09:51:07 -08001061
Chien-Yu Chena936ac22017-10-23 15:59:49 -07001062status_t Camera3OutputStream::dropBuffers(bool dropping) {
1063 Mutex::Autolock l(mLock);
1064 mDropBuffers = dropping;
1065 return OK;
1066}
1067
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001068const String8& Camera3OutputStream::getPhysicalCameraId() const {
1069 Mutex::Autolock l(mLock);
1070 return physicalCameraId();
1071}
1072
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -08001073status_t Camera3OutputStream::notifyBufferReleased(ANativeWindowBuffer* /*anwBuffer*/) {
Shuzhen Wang0129d522016-10-30 22:43:41 -07001074 return OK;
1075}
1076
1077bool Camera3OutputStream::isConsumerConfigurationDeferred(size_t surface_id) const {
Zhijun He5d677d12016-05-29 16:52:39 -07001078 Mutex::Autolock l(mLock);
Shuzhen Wang0129d522016-10-30 22:43:41 -07001079
1080 if (surface_id != 0) {
Shuzhen Wang758c2152017-01-10 18:26:18 -08001081 ALOGE("%s: surface_id %zu for Camera3OutputStream should be 0!", __FUNCTION__, surface_id);
Shuzhen Wang0129d522016-10-30 22:43:41 -07001082 }
Zhijun He5d677d12016-05-29 16:52:39 -07001083 return mConsumer == nullptr;
1084}
1085
Shuzhen Wang758c2152017-01-10 18:26:18 -08001086status_t Camera3OutputStream::setConsumers(const std::vector<sp<Surface>>& consumers) {
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -08001087 Mutex::Autolock l(mLock);
Shuzhen Wang758c2152017-01-10 18:26:18 -08001088 if (consumers.size() != 1) {
1089 ALOGE("%s: it's illegal to set %zu consumer surfaces!",
1090 __FUNCTION__, consumers.size());
1091 return INVALID_OPERATION;
1092 }
1093 if (consumers[0] == nullptr) {
1094 ALOGE("%s: it's illegal to set null consumer surface!", __FUNCTION__);
Zhijun He5d677d12016-05-29 16:52:39 -07001095 return INVALID_OPERATION;
1096 }
1097
1098 if (mConsumer != nullptr) {
1099 ALOGE("%s: consumer surface was already set!", __FUNCTION__);
1100 return INVALID_OPERATION;
1101 }
1102
Shuzhen Wang758c2152017-01-10 18:26:18 -08001103 mConsumer = consumers[0];
Zhijun He5d677d12016-05-29 16:52:39 -07001104 return OK;
1105}
1106
Shuzhen Wang13a69632016-01-26 09:51:07 -08001107bool Camera3OutputStream::isConsumedByHWComposer() const {
Emilian Peev050f5dc2017-05-18 14:43:56 +01001108 uint64_t usage = 0;
Shuzhen Wang13a69632016-01-26 09:51:07 -08001109 status_t res = getEndpointUsage(&usage);
1110 if (res != OK) {
1111 ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
1112 return false;
1113 }
1114
1115 return (usage & GRALLOC_USAGE_HW_COMPOSER) != 0;
1116}
1117
Zhijun Hef0645c12016-08-02 00:58:11 -07001118bool Camera3OutputStream::isConsumedByHWTexture() const {
Emilian Peev050f5dc2017-05-18 14:43:56 +01001119 uint64_t usage = 0;
Zhijun Hef0645c12016-08-02 00:58:11 -07001120 status_t res = getEndpointUsage(&usage);
1121 if (res != OK) {
1122 ALOGE("%s: getting end point usage failed: %s (%d).", __FUNCTION__, strerror(-res), res);
1123 return false;
1124 }
1125
1126 return (usage & GRALLOC_USAGE_HW_TEXTURE) != 0;
1127}
1128
Shuzhen Wangabbcb6b2020-12-09 22:32:44 -08001129void Camera3OutputStream::dumpImageToDisk(nsecs_t timestamp,
1130 ANativeWindowBuffer* anwBuffer, int fence) {
1131 // Deriver output file name
1132 std::string fileExtension = "jpg";
1133 char imageFileName[64];
1134 time_t now = time(0);
1135 tm *localTime = localtime(&now);
1136 snprintf(imageFileName, sizeof(imageFileName), "IMG_%4d%02d%02d_%02d%02d%02d_%" PRId64 ".%s",
Shuzhen Wang6a8237f2021-07-13 14:42:57 -07001137 1900 + localTime->tm_year, localTime->tm_mon + 1, localTime->tm_mday,
Shuzhen Wangabbcb6b2020-12-09 22:32:44 -08001138 localTime->tm_hour, localTime->tm_min, localTime->tm_sec,
1139 timestamp, fileExtension.c_str());
1140
1141 // Lock the image for CPU read
1142 sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(anwBuffer);
1143 void* mapped = nullptr;
1144 base::unique_fd fenceFd(dup(fence));
1145 status_t res = graphicBuffer->lockAsync(GraphicBuffer::USAGE_SW_READ_OFTEN, &mapped,
1146 fenceFd.get());
1147 if (res != OK) {
1148 ALOGE("%s: Failed to lock the buffer: %s (%d)", __FUNCTION__, strerror(-res), res);
1149 return;
1150 }
1151
1152 // Figure out actual file size
1153 auto actualJpegSize = android::camera2::JpegProcessor::findJpegSize((uint8_t*)mapped, mMaxSize);
1154 if (actualJpegSize == 0) {
1155 actualJpegSize = mMaxSize;
1156 }
1157
1158 // Output image data to file
1159 std::string filePath = "/data/misc/cameraserver/";
1160 filePath += imageFileName;
1161 std::ofstream imageFile(filePath.c_str(), std::ofstream::binary);
1162 if (!imageFile.is_open()) {
1163 ALOGE("%s: Unable to create file %s", __FUNCTION__, filePath.c_str());
1164 graphicBuffer->unlock();
1165 return;
1166 }
1167 imageFile.write((const char*)mapped, actualJpegSize);
1168
1169 graphicBuffer->unlock();
1170}
1171
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001172status_t Camera3OutputStream::setBatchSize(size_t batchSize) {
1173 Mutex::Autolock l(mLock);
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001174 if (batchSize == 0) {
1175 ALOGE("%s: invalid batch size 0", __FUNCTION__);
1176 return BAD_VALUE;
1177 }
1178
1179 if (mUseBufferManager) {
1180 ALOGE("%s: batch operation is not supported with buffer manager", __FUNCTION__);
1181 return INVALID_OPERATION;
1182 }
1183
1184 if (!isVideoStream()) {
1185 ALOGE("%s: batch operation is not supported with non-video stream", __FUNCTION__);
1186 return INVALID_OPERATION;
1187 }
1188
Shuzhen Wangc7629462021-07-12 15:02:58 -07001189 if (camera_stream::max_buffers < batchSize) {
1190 ALOGW("%s: batch size is capped by max_buffers %d", __FUNCTION__,
1191 camera_stream::max_buffers);
1192 batchSize = camera_stream::max_buffers;
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001193 }
Shuzhen Wangc7629462021-07-12 15:02:58 -07001194
1195 size_t defaultBatchSize = 1;
1196 if (!mBatchSize.compare_exchange_strong(defaultBatchSize, batchSize)) {
1197 ALOGE("%s: change batch size from %zu to %zu dynamically is not supported",
1198 __FUNCTION__, defaultBatchSize, batchSize);
1199 return INVALID_OPERATION;
1200 }
1201
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001202 return OK;
1203}
1204
1205void Camera3OutputStream::returnPrefetchedBuffersLocked() {
Shuzhen Wangc7629462021-07-12 15:02:58 -07001206 std::vector<Surface::BatchBuffer> batchedBuffers;
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001207
Shuzhen Wangc7629462021-07-12 15:02:58 -07001208 {
1209 std::lock_guard<std::mutex> batchLock(mBatchLock);
1210 if (mBatchedBuffers.size() != 0) {
1211 ALOGW("%s: %zu extra prefetched buffers detected. Returning",
1212 __FUNCTION__, mBatchedBuffers.size());
1213 batchedBuffers = std::move(mBatchedBuffers);
1214 }
1215 }
1216
1217 if (batchedBuffers.size() > 0) {
1218 mConsumer->cancelBuffers(batchedBuffers);
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001219 }
1220}
1221
Shuzhen Wange4adddb2021-09-21 15:24:44 -07001222bool Camera3OutputStream::shouldLogError(status_t res) {
1223 Mutex::Autolock l(mLock);
1224 return shouldLogError(res, mState);
1225}
1226
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -08001227}; // namespace camera3
1228
1229}; // namespace android