blob: 43954553211673f707de4eb7e5171c14bee9d189 [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
Emilian Peev2295df72021-11-12 18:14:10 -080017#include <vector>
18#include "system/window.h"
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080019#define LOG_TAG "Camera3-Stream"
20#define ATRACE_TAG ATRACE_TAG_CAMERA
21//#define LOG_NDEBUG 0
22
23#include <utils/Log.h>
24#include <utils/Trace.h>
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -070025#include "device3/Camera3Stream.h"
26#include "device3/StatusTracker.h"
Jayant Chowdharyd4776262020-06-23 23:45:57 -070027#include "utils/TraceHFR.h"
Emilian Peev2295df72021-11-12 18:14:10 -080028#include "ui/GraphicBufferMapper.h"
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080029
Igor Murashkin13d315e2014-04-03 18:09:04 -070030#include <cutils/properties.h>
31
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080032namespace android {
33
34namespace camera3 {
35
36Camera3Stream::~Camera3Stream() {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -070037 sp<StatusTracker> statusTracker = mStatusTracker.promote();
38 if (statusTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
39 statusTracker->removeComponent(mStatusId);
40 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080041}
42
Emilian Peevf4816702020-04-03 15:44:51 -070043Camera3Stream* Camera3Stream::cast(camera_stream *stream) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080044 return static_cast<Camera3Stream*>(stream);
45}
46
Emilian Peevf4816702020-04-03 15:44:51 -070047const Camera3Stream* Camera3Stream::cast(const camera_stream *stream) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080048 return static_cast<const Camera3Stream*>(stream);
49}
50
51Camera3Stream::Camera3Stream(int id,
Emilian Peevf4816702020-04-03 15:44:51 -070052 camera_stream_type type,
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -080053 uint32_t width, uint32_t height, size_t maxSize, int format,
Emilian Peevf4816702020-04-03 15:44:51 -070054 android_dataspace dataSpace, camera_stream_rotation_t rotation,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080055 const String8& physicalCameraId,
56 const std::unordered_set<int32_t> &sensorPixelModesUsed,
Emilian Peevc81a7592022-02-14 17:38:18 -080057 int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
Austin Borger9e2b27c2022-07-15 11:27:24 -070058 int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
59 int32_t colorSpace) :
Emilian Peevf4816702020-04-03 15:44:51 -070060 camera_stream(),
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080061 mId(id),
Zhijun He125684a2015-12-26 15:07:30 -080062 mSetId(setId),
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080063 mName(String8::format("Camera3Stream[%d]", id)),
64 mMaxSize(maxSize),
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -070065 mState(STATE_CONSTRUCTED),
Ruben Brunkc78ac262015-08-13 17:58:46 -070066 mStatusId(StatusTracker::NO_STATUS_ID),
Zhijun He5d677d12016-05-29 16:52:39 -070067 mStreamUnpreparable(true),
Emilian Peev050f5dc2017-05-18 14:43:56 +010068 mUsage(0),
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080069 mOldUsage(0),
70 mOldMaxBuffers(0),
Shuzhen Wangf9b4eb92019-06-10 11:06:01 -070071 mOldFormat(-1),
72 mOldDataSpace(HAL_DATASPACE_UNKNOWN),
Zhijun He125684a2015-12-26 15:07:30 -080073 mPrepared(false),
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -070074 mPrepareBlockRequest(true),
Zhijun He125684a2015-12-26 15:07:30 -080075 mPreparedBufferIdx(0),
Shuzhen Wang686f6442017-06-20 16:16:04 -070076 mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX),
Emilian Peev710c1422017-08-30 11:19:38 +010077 mBufferLimitLatency(kBufferLimitLatencyBinSize),
78 mFormatOverridden(false),
Yin-Chia Yeh90667662019-07-01 15:45:00 -070079 mOriginalFormat(format),
Shuzhen Wang92653952019-05-07 15:11:43 -070080 mDataSpaceOverridden(false),
Shuzhen Wang2f5010d2019-08-22 12:41:12 -070081 mOriginalDataSpace(dataSpace),
Shuzhen Wang26abaf42018-08-28 15:41:20 -070082 mPhysicalCameraId(physicalCameraId),
Shuzhen Wang83bff122020-11-20 15:51:39 -080083 mLastTimestamp(0),
Shuzhen Wange4208922022-02-01 16:52:48 -080084 mIsMultiResolution(isMultiResolution),
85 mDeviceTimeBaseIsRealtime(deviceTimeBaseIsRealtime),
86 mTimestampBase(timestampBase) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080087
Emilian Peevf4816702020-04-03 15:44:51 -070088 camera_stream::stream_type = type;
89 camera_stream::width = width;
90 camera_stream::height = height;
91 camera_stream::format = format;
92 camera_stream::data_space = dataSpace;
93 camera_stream::rotation = rotation;
94 camera_stream::max_buffers = 0;
95 camera_stream::physical_camera_id = mPhysicalCameraId.string();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080096 camera_stream::sensor_pixel_modes_used = sensorPixelModesUsed;
Emilian Peev2295df72021-11-12 18:14:10 -080097 camera_stream::dynamic_range_profile = dynamicRangeProfile;
Shuzhen Wangc8ab4522021-12-14 20:12:42 -080098 camera_stream::use_case = streamUseCase;
Austin Borger9e2b27c2022-07-15 11:27:24 -070099 camera_stream::color_space = colorSpace;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800100
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -0800101 if ((format == HAL_PIXEL_FORMAT_BLOB || format == HAL_PIXEL_FORMAT_RAW_OPAQUE) &&
102 maxSize == 0) {
103 ALOGE("%s: BLOB or RAW_OPAQUE format with size == 0", __FUNCTION__);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800104 mState = STATE_ERROR;
105 }
106}
107
108int Camera3Stream::getId() const {
109 return mId;
110}
111
Zhijun He125684a2015-12-26 15:07:30 -0800112int Camera3Stream::getStreamSetId() const {
113 return mSetId;
114}
115
Shuzhen Wang83bff122020-11-20 15:51:39 -0800116int Camera3Stream::getHalStreamGroupId() const {
117 return mIsMultiResolution ? mSetId : -1;
118}
119
120bool Camera3Stream::isMultiResolution() const {
121 return mIsMultiResolution;
122}
123
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800124uint32_t Camera3Stream::getWidth() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700125 return camera_stream::width;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800126}
127
128uint32_t Camera3Stream::getHeight() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700129 return camera_stream::height;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800130}
131
132int Camera3Stream::getFormat() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700133 return camera_stream::format;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800134}
135
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800136android_dataspace Camera3Stream::getDataSpace() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700137 return camera_stream::data_space;
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800138}
139
Austin Borger9e2b27c2022-07-15 11:27:24 -0700140int32_t Camera3Stream::getColorSpace() const {
141 return camera_stream::color_space;
142}
143
Emilian Peev050f5dc2017-05-18 14:43:56 +0100144uint64_t Camera3Stream::getUsage() const {
145 return mUsage;
146}
147
148void Camera3Stream::setUsage(uint64_t usage) {
149 mUsage = usage;
150}
151
Emilian Peev710c1422017-08-30 11:19:38 +0100152void Camera3Stream::setFormatOverride(bool formatOverridden) {
153 mFormatOverridden = formatOverridden;
154}
155
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700156bool Camera3Stream::isFormatOverridden() const {
Emilian Peev710c1422017-08-30 11:19:38 +0100157 return mFormatOverridden;
158}
159
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700160int Camera3Stream::getOriginalFormat() const {
161 return mOriginalFormat;
Emilian Peev710c1422017-08-30 11:19:38 +0100162}
163
Emilian Peevc81a7592022-02-14 17:38:18 -0800164int64_t Camera3Stream::getDynamicRangeProfile() const {
Emilian Peev2295df72021-11-12 18:14:10 -0800165 return camera_stream::dynamic_range_profile;
166}
167
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700168void Camera3Stream::setDataSpaceOverride(bool dataSpaceOverridden) {
169 mDataSpaceOverridden = dataSpaceOverridden;
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700170}
171
172bool Camera3Stream::isDataSpaceOverridden() const {
173 return mDataSpaceOverridden;
174}
175
176android_dataspace Camera3Stream::getOriginalDataSpace() const {
177 return mOriginalDataSpace;
Emilian Peev710c1422017-08-30 11:19:38 +0100178}
179
Shuzhen Wang5c22c152017-12-31 17:12:25 -0800180const String8& Camera3Stream::physicalCameraId() const {
181 return mPhysicalCameraId;
182}
183
Shuzhen Wang316781a2020-08-18 18:11:01 -0700184int Camera3Stream::getMaxHalBuffers() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700185 return camera_stream::max_buffers;
Shuzhen Wang316781a2020-08-18 18:11:01 -0700186}
187
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800188int64_t Camera3Stream::getStreamUseCase() const {
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800189 return camera_stream::use_case;
190}
191
Shuzhen Wange4208922022-02-01 16:52:48 -0800192int Camera3Stream::getTimestampBase() const {
193 return mTimestampBase;
194}
195
196bool Camera3Stream::isDeviceTimeBaseRealtime() const {
197 return mDeviceTimeBaseIsRealtime;
198}
199
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -0800200void Camera3Stream::setOfflineProcessingSupport(bool support) {
201 mSupportOfflineProcessing = support;
202}
203
204bool Camera3Stream::getOfflineProcessingSupport() const {
205 return mSupportOfflineProcessing;
206}
207
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000208status_t Camera3Stream::forceToIdle() {
209 ATRACE_CALL();
210 Mutex::Autolock l(mLock);
211 status_t res;
212
213 switch (mState) {
214 case STATE_ERROR:
215 case STATE_CONSTRUCTED:
216 case STATE_IN_CONFIG:
217 case STATE_PREPARING:
218 case STATE_IN_RECONFIG:
219 ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
220 res = NO_INIT;
221 break;
222 case STATE_CONFIGURED:
223 if (hasOutstandingBuffersLocked()) {
224 sp<StatusTracker> statusTracker = mStatusTracker.promote();
225 if (statusTracker != 0) {
226 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
227 }
228 }
229
230 mState = STATE_IN_IDLE;
231 res = OK;
232
233 break;
234 default:
235 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
236 res = NO_INIT;
237 }
238
239 return res;
240}
241
242status_t Camera3Stream::restoreConfiguredState() {
243 ATRACE_CALL();
244 Mutex::Autolock l(mLock);
245 status_t res;
246
247 switch (mState) {
248 case STATE_ERROR:
249 case STATE_CONSTRUCTED:
250 case STATE_IN_CONFIG:
251 case STATE_PREPARING:
252 case STATE_IN_RECONFIG:
253 case STATE_CONFIGURED:
254 ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
255 res = NO_INIT;
256 break;
257 case STATE_IN_IDLE:
258 if (hasOutstandingBuffersLocked()) {
259 sp<StatusTracker> statusTracker = mStatusTracker.promote();
260 if (statusTracker != 0) {
261 statusTracker->markComponentActive(mStatusId);
262 }
263 }
264
265 mState = STATE_CONFIGURED;
266 res = OK;
267
268 break;
269 default:
270 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
271 res = NO_INIT;
272 }
273
274 return res;
275}
276
Emilian Peevf4816702020-04-03 15:44:51 -0700277camera_stream* Camera3Stream::startConfiguration() {
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700278 ATRACE_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800279 Mutex::Autolock l(mLock);
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700280 status_t res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800281
282 switch (mState) {
283 case STATE_ERROR:
284 ALOGE("%s: In error state", __FUNCTION__);
285 return NULL;
286 case STATE_CONSTRUCTED:
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000287 case STATE_IN_IDLE:
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800288 // OK
289 break;
290 case STATE_IN_CONFIG:
291 case STATE_IN_RECONFIG:
292 // Can start config again with no trouble; but don't redo
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800293 // mOldUsage/mOldMaxBuffers
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800294 return this;
295 case STATE_CONFIGURED:
Chien-Yu Chen90746f42015-04-15 13:50:13 -0700296 if (hasOutstandingBuffersLocked()) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800297 ALOGE("%s: Cannot configure stream; has outstanding buffers",
298 __FUNCTION__);
299 return NULL;
300 }
301 break;
302 default:
303 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
304 return NULL;
305 }
306
Emilian Peev050f5dc2017-05-18 14:43:56 +0100307 mOldUsage = mUsage;
Emilian Peevf4816702020-04-03 15:44:51 -0700308 mOldMaxBuffers = camera_stream::max_buffers;
309 mOldFormat = camera_stream::format;
310 mOldDataSpace = camera_stream::data_space;
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700311
Emilian Peev050f5dc2017-05-18 14:43:56 +0100312 res = getEndpointUsage(&mUsage);
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700313 if (res != OK) {
314 ALOGE("%s: Cannot query consumer endpoint usage!",
315 __FUNCTION__);
316 return NULL;
317 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800318
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000319 if (mState == STATE_IN_IDLE) {
320 // Skip configuration.
321 return this;
322 }
323
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700324 // Stop tracking if currently doing so
325 if (mStatusId != StatusTracker::NO_STATUS_ID) {
326 sp<StatusTracker> statusTracker = mStatusTracker.promote();
327 if (statusTracker != 0) {
328 statusTracker->removeComponent(mStatusId);
329 }
330 mStatusId = StatusTracker::NO_STATUS_ID;
331 }
332
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800333 if (mState == STATE_CONSTRUCTED) {
334 mState = STATE_IN_CONFIG;
335 } else { // mState == STATE_CONFIGURED
Igor Murashkin13d315e2014-04-03 18:09:04 -0700336 LOG_ALWAYS_FATAL_IF(mState != STATE_CONFIGURED, "Invalid state: 0x%x", mState);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800337 mState = STATE_IN_RECONFIG;
338 }
339
340 return this;
341}
342
343bool Camera3Stream::isConfiguring() const {
344 Mutex::Autolock l(mLock);
345 return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
346}
347
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700348status_t Camera3Stream::finishConfiguration(/*out*/bool* streamReconfigured) {
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700349 ATRACE_CALL();
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700350 if (streamReconfigured != nullptr) {
351 *streamReconfigured = false;
352 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800353 Mutex::Autolock l(mLock);
354 switch (mState) {
355 case STATE_ERROR:
356 ALOGE("%s: In error state", __FUNCTION__);
357 return INVALID_OPERATION;
358 case STATE_IN_CONFIG:
359 case STATE_IN_RECONFIG:
360 // OK
361 break;
362 case STATE_CONSTRUCTED:
363 case STATE_CONFIGURED:
364 ALOGE("%s: Cannot finish configuration that hasn't been started",
365 __FUNCTION__);
366 return INVALID_OPERATION;
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000367 case STATE_IN_IDLE:
368 //Skip configuration in this state
369 return OK;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800370 default:
371 ALOGE("%s: Unknown state", __FUNCTION__);
372 return INVALID_OPERATION;
373 }
374
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700375 // Register for idle tracking
376 sp<StatusTracker> statusTracker = mStatusTracker.promote();
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700377 if (statusTracker != 0 && mStatusId == StatusTracker::NO_STATUS_ID) {
Yin-Chia Yeh87b3ec02019-06-03 10:44:39 -0700378 std::string name = std::string("Stream ") + std::to_string(mId);
379 mStatusId = statusTracker->addComponent(name.c_str());
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700380 }
381
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800382 // Check if the stream configuration is unchanged, and skip reallocation if
Emilian Peevf4816702020-04-03 15:44:51 -0700383 // so.
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800384 if (mState == STATE_IN_RECONFIG &&
Emilian Peev050f5dc2017-05-18 14:43:56 +0100385 mOldUsage == mUsage &&
Emilian Peevf4816702020-04-03 15:44:51 -0700386 mOldMaxBuffers == camera_stream::max_buffers &&
387 mOldDataSpace == camera_stream::data_space &&
388 mOldFormat == camera_stream::format) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800389 mState = STATE_CONFIGURED;
390 return OK;
391 }
392
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700393 // Reset prepared state, since buffer config has changed, and existing
394 // allocations are no longer valid
395 mPrepared = false;
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700396 mPrepareBlockRequest = true;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700397 mStreamUnpreparable = false;
398
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700399 bool reconfiguring = (mState == STATE_IN_RECONFIG);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800400 status_t res;
401 res = configureQueueLocked();
Shuzhen Wang210ba5c2018-07-25 16:47:40 -0700402 // configureQueueLocked could return error in case of abandoned surface.
403 // Treat as non-fatal error.
404 if (res == NO_INIT || res == DEAD_OBJECT) {
405 ALOGE("%s: Unable to configure stream %d queue (non-fatal): %s (%d)",
406 __FUNCTION__, mId, strerror(-res), res);
407 mState = STATE_ABANDONED;
408 return res;
409 } else if (res != OK) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800410 ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
411 __FUNCTION__, mId, strerror(-res), res);
412 mState = STATE_ERROR;
413 return res;
414 }
415
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700416 if (reconfiguring && streamReconfigured != nullptr) {
417 *streamReconfigured = true;
418 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800419 mState = STATE_CONFIGURED;
420
421 return res;
422}
423
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700424status_t Camera3Stream::cancelConfiguration() {
425 ATRACE_CALL();
426 Mutex::Autolock l(mLock);
427 switch (mState) {
428 case STATE_ERROR:
429 ALOGE("%s: In error state", __FUNCTION__);
430 return INVALID_OPERATION;
431 case STATE_IN_CONFIG:
432 case STATE_IN_RECONFIG:
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000433 case STATE_IN_IDLE:
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700434 // OK
435 break;
436 case STATE_CONSTRUCTED:
437 case STATE_CONFIGURED:
438 ALOGE("%s: Cannot cancel configuration that hasn't been started",
439 __FUNCTION__);
440 return INVALID_OPERATION;
441 default:
442 ALOGE("%s: Unknown state", __FUNCTION__);
443 return INVALID_OPERATION;
444 }
445
Emilian Peev050f5dc2017-05-18 14:43:56 +0100446 mUsage = mOldUsage;
Emilian Peevf4816702020-04-03 15:44:51 -0700447 camera_stream::max_buffers = mOldMaxBuffers;
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700448
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000449 mState = ((mState == STATE_IN_RECONFIG) || (mState == STATE_IN_IDLE)) ? STATE_CONFIGURED :
450 STATE_CONSTRUCTED;
451
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700452 return OK;
453}
454
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700455bool Camera3Stream::isUnpreparable() {
456 ATRACE_CALL();
457
458 Mutex::Autolock l(mLock);
459 return mStreamUnpreparable;
460}
461
Emilian Peevf0348ae2021-01-13 13:39:45 -0800462void Camera3Stream::markUnpreparable() {
463 ATRACE_CALL();
464
465 Mutex::Autolock l(mLock);
466 mStreamUnpreparable = true;
467}
468
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700469status_t Camera3Stream::startPrepare(int maxCount, bool blockRequest) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700470 ATRACE_CALL();
471
472 Mutex::Autolock l(mLock);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700473
Ruben Brunkc78ac262015-08-13 17:58:46 -0700474 if (maxCount < 0) {
475 ALOGE("%s: Stream %d: Can't prepare stream if max buffer count (%d) is < 0",
476 __FUNCTION__, mId, maxCount);
477 return BAD_VALUE;
478 }
479
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700480 // This function should be only called when the stream is configured already.
481 if (mState != STATE_CONFIGURED) {
482 ALOGE("%s: Stream %d: Can't prepare stream if stream is not in CONFIGURED "
483 "state %d", __FUNCTION__, mId, mState);
484 return INVALID_OPERATION;
485 }
486
487 // This function can't be called if the stream has already received filled
488 // buffers
489 if (mStreamUnpreparable) {
490 ALOGE("%s: Stream %d: Can't prepare stream that's already in use",
491 __FUNCTION__, mId);
492 return INVALID_OPERATION;
493 }
494
495 if (getHandoutOutputBufferCountLocked() > 0) {
496 ALOGE("%s: Stream %d: Can't prepare stream that has outstanding buffers",
497 __FUNCTION__, mId);
498 return INVALID_OPERATION;
499 }
500
Ruben Brunkc78ac262015-08-13 17:58:46 -0700501 size_t pipelineMax = getBufferCountLocked();
502 size_t clampedCount = (pipelineMax < static_cast<size_t>(maxCount)) ?
503 pipelineMax : static_cast<size_t>(maxCount);
504 size_t bufferCount = (maxCount == Camera3StreamInterface::ALLOCATE_PIPELINE_MAX) ?
505 pipelineMax : clampedCount;
506
507 mPrepared = bufferCount <= mLastMaxCount;
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700508 mPrepareBlockRequest = blockRequest;
Ruben Brunkc78ac262015-08-13 17:58:46 -0700509
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700510 if (mPrepared) return OK;
511
Ruben Brunkc78ac262015-08-13 17:58:46 -0700512 mLastMaxCount = bufferCount;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700513
Emilian Peevf4816702020-04-03 15:44:51 -0700514 mPreparedBuffers.insertAt(camera_stream_buffer_t(), /*index*/0, bufferCount);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700515 mPreparedBufferIdx = 0;
516
517 mState = STATE_PREPARING;
518
519 return NOT_ENOUGH_DATA;
520}
521
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700522bool Camera3Stream::isBlockedByPrepare() const {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700523 Mutex::Autolock l(mLock);
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700524 return mState == STATE_PREPARING && mPrepareBlockRequest;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700525}
526
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700527bool Camera3Stream::isAbandoned() const {
528 Mutex::Autolock l(mLock);
529 return mState == STATE_ABANDONED;
530}
531
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700532status_t Camera3Stream::prepareNextBuffer() {
533 ATRACE_CALL();
534
535 Mutex::Autolock l(mLock);
536 status_t res = OK;
537
538 // This function should be only called when the stream is preparing
539 if (mState != STATE_PREPARING) {
540 ALOGE("%s: Stream %d: Can't prepare buffer if stream is not in PREPARING "
541 "state %d", __FUNCTION__, mId, mState);
542 return INVALID_OPERATION;
543 }
544
545 // Get next buffer - this may allocate, and take a while for large buffers
546 res = getBufferLocked( &mPreparedBuffers.editItemAt(mPreparedBufferIdx) );
547 if (res != OK) {
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800548 ALOGE("%s: Stream %d: Unable to allocate buffer %zu during preparation",
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700549 __FUNCTION__, mId, mPreparedBufferIdx);
550 return NO_INIT;
551 }
552
553 mPreparedBufferIdx++;
554
555 // Check if we still have buffers left to allocate
556 if (mPreparedBufferIdx < mPreparedBuffers.size()) {
557 return NOT_ENOUGH_DATA;
558 }
559
560 // Done with prepare - mark stream as such, and return all buffers
561 // via cancelPrepare
562 mPrepared = true;
563
564 return cancelPrepareLocked();
565}
566
567status_t Camera3Stream::cancelPrepare() {
568 ATRACE_CALL();
569
570 Mutex::Autolock l(mLock);
571
572 return cancelPrepareLocked();
573}
574
575status_t Camera3Stream::cancelPrepareLocked() {
576 status_t res = OK;
577
578 // This function should be only called when the stream is mid-preparing.
579 if (mState != STATE_PREPARING) {
580 ALOGE("%s: Stream %d: Can't cancel prepare stream if stream is not in "
581 "PREPARING state %d", __FUNCTION__, mId, mState);
582 return INVALID_OPERATION;
583 }
584
585 // Return all valid buffers to stream, in ERROR state to indicate
586 // they weren't filled.
587 for (size_t i = 0; i < mPreparedBufferIdx; i++) {
588 mPreparedBuffers.editItemAt(i).release_fence = -1;
Emilian Peevf4816702020-04-03 15:44:51 -0700589 mPreparedBuffers.editItemAt(i).status = CAMERA_BUFFER_STATUS_ERROR;
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700590 returnBufferLocked(mPreparedBuffers[i], /*timestamp*/0, /*readoutTimestamp*/0,
591 /*transform*/ -1);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700592 }
593 mPreparedBuffers.clear();
594 mPreparedBufferIdx = 0;
595
596 mState = STATE_CONFIGURED;
597
598 return res;
599}
600
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -0700601status_t Camera3Stream::tearDown() {
602 ATRACE_CALL();
603 Mutex::Autolock l(mLock);
604
605 status_t res = OK;
606
607 // This function should be only called when the stream is configured.
608 if (mState != STATE_CONFIGURED) {
609 ALOGE("%s: Stream %d: Can't tear down stream if stream is not in "
610 "CONFIGURED state %d", __FUNCTION__, mId, mState);
611 return INVALID_OPERATION;
612 }
613
614 // If any buffers have been handed to the HAL, the stream cannot be torn down.
615 if (getHandoutOutputBufferCountLocked() > 0) {
616 ALOGE("%s: Stream %d: Can't tear down a stream that has outstanding buffers",
617 __FUNCTION__, mId);
618 return INVALID_OPERATION;
619 }
620
621 // Free buffers by disconnecting and then reconnecting to the buffer queue
622 // Only unused buffers will be dropped immediately; buffers that have been filled
623 // and are waiting to be acquired by the consumer and buffers that are currently
624 // acquired will be freed once they are released by the consumer.
625
626 res = disconnectLocked();
627 if (res != OK) {
628 if (res == -ENOTCONN) {
629 // queue has been disconnected, nothing left to do, so exit with success
630 return OK;
631 }
632 ALOGE("%s: Stream %d: Unable to disconnect to tear down buffers: %s (%d)",
633 __FUNCTION__, mId, strerror(-res), res);
634 return res;
635 }
636
637 mState = STATE_IN_CONFIG;
638
639 res = configureQueueLocked();
640 if (res != OK) {
641 ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
642 __FUNCTION__, mId, strerror(-res), res);
643 mState = STATE_ERROR;
644 return res;
645 }
646
647 // Reset prepared state, since we've reconnected to the queue and can prepare again.
648 mPrepared = false;
649 mStreamUnpreparable = false;
650
651 mState = STATE_CONFIGURED;
652
653 return OK;
654}
655
Emilian Peevf4816702020-04-03 15:44:51 -0700656status_t Camera3Stream::getBuffer(camera_stream_buffer *buffer,
Yin-Chia Yehb3a80b12018-09-04 12:13:05 -0700657 nsecs_t waitBufferTimeout,
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800658 const std::vector<size_t>& surface_ids) {
Jayant Chowdharyd4776262020-06-23 23:45:57 -0700659 ATRACE_HFR_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800660 Mutex::Autolock l(mLock);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700661 status_t res = OK;
Igor Murashkin2fba5842013-04-22 14:03:54 -0700662
Zhijun He6adc9cc2014-04-15 14:09:55 -0700663 // This function should be only called when the stream is configured already.
664 if (mState != STATE_CONFIGURED) {
665 ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
666 __FUNCTION__, mId, mState);
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -0800667 if (mState == STATE_ABANDONED) {
668 return DEAD_OBJECT;
669 } else {
670 return INVALID_OPERATION;
671 }
Zhijun He6adc9cc2014-04-15 14:09:55 -0700672 }
673
Shuzhen Wangc2352702022-09-06 18:36:31 -0700674 // Wait for new buffer returned back if we are running into the limit. There
675 // are 2 limits:
676 // 1. The number of HAL buffers is greater than max_buffers
677 // 2. The number of HAL buffers + cached buffers is greater than max_buffers
678 // + maxCachedBuffers
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800679 size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked();
Shuzhen Wangc2352702022-09-06 18:36:31 -0700680 size_t numCachedBuffers = getCachedOutputBufferCountLocked();
681 size_t maxNumCachedBuffers = getMaxCachedOutputBuffersLocked();
682 while (numOutstandingBuffers == camera_stream::max_buffers ||
683 numOutstandingBuffers + numCachedBuffers ==
684 camera_stream::max_buffers + maxNumCachedBuffers) {
685 ALOGV("%s: Already dequeued max output buffers (%d(+%zu)), wait for next returned one.",
686 __FUNCTION__, camera_stream::max_buffers, maxNumCachedBuffers);
Shuzhen Wang686f6442017-06-20 16:16:04 -0700687 nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
Yin-Chia Yehb3a80b12018-09-04 12:13:05 -0700688 if (waitBufferTimeout < kWaitForBufferDuration) {
689 waitBufferTimeout = kWaitForBufferDuration;
690 }
691 res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
Shuzhen Wang686f6442017-06-20 16:16:04 -0700692 nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
693 mBufferLimitLatency.add(waitStart, waitEnd);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700694 if (res != OK) {
695 if (res == TIMED_OUT) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -0700696 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
Yin-Chia Yehb3a80b12018-09-04 12:13:05 -0700697 __FUNCTION__, waitBufferTimeout / 1000000LL,
Emilian Peevf4816702020-04-03 15:44:51 -0700698 camera_stream::max_buffers);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700699 }
700 return res;
701 }
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800702
703 size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked();
Shuzhen Wangc2352702022-09-06 18:36:31 -0700704 size_t updatedNumCachedBuffers = getCachedOutputBufferCountLocked();
705 if (updatedNumOutstandingBuffers >= numOutstandingBuffers &&
706 updatedNumCachedBuffers == numCachedBuffers) {
707 ALOGE("%s: outstanding buffer count goes from %zu to %zu, "
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800708 "getBuffer(s) call must not run in parallel!", __FUNCTION__,
709 numOutstandingBuffers, updatedNumOutstandingBuffers);
710 return INVALID_OPERATION;
711 }
Shuzhen Wangc2352702022-09-06 18:36:31 -0700712 numOutstandingBuffers = updatedNumOutstandingBuffers;
713 numCachedBuffers = updatedNumCachedBuffers;
Zhijun He6adc9cc2014-04-15 14:09:55 -0700714 }
715
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800716 res = getBufferLocked(buffer, surface_ids);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700717 if (res == OK) {
718 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700719 if (buffer->buffer) {
Emilian Peev889234d2017-07-18 18:21:26 -0700720 Mutex::Autolock l(mOutstandingBuffersLock);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700721 mOutstandingBuffers.push_back(*buffer->buffer);
722 }
Igor Murashkin2fba5842013-04-22 14:03:54 -0700723 }
724
725 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800726}
727
Emilian Peevf4816702020-04-03 15:44:51 -0700728bool Camera3Stream::isOutstandingBuffer(const camera_stream_buffer &buffer) const{
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700729 if (buffer.buffer == nullptr) {
730 return false;
731 }
732
Emilian Peev889234d2017-07-18 18:21:26 -0700733 Mutex::Autolock l(mOutstandingBuffersLock);
734
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700735 for (auto b : mOutstandingBuffers) {
736 if (b == *buffer.buffer) {
737 return true;
738 }
739 }
740 return false;
741}
742
Emilian Peevf4816702020-04-03 15:44:51 -0700743void Camera3Stream::removeOutstandingBuffer(const camera_stream_buffer &buffer) {
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700744 if (buffer.buffer == nullptr) {
745 return;
746 }
747
Emilian Peev889234d2017-07-18 18:21:26 -0700748 Mutex::Autolock l(mOutstandingBuffersLock);
749
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700750 for (auto b = mOutstandingBuffers.begin(); b != mOutstandingBuffers.end(); b++) {
751 if (*b == *buffer.buffer) {
752 mOutstandingBuffers.erase(b);
753 return;
754 }
755 }
756}
757
Emilian Peevf4816702020-04-03 15:44:51 -0700758status_t Camera3Stream::returnBuffer(const camera_stream_buffer &buffer,
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700759 nsecs_t timestamp, nsecs_t readoutTimestamp, bool timestampIncreasing,
Emilian Peev5104fe92021-10-21 14:27:09 -0700760 const std::vector<size_t>& surface_ids, uint64_t frameNumber, int32_t transform) {
Jayant Chowdharyd4776262020-06-23 23:45:57 -0700761 ATRACE_HFR_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800762 Mutex::Autolock l(mLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700763
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700764 // Check if this buffer is outstanding.
765 if (!isOutstandingBuffer(buffer)) {
766 ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
767 return BAD_VALUE;
768 }
769
Shuzhen Wang1c484a62017-07-14 15:14:19 -0700770 removeOutstandingBuffer(buffer);
771
Shuzhen Wangf0c4a6b2018-09-05 09:36:14 -0700772 // Buffer status may be changed, so make a copy of the stream_buffer struct.
Emilian Peevf4816702020-04-03 15:44:51 -0700773 camera_stream_buffer b = buffer;
Shuzhen Wang26abaf42018-08-28 15:41:20 -0700774 if (timestampIncreasing && timestamp != 0 && timestamp <= mLastTimestamp) {
Shuzhen Wangf0c4a6b2018-09-05 09:36:14 -0700775 ALOGE("%s: Stream %d: timestamp %" PRId64 " is not increasing. Prev timestamp %" PRId64,
Shuzhen Wang26abaf42018-08-28 15:41:20 -0700776 __FUNCTION__, mId, timestamp, mLastTimestamp);
Emilian Peevf4816702020-04-03 15:44:51 -0700777 b.status = CAMERA_BUFFER_STATUS_ERROR;
Shuzhen Wang26abaf42018-08-28 15:41:20 -0700778 }
779 mLastTimestamp = timestamp;
780
Igor Murashkin13d315e2014-04-03 18:09:04 -0700781 /**
782 * TODO: Check that the state is valid first.
783 *
784 * <HAL3.2 IN_CONFIG and IN_RECONFIG in addition to CONFIGURED.
785 * >= HAL3.2 CONFIGURED only
786 *
787 * Do this for getBuffer as well.
788 */
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700789 status_t res = returnBufferLocked(b, timestamp, readoutTimestamp, transform, surface_ids);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700790 if (res == OK) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000791 fireBufferListenersLocked(b, /*acquired*/false, /*output*/true, timestamp, frameNumber);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700792 }
793
Chien-Yu Chenb83c1fe2015-09-10 16:15:21 -0700794 // Even if returning the buffer failed, we still want to signal whoever is waiting for the
795 // buffer to be returned.
796 mOutputBufferReturnedSignal.signal();
797
Igor Murashkin2fba5842013-04-22 14:03:54 -0700798 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800799}
800
Shuzhen Wang83bff122020-11-20 15:51:39 -0800801status_t Camera3Stream::getInputBuffer(camera_stream_buffer *buffer,
802 Size* size, bool respectHalLimit) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700803 ATRACE_CALL();
804 Mutex::Autolock l(mLock);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700805 status_t res = OK;
Igor Murashkin2fba5842013-04-22 14:03:54 -0700806
Shuzhen Wang83bff122020-11-20 15:51:39 -0800807 if (size == nullptr) {
808 ALOGE("%s: size must not be null", __FUNCTION__);
809 return BAD_VALUE;
810 }
Zhijun He6adc9cc2014-04-15 14:09:55 -0700811 // This function should be only called when the stream is configured already.
812 if (mState != STATE_CONFIGURED) {
813 ALOGE("%s: Stream %d: Can't get input buffers if stream is not in CONFIGURED state %d",
814 __FUNCTION__, mId, mState);
815 return INVALID_OPERATION;
816 }
817
818 // Wait for new buffer returned back if we are running into the limit.
Emilian Peevf4816702020-04-03 15:44:51 -0700819 if (getHandoutInputBufferCountLocked() == camera_stream::max_buffers && respectHalLimit) {
Zhijun He6adc9cc2014-04-15 14:09:55 -0700820 ALOGV("%s: Already dequeued max input buffers (%d), wait for next returned one.",
Emilian Peevf4816702020-04-03 15:44:51 -0700821 __FUNCTION__, camera_stream::max_buffers);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700822 res = mInputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
823 if (res != OK) {
824 if (res == TIMED_OUT) {
825 ALOGE("%s: wait for input buffer return timed out after %lldms", __FUNCTION__,
826 kWaitForBufferDuration / 1000000LL);
827 }
828 return res;
829 }
830 }
831
Shuzhen Wang83bff122020-11-20 15:51:39 -0800832 res = getInputBufferLocked(buffer, size);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700833 if (res == OK) {
834 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700835 if (buffer->buffer) {
Emilian Peev889234d2017-07-18 18:21:26 -0700836 Mutex::Autolock l(mOutstandingBuffersLock);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700837 mOutstandingBuffers.push_back(*buffer->buffer);
838 }
Igor Murashkin2fba5842013-04-22 14:03:54 -0700839 }
840
841 return res;
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700842}
843
Emilian Peevf4816702020-04-03 15:44:51 -0700844status_t Camera3Stream::returnInputBuffer(const camera_stream_buffer &buffer) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700845 ATRACE_CALL();
846 Mutex::Autolock l(mLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700847
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700848 // Check if this buffer is outstanding.
849 if (!isOutstandingBuffer(buffer)) {
850 ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
851 return BAD_VALUE;
852 }
853
Shuzhen Wang1c484a62017-07-14 15:14:19 -0700854 removeOutstandingBuffer(buffer);
855
Igor Murashkin2fba5842013-04-22 14:03:54 -0700856 status_t res = returnInputBufferLocked(buffer);
857 if (res == OK) {
858 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700859 mInputBufferReturnedSignal.signal();
Igor Murashkin2fba5842013-04-22 14:03:54 -0700860 }
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700861
Igor Murashkin2fba5842013-04-22 14:03:54 -0700862 return res;
863}
864
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700865status_t Camera3Stream::getInputBufferProducer(sp<IGraphicBufferProducer> *producer) {
866 ATRACE_CALL();
867 Mutex::Autolock l(mLock);
868
869 return getInputBufferProducerLocked(producer);
870}
871
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800872void Camera3Stream::fireBufferRequestForFrameNumber(uint64_t frameNumber,
873 const CameraMetadata& settings) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000874 ATRACE_CALL();
875 Mutex::Autolock l(mLock);
876
877 for (auto &it : mBufferListenerList) {
878 sp<Camera3StreamBufferListener> listener = it.promote();
879 if (listener.get() != nullptr) {
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800880 listener->onBufferRequestForFrameNumber(frameNumber, getId(), settings);
Emilian Peev538c90e2018-12-17 18:03:19 +0000881 }
882 }
883}
884
Igor Murashkin2fba5842013-04-22 14:03:54 -0700885void Camera3Stream::fireBufferListenersLocked(
Emilian Peevf4816702020-04-03 15:44:51 -0700886 const camera_stream_buffer& buffer, bool acquired, bool output, nsecs_t timestamp,
Emilian Peev538c90e2018-12-17 18:03:19 +0000887 uint64_t frameNumber) {
Igor Murashkin2fba5842013-04-22 14:03:54 -0700888 List<wp<Camera3StreamBufferListener> >::iterator it, end;
889
890 // TODO: finish implementing
891
892 Camera3StreamBufferListener::BufferInfo info =
893 Camera3StreamBufferListener::BufferInfo();
894 info.mOutput = output;
Emilian Peevf4816702020-04-03 15:44:51 -0700895 info.mError = (buffer.status == CAMERA_BUFFER_STATUS_ERROR);
Emilian Peev538c90e2018-12-17 18:03:19 +0000896 info.mFrameNumber = frameNumber;
897 info.mTimestamp = timestamp;
Shuzhen Wange8675782019-12-05 09:12:14 -0800898 info.mStreamId = getId();
899
Igor Murashkin2fba5842013-04-22 14:03:54 -0700900 // TODO: rest of fields
901
902 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
903 it != end;
904 ++it) {
905
906 sp<Camera3StreamBufferListener> listener = it->promote();
907 if (listener != 0) {
908 if (acquired) {
909 listener->onBufferAcquired(info);
910 } else {
911 listener->onBufferReleased(info);
912 }
913 }
914 }
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700915}
916
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800917bool Camera3Stream::hasOutstandingBuffers() const {
918 ATRACE_CALL();
919 Mutex::Autolock l(mLock);
920 return hasOutstandingBuffersLocked();
921}
922
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -0700923size_t Camera3Stream::getOutstandingBuffersCount() const {
924 ATRACE_CALL();
925 Mutex::Autolock l(mLock);
926 return getHandoutOutputBufferCountLocked();
927}
928
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700929status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) {
930 Mutex::Autolock l(mLock);
931 sp<StatusTracker> oldTracker = mStatusTracker.promote();
932 if (oldTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
933 oldTracker->removeComponent(mStatusId);
934 }
935 mStatusId = StatusTracker::NO_STATUS_ID;
936 mStatusTracker = statusTracker;
937
938 return OK;
939}
940
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800941status_t Camera3Stream::disconnect() {
942 ATRACE_CALL();
943 Mutex::Autolock l(mLock);
Igor Murashkine2172be2013-05-28 15:31:39 -0700944 ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId);
945 status_t res = disconnectLocked();
946
Shuzhen Wang686f6442017-06-20 16:16:04 -0700947 mBufferLimitLatency.log("Stream %d latency histogram for wait on max_buffers", mId);
948 mBufferLimitLatency.reset();
949
Igor Murashkine2172be2013-05-28 15:31:39 -0700950 if (res == -ENOTCONN) {
951 // "Already disconnected" -- not an error
952 return OK;
953 } else {
954 return res;
955 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800956}
957
Jing Mikec7f9b132023-03-12 11:12:04 +0800958void Camera3Stream::dump(int fd, [[maybe_unused]] const Vector<String16> &args) const
Shuzhen Wang686f6442017-06-20 16:16:04 -0700959{
Shuzhen Wang686f6442017-06-20 16:16:04 -0700960 mBufferLimitLatency.dump(fd,
961 " Latency histogram for wait on max_buffers");
962}
963
Emilian Peevf4816702020-04-03 15:44:51 -0700964status_t Camera3Stream::getBufferLocked(camera_stream_buffer *,
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800965 const std::vector<size_t>&) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700966 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
967 return INVALID_OPERATION;
968}
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800969
970status_t Camera3Stream::getBuffersLocked(std::vector<OutstandingBuffer>*) {
971 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
972 return INVALID_OPERATION;
973}
974
Emilian Peevf4816702020-04-03 15:44:51 -0700975status_t Camera3Stream::returnBufferLocked(const camera_stream_buffer &,
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700976 nsecs_t, nsecs_t, int32_t, const std::vector<size_t>&) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700977 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
978 return INVALID_OPERATION;
979}
Shuzhen Wang83bff122020-11-20 15:51:39 -0800980status_t Camera3Stream::getInputBufferLocked(camera_stream_buffer *, Size *) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700981 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
982 return INVALID_OPERATION;
983}
984status_t Camera3Stream::returnInputBufferLocked(
Emilian Peevf4816702020-04-03 15:44:51 -0700985 const camera_stream_buffer &) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700986 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
987 return INVALID_OPERATION;
988}
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800989status_t Camera3Stream::getInputBufferProducerLocked(sp<IGraphicBufferProducer>*) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700990 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
991 return INVALID_OPERATION;
992}
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700993
Igor Murashkin2fba5842013-04-22 14:03:54 -0700994void Camera3Stream::addBufferListener(
995 wp<Camera3StreamBufferListener> listener) {
996 Mutex::Autolock l(mLock);
Zhijun Hef0d962a2014-06-30 10:24:11 -0700997
998 List<wp<Camera3StreamBufferListener> >::iterator it, end;
999 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
1000 it != end;
1001 ) {
1002 if (*it == listener) {
1003 ALOGE("%s: Try to add the same listener twice, ignoring...", __FUNCTION__);
1004 return;
1005 }
1006 it++;
1007 }
1008
Igor Murashkin2fba5842013-04-22 14:03:54 -07001009 mBufferListenerList.push_back(listener);
1010}
1011
1012void Camera3Stream::removeBufferListener(
1013 const sp<Camera3StreamBufferListener>& listener) {
1014 Mutex::Autolock l(mLock);
1015
1016 bool erased = true;
1017 List<wp<Camera3StreamBufferListener> >::iterator it, end;
1018 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
1019 it != end;
1020 ) {
1021
1022 if (*it == listener) {
1023 it = mBufferListenerList.erase(it);
1024 erased = true;
1025 } else {
1026 ++it;
1027 }
1028 }
1029
1030 if (!erased) {
1031 ALOGW("%s: Could not find listener to remove, already removed",
1032 __FUNCTION__);
1033 }
1034}
1035
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07001036void Camera3Stream::setBufferFreedListener(
Yin-Chia Yehdb1e8642017-07-14 15:19:30 -07001037 wp<Camera3StreamBufferFreedListener> listener) {
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07001038 Mutex::Autolock l(mLock);
1039 // Only allow set listener during stream configuration because stream is guaranteed to be IDLE
1040 // at this state, so setBufferFreedListener won't collide with onBufferFreed callbacks
1041 if (mState != STATE_IN_CONFIG && mState != STATE_IN_RECONFIG) {
1042 ALOGE("%s: listener must be set during stream configuration!",__FUNCTION__);
1043 return;
1044 }
1045 mBufferFreedListener = listener;
1046}
1047
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001048status_t Camera3Stream::getBuffers(std::vector<OutstandingBuffer>* buffers,
1049 nsecs_t waitBufferTimeout) {
1050 ATRACE_CALL();
1051 Mutex::Autolock l(mLock);
1052 status_t res = OK;
1053
1054 if (buffers == nullptr) {
1055 ALOGI("%s: buffers must not be null!", __FUNCTION__);
1056 return BAD_VALUE;
1057 }
1058
1059 size_t numBuffersRequested = buffers->size();
1060 if (numBuffersRequested == 0) {
1061 ALOGE("%s: 0 buffers are requested!", __FUNCTION__);
1062 return BAD_VALUE;
1063 }
1064
1065 // This function should be only called when the stream is configured already.
1066 if (mState != STATE_CONFIGURED) {
1067 ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
1068 __FUNCTION__, mId, mState);
1069 if (mState == STATE_ABANDONED) {
1070 return DEAD_OBJECT;
1071 } else {
1072 return INVALID_OPERATION;
1073 }
1074 }
1075
1076 size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked();
Shuzhen Wangc2352702022-09-06 18:36:31 -07001077 size_t numCachedBuffers = getCachedOutputBufferCountLocked();
1078 size_t maxNumCachedBuffers = getMaxCachedOutputBuffersLocked();
1079 // Wait for new buffer returned back if we are running into the limit. There
1080 // are 2 limits:
1081 // 1. The number of HAL buffers is greater than max_buffers
1082 // 2. The number of HAL buffers + cached buffers is greater than max_buffers
1083 // + maxCachedBuffers
1084 while (numOutstandingBuffers + numBuffersRequested > camera_stream::max_buffers ||
1085 numOutstandingBuffers + numCachedBuffers + numBuffersRequested >
1086 camera_stream::max_buffers + maxNumCachedBuffers) {
1087 ALOGV("%s: Already dequeued %zu(+%zu) output buffers and requesting %zu "
1088 "(max is %d(+%zu)), waiting.", __FUNCTION__, numOutstandingBuffers,
1089 numCachedBuffers, numBuffersRequested, camera_stream::max_buffers,
1090 maxNumCachedBuffers);
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001091 nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
1092 if (waitBufferTimeout < kWaitForBufferDuration) {
1093 waitBufferTimeout = kWaitForBufferDuration;
1094 }
1095 res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
1096 nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
1097 mBufferLimitLatency.add(waitStart, waitEnd);
1098 if (res != OK) {
1099 if (res == TIMED_OUT) {
1100 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
1101 __FUNCTION__, waitBufferTimeout / 1000000LL,
1102 camera_stream::max_buffers);
1103 }
1104 return res;
1105 }
1106 size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked();
Shuzhen Wangc2352702022-09-06 18:36:31 -07001107 size_t updatedNumCachedBuffers = getCachedOutputBufferCountLocked();
1108 if (updatedNumOutstandingBuffers >= numOutstandingBuffers &&
1109 updatedNumCachedBuffers == numCachedBuffers) {
1110 ALOGE("%s: outstanding buffer count goes from %zu to %zu, "
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001111 "getBuffer(s) call must not run in parallel!", __FUNCTION__,
1112 numOutstandingBuffers, updatedNumOutstandingBuffers);
1113 return INVALID_OPERATION;
1114 }
1115 numOutstandingBuffers = updatedNumOutstandingBuffers;
Shuzhen Wangc2352702022-09-06 18:36:31 -07001116 numCachedBuffers = updatedNumCachedBuffers;
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001117 }
1118
1119 res = getBuffersLocked(buffers);
1120 if (res == OK) {
1121 for (auto& outstandingBuffer : *buffers) {
1122 camera_stream_buffer* buffer = outstandingBuffer.outBuffer;
1123 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
1124 if (buffer->buffer) {
1125 Mutex::Autolock l(mOutstandingBuffersLock);
1126 mOutstandingBuffers.push_back(*buffer->buffer);
1127 }
1128 }
1129 }
1130
1131 return res;
1132}
1133
Emilian Peev2295df72021-11-12 18:14:10 -08001134void Camera3Stream::queueHDRMetadata(buffer_handle_t buffer, sp<ANativeWindow>& anw,
Emilian Peevc81a7592022-02-14 17:38:18 -08001135 int64_t dynamicRangeProfile) {
Emilian Peev2295df72021-11-12 18:14:10 -08001136 auto& mapper = GraphicBufferMapper::get();
1137 switch (dynamicRangeProfile) {
1138 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10: {
1139 std::optional<ui::Smpte2086> smpte2086;
1140 auto res = mapper.getSmpte2086(buffer, &smpte2086);
1141 if ((res == OK) && smpte2086.has_value()) {
1142 const auto& metaValue = smpte2086.value();
1143 android_smpte2086_metadata meta = {
1144 .displayPrimaryRed.x = metaValue.primaryRed.x,
1145 .displayPrimaryRed.y = metaValue.primaryRed.y,
1146 .displayPrimaryGreen.x = metaValue.primaryGreen.x,
1147 .displayPrimaryGreen.y = metaValue.primaryGreen.y,
1148 .displayPrimaryBlue.x = metaValue.primaryBlue.x,
1149 .displayPrimaryBlue.y = metaValue.primaryBlue.y,
1150 .whitePoint.x = metaValue.whitePoint.x,
1151 .whitePoint.y = metaValue.whitePoint.y,
1152 .maxLuminance = metaValue.maxLuminance,
1153 .minLuminance = metaValue.minLuminance};
1154 native_window_set_buffers_smpte2086_metadata(anw.get(), &meta);
1155 } else {
1156 ALOGE("%s Couldn't retrieve Smpte2086 metadata %s (%d)",
1157 __FUNCTION__, strerror(-res), res);
1158 }
1159 break;
1160 }
1161 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS: {
1162 std::optional<std::vector<uint8_t>> smpte2094_40;
1163 auto res = mapper.getSmpte2094_40(buffer, &smpte2094_40);
1164 if ((res == OK) && smpte2094_40.has_value()) {
1165 native_window_set_buffers_hdr10_plus_metadata(anw.get(),
1166 smpte2094_40.value().size(), smpte2094_40.value().data());
1167 } else {
1168 ALOGE("%s Couldn't retrieve Smpte2094_40 metadata %s (%d)",
1169 __FUNCTION__, strerror(-res), res);
1170 }
1171 break;
1172 }
1173 default:
1174 // No-op
1175 break;
1176 }
1177}
1178
1179
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -08001180}; // namespace camera3
1181
1182}; // namespace android