blob: 7ad6649754c7e9b52133954c5a9c5c1e4f844bb9 [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,
Shuzhen Wang8ed1e872022-03-08 16:34:33 -080058 int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase) :
Emilian Peevf4816702020-04-03 15:44:51 -070059 camera_stream(),
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080060 mId(id),
Zhijun He125684a2015-12-26 15:07:30 -080061 mSetId(setId),
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080062 mName(String8::format("Camera3Stream[%d]", id)),
63 mMaxSize(maxSize),
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -070064 mState(STATE_CONSTRUCTED),
Ruben Brunkc78ac262015-08-13 17:58:46 -070065 mStatusId(StatusTracker::NO_STATUS_ID),
Zhijun He5d677d12016-05-29 16:52:39 -070066 mStreamUnpreparable(true),
Emilian Peev050f5dc2017-05-18 14:43:56 +010067 mUsage(0),
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080068 mOldUsage(0),
69 mOldMaxBuffers(0),
Shuzhen Wangf9b4eb92019-06-10 11:06:01 -070070 mOldFormat(-1),
71 mOldDataSpace(HAL_DATASPACE_UNKNOWN),
Zhijun He125684a2015-12-26 15:07:30 -080072 mPrepared(false),
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -070073 mPrepareBlockRequest(true),
Zhijun He125684a2015-12-26 15:07:30 -080074 mPreparedBufferIdx(0),
Shuzhen Wang686f6442017-06-20 16:16:04 -070075 mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX),
Emilian Peev710c1422017-08-30 11:19:38 +010076 mBufferLimitLatency(kBufferLimitLatencyBinSize),
77 mFormatOverridden(false),
Yin-Chia Yeh90667662019-07-01 15:45:00 -070078 mOriginalFormat(format),
Shuzhen Wang92653952019-05-07 15:11:43 -070079 mDataSpaceOverridden(false),
Shuzhen Wang2f5010d2019-08-22 12:41:12 -070080 mOriginalDataSpace(dataSpace),
Shuzhen Wang26abaf42018-08-28 15:41:20 -070081 mPhysicalCameraId(physicalCameraId),
Shuzhen Wang83bff122020-11-20 15:51:39 -080082 mLastTimestamp(0),
Shuzhen Wange4208922022-02-01 16:52:48 -080083 mIsMultiResolution(isMultiResolution),
84 mDeviceTimeBaseIsRealtime(deviceTimeBaseIsRealtime),
85 mTimestampBase(timestampBase) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080086
Emilian Peevf4816702020-04-03 15:44:51 -070087 camera_stream::stream_type = type;
88 camera_stream::width = width;
89 camera_stream::height = height;
90 camera_stream::format = format;
91 camera_stream::data_space = dataSpace;
92 camera_stream::rotation = rotation;
93 camera_stream::max_buffers = 0;
94 camera_stream::physical_camera_id = mPhysicalCameraId.string();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080095 camera_stream::sensor_pixel_modes_used = sensorPixelModesUsed;
Emilian Peev2295df72021-11-12 18:14:10 -080096 camera_stream::dynamic_range_profile = dynamicRangeProfile;
Shuzhen Wangc8ab4522021-12-14 20:12:42 -080097 camera_stream::use_case = streamUseCase;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080098
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -080099 if ((format == HAL_PIXEL_FORMAT_BLOB || format == HAL_PIXEL_FORMAT_RAW_OPAQUE) &&
100 maxSize == 0) {
101 ALOGE("%s: BLOB or RAW_OPAQUE format with size == 0", __FUNCTION__);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800102 mState = STATE_ERROR;
103 }
104}
105
106int Camera3Stream::getId() const {
107 return mId;
108}
109
Zhijun He125684a2015-12-26 15:07:30 -0800110int Camera3Stream::getStreamSetId() const {
111 return mSetId;
112}
113
Shuzhen Wang83bff122020-11-20 15:51:39 -0800114int Camera3Stream::getHalStreamGroupId() const {
115 return mIsMultiResolution ? mSetId : -1;
116}
117
118bool Camera3Stream::isMultiResolution() const {
119 return mIsMultiResolution;
120}
121
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800122uint32_t Camera3Stream::getWidth() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700123 return camera_stream::width;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800124}
125
126uint32_t Camera3Stream::getHeight() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700127 return camera_stream::height;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800128}
129
130int Camera3Stream::getFormat() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700131 return camera_stream::format;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800132}
133
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800134android_dataspace Camera3Stream::getDataSpace() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700135 return camera_stream::data_space;
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800136}
137
Emilian Peev050f5dc2017-05-18 14:43:56 +0100138uint64_t Camera3Stream::getUsage() const {
139 return mUsage;
140}
141
142void Camera3Stream::setUsage(uint64_t usage) {
143 mUsage = usage;
144}
145
Emilian Peev710c1422017-08-30 11:19:38 +0100146void Camera3Stream::setFormatOverride(bool formatOverridden) {
147 mFormatOverridden = formatOverridden;
148}
149
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700150bool Camera3Stream::isFormatOverridden() const {
Emilian Peev710c1422017-08-30 11:19:38 +0100151 return mFormatOverridden;
152}
153
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700154int Camera3Stream::getOriginalFormat() const {
155 return mOriginalFormat;
Emilian Peev710c1422017-08-30 11:19:38 +0100156}
157
Emilian Peevc81a7592022-02-14 17:38:18 -0800158int64_t Camera3Stream::getDynamicRangeProfile() const {
Emilian Peev2295df72021-11-12 18:14:10 -0800159 return camera_stream::dynamic_range_profile;
160}
161
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700162void Camera3Stream::setDataSpaceOverride(bool dataSpaceOverridden) {
163 mDataSpaceOverridden = dataSpaceOverridden;
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700164}
165
166bool Camera3Stream::isDataSpaceOverridden() const {
167 return mDataSpaceOverridden;
168}
169
170android_dataspace Camera3Stream::getOriginalDataSpace() const {
171 return mOriginalDataSpace;
Emilian Peev710c1422017-08-30 11:19:38 +0100172}
173
Shuzhen Wang5c22c152017-12-31 17:12:25 -0800174const String8& Camera3Stream::physicalCameraId() const {
175 return mPhysicalCameraId;
176}
177
Shuzhen Wang316781a2020-08-18 18:11:01 -0700178int Camera3Stream::getMaxHalBuffers() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700179 return camera_stream::max_buffers;
Shuzhen Wang316781a2020-08-18 18:11:01 -0700180}
181
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800182int64_t Camera3Stream::getStreamUseCase() const {
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800183 return camera_stream::use_case;
184}
185
Shuzhen Wange4208922022-02-01 16:52:48 -0800186int Camera3Stream::getTimestampBase() const {
187 return mTimestampBase;
188}
189
190bool Camera3Stream::isDeviceTimeBaseRealtime() const {
191 return mDeviceTimeBaseIsRealtime;
192}
193
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -0800194void Camera3Stream::setOfflineProcessingSupport(bool support) {
195 mSupportOfflineProcessing = support;
196}
197
198bool Camera3Stream::getOfflineProcessingSupport() const {
199 return mSupportOfflineProcessing;
200}
201
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000202status_t Camera3Stream::forceToIdle() {
203 ATRACE_CALL();
204 Mutex::Autolock l(mLock);
205 status_t res;
206
207 switch (mState) {
208 case STATE_ERROR:
209 case STATE_CONSTRUCTED:
210 case STATE_IN_CONFIG:
211 case STATE_PREPARING:
212 case STATE_IN_RECONFIG:
213 ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
214 res = NO_INIT;
215 break;
216 case STATE_CONFIGURED:
217 if (hasOutstandingBuffersLocked()) {
218 sp<StatusTracker> statusTracker = mStatusTracker.promote();
219 if (statusTracker != 0) {
220 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
221 }
222 }
223
224 mState = STATE_IN_IDLE;
225 res = OK;
226
227 break;
228 default:
229 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
230 res = NO_INIT;
231 }
232
233 return res;
234}
235
236status_t Camera3Stream::restoreConfiguredState() {
237 ATRACE_CALL();
238 Mutex::Autolock l(mLock);
239 status_t res;
240
241 switch (mState) {
242 case STATE_ERROR:
243 case STATE_CONSTRUCTED:
244 case STATE_IN_CONFIG:
245 case STATE_PREPARING:
246 case STATE_IN_RECONFIG:
247 case STATE_CONFIGURED:
248 ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
249 res = NO_INIT;
250 break;
251 case STATE_IN_IDLE:
252 if (hasOutstandingBuffersLocked()) {
253 sp<StatusTracker> statusTracker = mStatusTracker.promote();
254 if (statusTracker != 0) {
255 statusTracker->markComponentActive(mStatusId);
256 }
257 }
258
259 mState = STATE_CONFIGURED;
260 res = OK;
261
262 break;
263 default:
264 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
265 res = NO_INIT;
266 }
267
268 return res;
269}
270
Emilian Peevf4816702020-04-03 15:44:51 -0700271camera_stream* Camera3Stream::startConfiguration() {
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700272 ATRACE_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800273 Mutex::Autolock l(mLock);
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700274 status_t res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800275
276 switch (mState) {
277 case STATE_ERROR:
278 ALOGE("%s: In error state", __FUNCTION__);
279 return NULL;
280 case STATE_CONSTRUCTED:
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000281 case STATE_IN_IDLE:
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800282 // OK
283 break;
284 case STATE_IN_CONFIG:
285 case STATE_IN_RECONFIG:
286 // Can start config again with no trouble; but don't redo
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800287 // mOldUsage/mOldMaxBuffers
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800288 return this;
289 case STATE_CONFIGURED:
Chien-Yu Chen90746f42015-04-15 13:50:13 -0700290 if (hasOutstandingBuffersLocked()) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800291 ALOGE("%s: Cannot configure stream; has outstanding buffers",
292 __FUNCTION__);
293 return NULL;
294 }
295 break;
296 default:
297 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
298 return NULL;
299 }
300
Emilian Peev050f5dc2017-05-18 14:43:56 +0100301 mOldUsage = mUsage;
Emilian Peevf4816702020-04-03 15:44:51 -0700302 mOldMaxBuffers = camera_stream::max_buffers;
303 mOldFormat = camera_stream::format;
304 mOldDataSpace = camera_stream::data_space;
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700305
Emilian Peev050f5dc2017-05-18 14:43:56 +0100306 res = getEndpointUsage(&mUsage);
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700307 if (res != OK) {
308 ALOGE("%s: Cannot query consumer endpoint usage!",
309 __FUNCTION__);
310 return NULL;
311 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800312
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000313 if (mState == STATE_IN_IDLE) {
314 // Skip configuration.
315 return this;
316 }
317
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700318 // Stop tracking if currently doing so
319 if (mStatusId != StatusTracker::NO_STATUS_ID) {
320 sp<StatusTracker> statusTracker = mStatusTracker.promote();
321 if (statusTracker != 0) {
322 statusTracker->removeComponent(mStatusId);
323 }
324 mStatusId = StatusTracker::NO_STATUS_ID;
325 }
326
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800327 if (mState == STATE_CONSTRUCTED) {
328 mState = STATE_IN_CONFIG;
329 } else { // mState == STATE_CONFIGURED
Igor Murashkin13d315e2014-04-03 18:09:04 -0700330 LOG_ALWAYS_FATAL_IF(mState != STATE_CONFIGURED, "Invalid state: 0x%x", mState);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800331 mState = STATE_IN_RECONFIG;
332 }
333
334 return this;
335}
336
337bool Camera3Stream::isConfiguring() const {
338 Mutex::Autolock l(mLock);
339 return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
340}
341
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700342status_t Camera3Stream::finishConfiguration(/*out*/bool* streamReconfigured) {
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700343 ATRACE_CALL();
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700344 if (streamReconfigured != nullptr) {
345 *streamReconfigured = false;
346 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800347 Mutex::Autolock l(mLock);
348 switch (mState) {
349 case STATE_ERROR:
350 ALOGE("%s: In error state", __FUNCTION__);
351 return INVALID_OPERATION;
352 case STATE_IN_CONFIG:
353 case STATE_IN_RECONFIG:
354 // OK
355 break;
356 case STATE_CONSTRUCTED:
357 case STATE_CONFIGURED:
358 ALOGE("%s: Cannot finish configuration that hasn't been started",
359 __FUNCTION__);
360 return INVALID_OPERATION;
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000361 case STATE_IN_IDLE:
362 //Skip configuration in this state
363 return OK;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800364 default:
365 ALOGE("%s: Unknown state", __FUNCTION__);
366 return INVALID_OPERATION;
367 }
368
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700369 // Register for idle tracking
370 sp<StatusTracker> statusTracker = mStatusTracker.promote();
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700371 if (statusTracker != 0 && mStatusId == StatusTracker::NO_STATUS_ID) {
Yin-Chia Yeh87b3ec02019-06-03 10:44:39 -0700372 std::string name = std::string("Stream ") + std::to_string(mId);
373 mStatusId = statusTracker->addComponent(name.c_str());
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700374 }
375
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800376 // Check if the stream configuration is unchanged, and skip reallocation if
Emilian Peevf4816702020-04-03 15:44:51 -0700377 // so.
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800378 if (mState == STATE_IN_RECONFIG &&
Emilian Peev050f5dc2017-05-18 14:43:56 +0100379 mOldUsage == mUsage &&
Emilian Peevf4816702020-04-03 15:44:51 -0700380 mOldMaxBuffers == camera_stream::max_buffers &&
381 mOldDataSpace == camera_stream::data_space &&
382 mOldFormat == camera_stream::format) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800383 mState = STATE_CONFIGURED;
384 return OK;
385 }
386
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700387 // Reset prepared state, since buffer config has changed, and existing
388 // allocations are no longer valid
389 mPrepared = false;
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700390 mPrepareBlockRequest = true;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700391 mStreamUnpreparable = false;
392
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700393 bool reconfiguring = (mState == STATE_IN_RECONFIG);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800394 status_t res;
395 res = configureQueueLocked();
Shuzhen Wang210ba5c2018-07-25 16:47:40 -0700396 // configureQueueLocked could return error in case of abandoned surface.
397 // Treat as non-fatal error.
398 if (res == NO_INIT || res == DEAD_OBJECT) {
399 ALOGE("%s: Unable to configure stream %d queue (non-fatal): %s (%d)",
400 __FUNCTION__, mId, strerror(-res), res);
401 mState = STATE_ABANDONED;
402 return res;
403 } else if (res != OK) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800404 ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
405 __FUNCTION__, mId, strerror(-res), res);
406 mState = STATE_ERROR;
407 return res;
408 }
409
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700410 if (reconfiguring && streamReconfigured != nullptr) {
411 *streamReconfigured = true;
412 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800413 mState = STATE_CONFIGURED;
414
415 return res;
416}
417
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700418status_t Camera3Stream::cancelConfiguration() {
419 ATRACE_CALL();
420 Mutex::Autolock l(mLock);
421 switch (mState) {
422 case STATE_ERROR:
423 ALOGE("%s: In error state", __FUNCTION__);
424 return INVALID_OPERATION;
425 case STATE_IN_CONFIG:
426 case STATE_IN_RECONFIG:
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000427 case STATE_IN_IDLE:
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700428 // OK
429 break;
430 case STATE_CONSTRUCTED:
431 case STATE_CONFIGURED:
432 ALOGE("%s: Cannot cancel configuration that hasn't been started",
433 __FUNCTION__);
434 return INVALID_OPERATION;
435 default:
436 ALOGE("%s: Unknown state", __FUNCTION__);
437 return INVALID_OPERATION;
438 }
439
Emilian Peev050f5dc2017-05-18 14:43:56 +0100440 mUsage = mOldUsage;
Emilian Peevf4816702020-04-03 15:44:51 -0700441 camera_stream::max_buffers = mOldMaxBuffers;
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700442
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000443 mState = ((mState == STATE_IN_RECONFIG) || (mState == STATE_IN_IDLE)) ? STATE_CONFIGURED :
444 STATE_CONSTRUCTED;
445
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700446 return OK;
447}
448
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700449bool Camera3Stream::isUnpreparable() {
450 ATRACE_CALL();
451
452 Mutex::Autolock l(mLock);
453 return mStreamUnpreparable;
454}
455
Emilian Peevf0348ae2021-01-13 13:39:45 -0800456void Camera3Stream::markUnpreparable() {
457 ATRACE_CALL();
458
459 Mutex::Autolock l(mLock);
460 mStreamUnpreparable = true;
461}
462
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700463status_t Camera3Stream::startPrepare(int maxCount, bool blockRequest) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700464 ATRACE_CALL();
465
466 Mutex::Autolock l(mLock);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700467
Ruben Brunkc78ac262015-08-13 17:58:46 -0700468 if (maxCount < 0) {
469 ALOGE("%s: Stream %d: Can't prepare stream if max buffer count (%d) is < 0",
470 __FUNCTION__, mId, maxCount);
471 return BAD_VALUE;
472 }
473
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700474 // This function should be only called when the stream is configured already.
475 if (mState != STATE_CONFIGURED) {
476 ALOGE("%s: Stream %d: Can't prepare stream if stream is not in CONFIGURED "
477 "state %d", __FUNCTION__, mId, mState);
478 return INVALID_OPERATION;
479 }
480
481 // This function can't be called if the stream has already received filled
482 // buffers
483 if (mStreamUnpreparable) {
484 ALOGE("%s: Stream %d: Can't prepare stream that's already in use",
485 __FUNCTION__, mId);
486 return INVALID_OPERATION;
487 }
488
489 if (getHandoutOutputBufferCountLocked() > 0) {
490 ALOGE("%s: Stream %d: Can't prepare stream that has outstanding buffers",
491 __FUNCTION__, mId);
492 return INVALID_OPERATION;
493 }
494
Ruben Brunkc78ac262015-08-13 17:58:46 -0700495 size_t pipelineMax = getBufferCountLocked();
496 size_t clampedCount = (pipelineMax < static_cast<size_t>(maxCount)) ?
497 pipelineMax : static_cast<size_t>(maxCount);
498 size_t bufferCount = (maxCount == Camera3StreamInterface::ALLOCATE_PIPELINE_MAX) ?
499 pipelineMax : clampedCount;
500
501 mPrepared = bufferCount <= mLastMaxCount;
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700502 mPrepareBlockRequest = blockRequest;
Ruben Brunkc78ac262015-08-13 17:58:46 -0700503
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700504 if (mPrepared) return OK;
505
Ruben Brunkc78ac262015-08-13 17:58:46 -0700506 mLastMaxCount = bufferCount;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700507
Emilian Peevf4816702020-04-03 15:44:51 -0700508 mPreparedBuffers.insertAt(camera_stream_buffer_t(), /*index*/0, bufferCount);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700509 mPreparedBufferIdx = 0;
510
511 mState = STATE_PREPARING;
512
513 return NOT_ENOUGH_DATA;
514}
515
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700516bool Camera3Stream::isBlockedByPrepare() const {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700517 Mutex::Autolock l(mLock);
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700518 return mState == STATE_PREPARING && mPrepareBlockRequest;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700519}
520
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700521bool Camera3Stream::isAbandoned() const {
522 Mutex::Autolock l(mLock);
523 return mState == STATE_ABANDONED;
524}
525
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700526status_t Camera3Stream::prepareNextBuffer() {
527 ATRACE_CALL();
528
529 Mutex::Autolock l(mLock);
530 status_t res = OK;
531
532 // This function should be only called when the stream is preparing
533 if (mState != STATE_PREPARING) {
534 ALOGE("%s: Stream %d: Can't prepare buffer if stream is not in PREPARING "
535 "state %d", __FUNCTION__, mId, mState);
536 return INVALID_OPERATION;
537 }
538
539 // Get next buffer - this may allocate, and take a while for large buffers
540 res = getBufferLocked( &mPreparedBuffers.editItemAt(mPreparedBufferIdx) );
541 if (res != OK) {
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800542 ALOGE("%s: Stream %d: Unable to allocate buffer %zu during preparation",
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700543 __FUNCTION__, mId, mPreparedBufferIdx);
544 return NO_INIT;
545 }
546
547 mPreparedBufferIdx++;
548
549 // Check if we still have buffers left to allocate
550 if (mPreparedBufferIdx < mPreparedBuffers.size()) {
551 return NOT_ENOUGH_DATA;
552 }
553
554 // Done with prepare - mark stream as such, and return all buffers
555 // via cancelPrepare
556 mPrepared = true;
557
558 return cancelPrepareLocked();
559}
560
561status_t Camera3Stream::cancelPrepare() {
562 ATRACE_CALL();
563
564 Mutex::Autolock l(mLock);
565
566 return cancelPrepareLocked();
567}
568
569status_t Camera3Stream::cancelPrepareLocked() {
570 status_t res = OK;
571
572 // This function should be only called when the stream is mid-preparing.
573 if (mState != STATE_PREPARING) {
574 ALOGE("%s: Stream %d: Can't cancel prepare stream if stream is not in "
575 "PREPARING state %d", __FUNCTION__, mId, mState);
576 return INVALID_OPERATION;
577 }
578
579 // Return all valid buffers to stream, in ERROR state to indicate
580 // they weren't filled.
581 for (size_t i = 0; i < mPreparedBufferIdx; i++) {
582 mPreparedBuffers.editItemAt(i).release_fence = -1;
Emilian Peevf4816702020-04-03 15:44:51 -0700583 mPreparedBuffers.editItemAt(i).status = CAMERA_BUFFER_STATUS_ERROR;
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700584 returnBufferLocked(mPreparedBuffers[i], /*timestamp*/0, /*readoutTimestamp*/0,
585 /*transform*/ -1);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700586 }
587 mPreparedBuffers.clear();
588 mPreparedBufferIdx = 0;
589
590 mState = STATE_CONFIGURED;
591
592 return res;
593}
594
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -0700595status_t Camera3Stream::tearDown() {
596 ATRACE_CALL();
597 Mutex::Autolock l(mLock);
598
599 status_t res = OK;
600
601 // This function should be only called when the stream is configured.
602 if (mState != STATE_CONFIGURED) {
603 ALOGE("%s: Stream %d: Can't tear down stream if stream is not in "
604 "CONFIGURED state %d", __FUNCTION__, mId, mState);
605 return INVALID_OPERATION;
606 }
607
608 // If any buffers have been handed to the HAL, the stream cannot be torn down.
609 if (getHandoutOutputBufferCountLocked() > 0) {
610 ALOGE("%s: Stream %d: Can't tear down a stream that has outstanding buffers",
611 __FUNCTION__, mId);
612 return INVALID_OPERATION;
613 }
614
615 // Free buffers by disconnecting and then reconnecting to the buffer queue
616 // Only unused buffers will be dropped immediately; buffers that have been filled
617 // and are waiting to be acquired by the consumer and buffers that are currently
618 // acquired will be freed once they are released by the consumer.
619
620 res = disconnectLocked();
621 if (res != OK) {
622 if (res == -ENOTCONN) {
623 // queue has been disconnected, nothing left to do, so exit with success
624 return OK;
625 }
626 ALOGE("%s: Stream %d: Unable to disconnect to tear down buffers: %s (%d)",
627 __FUNCTION__, mId, strerror(-res), res);
628 return res;
629 }
630
631 mState = STATE_IN_CONFIG;
632
633 res = configureQueueLocked();
634 if (res != OK) {
635 ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
636 __FUNCTION__, mId, strerror(-res), res);
637 mState = STATE_ERROR;
638 return res;
639 }
640
641 // Reset prepared state, since we've reconnected to the queue and can prepare again.
642 mPrepared = false;
643 mStreamUnpreparable = false;
644
645 mState = STATE_CONFIGURED;
646
647 return OK;
648}
649
Emilian Peevf4816702020-04-03 15:44:51 -0700650status_t Camera3Stream::getBuffer(camera_stream_buffer *buffer,
Yin-Chia Yehb3a80b12018-09-04 12:13:05 -0700651 nsecs_t waitBufferTimeout,
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800652 const std::vector<size_t>& surface_ids) {
Jayant Chowdharyd4776262020-06-23 23:45:57 -0700653 ATRACE_HFR_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800654 Mutex::Autolock l(mLock);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700655 status_t res = OK;
Igor Murashkin2fba5842013-04-22 14:03:54 -0700656
Zhijun He6adc9cc2014-04-15 14:09:55 -0700657 // This function should be only called when the stream is configured already.
658 if (mState != STATE_CONFIGURED) {
659 ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
660 __FUNCTION__, mId, mState);
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -0800661 if (mState == STATE_ABANDONED) {
662 return DEAD_OBJECT;
663 } else {
664 return INVALID_OPERATION;
665 }
Zhijun He6adc9cc2014-04-15 14:09:55 -0700666 }
667
668 // Wait for new buffer returned back if we are running into the limit.
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800669 size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked();
670 if (numOutstandingBuffers == camera_stream::max_buffers) {
Zhijun He6adc9cc2014-04-15 14:09:55 -0700671 ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.",
Emilian Peevf4816702020-04-03 15:44:51 -0700672 __FUNCTION__, camera_stream::max_buffers);
Shuzhen Wang686f6442017-06-20 16:16:04 -0700673 nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
Yin-Chia Yehb3a80b12018-09-04 12:13:05 -0700674 if (waitBufferTimeout < kWaitForBufferDuration) {
675 waitBufferTimeout = kWaitForBufferDuration;
676 }
677 res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
Shuzhen Wang686f6442017-06-20 16:16:04 -0700678 nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
679 mBufferLimitLatency.add(waitStart, waitEnd);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700680 if (res != OK) {
681 if (res == TIMED_OUT) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -0700682 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
Yin-Chia Yehb3a80b12018-09-04 12:13:05 -0700683 __FUNCTION__, waitBufferTimeout / 1000000LL,
Emilian Peevf4816702020-04-03 15:44:51 -0700684 camera_stream::max_buffers);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700685 }
686 return res;
687 }
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800688
689 size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked();
690 if (updatedNumOutstandingBuffers >= numOutstandingBuffers) {
691 ALOGE("%s: outsanding buffer count goes from %zu to %zu, "
692 "getBuffer(s) call must not run in parallel!", __FUNCTION__,
693 numOutstandingBuffers, updatedNumOutstandingBuffers);
694 return INVALID_OPERATION;
695 }
Zhijun He6adc9cc2014-04-15 14:09:55 -0700696 }
697
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800698 res = getBufferLocked(buffer, surface_ids);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700699 if (res == OK) {
700 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700701 if (buffer->buffer) {
Emilian Peev889234d2017-07-18 18:21:26 -0700702 Mutex::Autolock l(mOutstandingBuffersLock);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700703 mOutstandingBuffers.push_back(*buffer->buffer);
704 }
Igor Murashkin2fba5842013-04-22 14:03:54 -0700705 }
706
707 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800708}
709
Emilian Peevf4816702020-04-03 15:44:51 -0700710bool Camera3Stream::isOutstandingBuffer(const camera_stream_buffer &buffer) const{
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700711 if (buffer.buffer == nullptr) {
712 return false;
713 }
714
Emilian Peev889234d2017-07-18 18:21:26 -0700715 Mutex::Autolock l(mOutstandingBuffersLock);
716
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700717 for (auto b : mOutstandingBuffers) {
718 if (b == *buffer.buffer) {
719 return true;
720 }
721 }
722 return false;
723}
724
Emilian Peevf4816702020-04-03 15:44:51 -0700725void Camera3Stream::removeOutstandingBuffer(const camera_stream_buffer &buffer) {
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700726 if (buffer.buffer == nullptr) {
727 return;
728 }
729
Emilian Peev889234d2017-07-18 18:21:26 -0700730 Mutex::Autolock l(mOutstandingBuffersLock);
731
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700732 for (auto b = mOutstandingBuffers.begin(); b != mOutstandingBuffers.end(); b++) {
733 if (*b == *buffer.buffer) {
734 mOutstandingBuffers.erase(b);
735 return;
736 }
737 }
738}
739
Emilian Peevf4816702020-04-03 15:44:51 -0700740status_t Camera3Stream::returnBuffer(const camera_stream_buffer &buffer,
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700741 nsecs_t timestamp, nsecs_t readoutTimestamp, bool timestampIncreasing,
Emilian Peev5104fe92021-10-21 14:27:09 -0700742 const std::vector<size_t>& surface_ids, uint64_t frameNumber, int32_t transform) {
Jayant Chowdharyd4776262020-06-23 23:45:57 -0700743 ATRACE_HFR_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800744 Mutex::Autolock l(mLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700745
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700746 // Check if this buffer is outstanding.
747 if (!isOutstandingBuffer(buffer)) {
748 ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
749 return BAD_VALUE;
750 }
751
Shuzhen Wang1c484a62017-07-14 15:14:19 -0700752 removeOutstandingBuffer(buffer);
753
Shuzhen Wangf0c4a6b2018-09-05 09:36:14 -0700754 // Buffer status may be changed, so make a copy of the stream_buffer struct.
Emilian Peevf4816702020-04-03 15:44:51 -0700755 camera_stream_buffer b = buffer;
Shuzhen Wang26abaf42018-08-28 15:41:20 -0700756 if (timestampIncreasing && timestamp != 0 && timestamp <= mLastTimestamp) {
Shuzhen Wangf0c4a6b2018-09-05 09:36:14 -0700757 ALOGE("%s: Stream %d: timestamp %" PRId64 " is not increasing. Prev timestamp %" PRId64,
Shuzhen Wang26abaf42018-08-28 15:41:20 -0700758 __FUNCTION__, mId, timestamp, mLastTimestamp);
Emilian Peevf4816702020-04-03 15:44:51 -0700759 b.status = CAMERA_BUFFER_STATUS_ERROR;
Shuzhen Wang26abaf42018-08-28 15:41:20 -0700760 }
761 mLastTimestamp = timestamp;
762
Igor Murashkin13d315e2014-04-03 18:09:04 -0700763 /**
764 * TODO: Check that the state is valid first.
765 *
766 * <HAL3.2 IN_CONFIG and IN_RECONFIG in addition to CONFIGURED.
767 * >= HAL3.2 CONFIGURED only
768 *
769 * Do this for getBuffer as well.
770 */
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700771 status_t res = returnBufferLocked(b, timestamp, readoutTimestamp, transform, surface_ids);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700772 if (res == OK) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000773 fireBufferListenersLocked(b, /*acquired*/false, /*output*/true, timestamp, frameNumber);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700774 }
775
Chien-Yu Chenb83c1fe2015-09-10 16:15:21 -0700776 // Even if returning the buffer failed, we still want to signal whoever is waiting for the
777 // buffer to be returned.
778 mOutputBufferReturnedSignal.signal();
779
Igor Murashkin2fba5842013-04-22 14:03:54 -0700780 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800781}
782
Shuzhen Wang83bff122020-11-20 15:51:39 -0800783status_t Camera3Stream::getInputBuffer(camera_stream_buffer *buffer,
784 Size* size, bool respectHalLimit) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700785 ATRACE_CALL();
786 Mutex::Autolock l(mLock);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700787 status_t res = OK;
Igor Murashkin2fba5842013-04-22 14:03:54 -0700788
Shuzhen Wang83bff122020-11-20 15:51:39 -0800789 if (size == nullptr) {
790 ALOGE("%s: size must not be null", __FUNCTION__);
791 return BAD_VALUE;
792 }
Zhijun He6adc9cc2014-04-15 14:09:55 -0700793 // This function should be only called when the stream is configured already.
794 if (mState != STATE_CONFIGURED) {
795 ALOGE("%s: Stream %d: Can't get input buffers if stream is not in CONFIGURED state %d",
796 __FUNCTION__, mId, mState);
797 return INVALID_OPERATION;
798 }
799
800 // Wait for new buffer returned back if we are running into the limit.
Emilian Peevf4816702020-04-03 15:44:51 -0700801 if (getHandoutInputBufferCountLocked() == camera_stream::max_buffers && respectHalLimit) {
Zhijun He6adc9cc2014-04-15 14:09:55 -0700802 ALOGV("%s: Already dequeued max input buffers (%d), wait for next returned one.",
Emilian Peevf4816702020-04-03 15:44:51 -0700803 __FUNCTION__, camera_stream::max_buffers);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700804 res = mInputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
805 if (res != OK) {
806 if (res == TIMED_OUT) {
807 ALOGE("%s: wait for input buffer return timed out after %lldms", __FUNCTION__,
808 kWaitForBufferDuration / 1000000LL);
809 }
810 return res;
811 }
812 }
813
Shuzhen Wang83bff122020-11-20 15:51:39 -0800814 res = getInputBufferLocked(buffer, size);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700815 if (res == OK) {
816 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700817 if (buffer->buffer) {
Emilian Peev889234d2017-07-18 18:21:26 -0700818 Mutex::Autolock l(mOutstandingBuffersLock);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700819 mOutstandingBuffers.push_back(*buffer->buffer);
820 }
Igor Murashkin2fba5842013-04-22 14:03:54 -0700821 }
822
823 return res;
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700824}
825
Emilian Peevf4816702020-04-03 15:44:51 -0700826status_t Camera3Stream::returnInputBuffer(const camera_stream_buffer &buffer) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700827 ATRACE_CALL();
828 Mutex::Autolock l(mLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700829
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700830 // Check if this buffer is outstanding.
831 if (!isOutstandingBuffer(buffer)) {
832 ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
833 return BAD_VALUE;
834 }
835
Shuzhen Wang1c484a62017-07-14 15:14:19 -0700836 removeOutstandingBuffer(buffer);
837
Igor Murashkin2fba5842013-04-22 14:03:54 -0700838 status_t res = returnInputBufferLocked(buffer);
839 if (res == OK) {
840 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700841 mInputBufferReturnedSignal.signal();
Igor Murashkin2fba5842013-04-22 14:03:54 -0700842 }
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700843
Igor Murashkin2fba5842013-04-22 14:03:54 -0700844 return res;
845}
846
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700847status_t Camera3Stream::getInputBufferProducer(sp<IGraphicBufferProducer> *producer) {
848 ATRACE_CALL();
849 Mutex::Autolock l(mLock);
850
851 return getInputBufferProducerLocked(producer);
852}
853
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800854void Camera3Stream::fireBufferRequestForFrameNumber(uint64_t frameNumber,
855 const CameraMetadata& settings) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000856 ATRACE_CALL();
857 Mutex::Autolock l(mLock);
858
859 for (auto &it : mBufferListenerList) {
860 sp<Camera3StreamBufferListener> listener = it.promote();
861 if (listener.get() != nullptr) {
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800862 listener->onBufferRequestForFrameNumber(frameNumber, getId(), settings);
Emilian Peev538c90e2018-12-17 18:03:19 +0000863 }
864 }
865}
866
Igor Murashkin2fba5842013-04-22 14:03:54 -0700867void Camera3Stream::fireBufferListenersLocked(
Emilian Peevf4816702020-04-03 15:44:51 -0700868 const camera_stream_buffer& buffer, bool acquired, bool output, nsecs_t timestamp,
Emilian Peev538c90e2018-12-17 18:03:19 +0000869 uint64_t frameNumber) {
Igor Murashkin2fba5842013-04-22 14:03:54 -0700870 List<wp<Camera3StreamBufferListener> >::iterator it, end;
871
872 // TODO: finish implementing
873
874 Camera3StreamBufferListener::BufferInfo info =
875 Camera3StreamBufferListener::BufferInfo();
876 info.mOutput = output;
Emilian Peevf4816702020-04-03 15:44:51 -0700877 info.mError = (buffer.status == CAMERA_BUFFER_STATUS_ERROR);
Emilian Peev538c90e2018-12-17 18:03:19 +0000878 info.mFrameNumber = frameNumber;
879 info.mTimestamp = timestamp;
Shuzhen Wange8675782019-12-05 09:12:14 -0800880 info.mStreamId = getId();
881
Igor Murashkin2fba5842013-04-22 14:03:54 -0700882 // TODO: rest of fields
883
884 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
885 it != end;
886 ++it) {
887
888 sp<Camera3StreamBufferListener> listener = it->promote();
889 if (listener != 0) {
890 if (acquired) {
891 listener->onBufferAcquired(info);
892 } else {
893 listener->onBufferReleased(info);
894 }
895 }
896 }
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700897}
898
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800899bool Camera3Stream::hasOutstandingBuffers() const {
900 ATRACE_CALL();
901 Mutex::Autolock l(mLock);
902 return hasOutstandingBuffersLocked();
903}
904
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -0700905size_t Camera3Stream::getOutstandingBuffersCount() const {
906 ATRACE_CALL();
907 Mutex::Autolock l(mLock);
908 return getHandoutOutputBufferCountLocked();
909}
910
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700911status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) {
912 Mutex::Autolock l(mLock);
913 sp<StatusTracker> oldTracker = mStatusTracker.promote();
914 if (oldTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
915 oldTracker->removeComponent(mStatusId);
916 }
917 mStatusId = StatusTracker::NO_STATUS_ID;
918 mStatusTracker = statusTracker;
919
920 return OK;
921}
922
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800923status_t Camera3Stream::disconnect() {
924 ATRACE_CALL();
925 Mutex::Autolock l(mLock);
Igor Murashkine2172be2013-05-28 15:31:39 -0700926 ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId);
927 status_t res = disconnectLocked();
928
Shuzhen Wang686f6442017-06-20 16:16:04 -0700929 mBufferLimitLatency.log("Stream %d latency histogram for wait on max_buffers", mId);
930 mBufferLimitLatency.reset();
931
Igor Murashkine2172be2013-05-28 15:31:39 -0700932 if (res == -ENOTCONN) {
933 // "Already disconnected" -- not an error
934 return OK;
935 } else {
936 return res;
937 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800938}
939
Shuzhen Wang686f6442017-06-20 16:16:04 -0700940void Camera3Stream::dump(int fd, const Vector<String16> &args) const
941{
942 (void)args;
943 mBufferLimitLatency.dump(fd,
944 " Latency histogram for wait on max_buffers");
945}
946
Emilian Peevf4816702020-04-03 15:44:51 -0700947status_t Camera3Stream::getBufferLocked(camera_stream_buffer *,
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800948 const std::vector<size_t>&) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700949 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
950 return INVALID_OPERATION;
951}
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800952
953status_t Camera3Stream::getBuffersLocked(std::vector<OutstandingBuffer>*) {
954 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
955 return INVALID_OPERATION;
956}
957
Emilian Peevf4816702020-04-03 15:44:51 -0700958status_t Camera3Stream::returnBufferLocked(const camera_stream_buffer &,
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700959 nsecs_t, nsecs_t, int32_t, const std::vector<size_t>&) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700960 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
961 return INVALID_OPERATION;
962}
Shuzhen Wang83bff122020-11-20 15:51:39 -0800963status_t Camera3Stream::getInputBufferLocked(camera_stream_buffer *, Size *) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700964 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
965 return INVALID_OPERATION;
966}
967status_t Camera3Stream::returnInputBufferLocked(
Emilian Peevf4816702020-04-03 15:44:51 -0700968 const camera_stream_buffer &) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700969 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
970 return INVALID_OPERATION;
971}
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800972status_t Camera3Stream::getInputBufferProducerLocked(sp<IGraphicBufferProducer>*) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700973 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
974 return INVALID_OPERATION;
975}
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700976
Igor Murashkin2fba5842013-04-22 14:03:54 -0700977void Camera3Stream::addBufferListener(
978 wp<Camera3StreamBufferListener> listener) {
979 Mutex::Autolock l(mLock);
Zhijun Hef0d962a2014-06-30 10:24:11 -0700980
981 List<wp<Camera3StreamBufferListener> >::iterator it, end;
982 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
983 it != end;
984 ) {
985 if (*it == listener) {
986 ALOGE("%s: Try to add the same listener twice, ignoring...", __FUNCTION__);
987 return;
988 }
989 it++;
990 }
991
Igor Murashkin2fba5842013-04-22 14:03:54 -0700992 mBufferListenerList.push_back(listener);
993}
994
995void Camera3Stream::removeBufferListener(
996 const sp<Camera3StreamBufferListener>& listener) {
997 Mutex::Autolock l(mLock);
998
999 bool erased = true;
1000 List<wp<Camera3StreamBufferListener> >::iterator it, end;
1001 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
1002 it != end;
1003 ) {
1004
1005 if (*it == listener) {
1006 it = mBufferListenerList.erase(it);
1007 erased = true;
1008 } else {
1009 ++it;
1010 }
1011 }
1012
1013 if (!erased) {
1014 ALOGW("%s: Could not find listener to remove, already removed",
1015 __FUNCTION__);
1016 }
1017}
1018
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07001019void Camera3Stream::setBufferFreedListener(
Yin-Chia Yehdb1e8642017-07-14 15:19:30 -07001020 wp<Camera3StreamBufferFreedListener> listener) {
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07001021 Mutex::Autolock l(mLock);
1022 // Only allow set listener during stream configuration because stream is guaranteed to be IDLE
1023 // at this state, so setBufferFreedListener won't collide with onBufferFreed callbacks
1024 if (mState != STATE_IN_CONFIG && mState != STATE_IN_RECONFIG) {
1025 ALOGE("%s: listener must be set during stream configuration!",__FUNCTION__);
1026 return;
1027 }
1028 mBufferFreedListener = listener;
1029}
1030
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001031status_t Camera3Stream::getBuffers(std::vector<OutstandingBuffer>* buffers,
1032 nsecs_t waitBufferTimeout) {
1033 ATRACE_CALL();
1034 Mutex::Autolock l(mLock);
1035 status_t res = OK;
1036
1037 if (buffers == nullptr) {
1038 ALOGI("%s: buffers must not be null!", __FUNCTION__);
1039 return BAD_VALUE;
1040 }
1041
1042 size_t numBuffersRequested = buffers->size();
1043 if (numBuffersRequested == 0) {
1044 ALOGE("%s: 0 buffers are requested!", __FUNCTION__);
1045 return BAD_VALUE;
1046 }
1047
1048 // This function should be only called when the stream is configured already.
1049 if (mState != STATE_CONFIGURED) {
1050 ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
1051 __FUNCTION__, mId, mState);
1052 if (mState == STATE_ABANDONED) {
1053 return DEAD_OBJECT;
1054 } else {
1055 return INVALID_OPERATION;
1056 }
1057 }
1058
1059 size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked();
1060 // Wait for new buffer returned back if we are running into the limit.
1061 while (numOutstandingBuffers + numBuffersRequested > camera_stream::max_buffers) {
1062 ALOGV("%s: Already dequeued %zu output buffers and requesting %zu (max is %d), waiting.",
1063 __FUNCTION__, numOutstandingBuffers, numBuffersRequested,
1064 camera_stream::max_buffers);
1065 nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
1066 if (waitBufferTimeout < kWaitForBufferDuration) {
1067 waitBufferTimeout = kWaitForBufferDuration;
1068 }
1069 res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
1070 nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
1071 mBufferLimitLatency.add(waitStart, waitEnd);
1072 if (res != OK) {
1073 if (res == TIMED_OUT) {
1074 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
1075 __FUNCTION__, waitBufferTimeout / 1000000LL,
1076 camera_stream::max_buffers);
1077 }
1078 return res;
1079 }
1080 size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked();
1081 if (updatedNumOutstandingBuffers >= numOutstandingBuffers) {
1082 ALOGE("%s: outsanding buffer count goes from %zu to %zu, "
1083 "getBuffer(s) call must not run in parallel!", __FUNCTION__,
1084 numOutstandingBuffers, updatedNumOutstandingBuffers);
1085 return INVALID_OPERATION;
1086 }
1087 numOutstandingBuffers = updatedNumOutstandingBuffers;
1088 }
1089
1090 res = getBuffersLocked(buffers);
1091 if (res == OK) {
1092 for (auto& outstandingBuffer : *buffers) {
1093 camera_stream_buffer* buffer = outstandingBuffer.outBuffer;
1094 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
1095 if (buffer->buffer) {
1096 Mutex::Autolock l(mOutstandingBuffersLock);
1097 mOutstandingBuffers.push_back(*buffer->buffer);
1098 }
1099 }
1100 }
1101
1102 return res;
1103}
1104
Emilian Peev2295df72021-11-12 18:14:10 -08001105void Camera3Stream::queueHDRMetadata(buffer_handle_t buffer, sp<ANativeWindow>& anw,
Emilian Peevc81a7592022-02-14 17:38:18 -08001106 int64_t dynamicRangeProfile) {
Emilian Peev2295df72021-11-12 18:14:10 -08001107 auto& mapper = GraphicBufferMapper::get();
1108 switch (dynamicRangeProfile) {
1109 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10: {
1110 std::optional<ui::Smpte2086> smpte2086;
1111 auto res = mapper.getSmpte2086(buffer, &smpte2086);
1112 if ((res == OK) && smpte2086.has_value()) {
1113 const auto& metaValue = smpte2086.value();
1114 android_smpte2086_metadata meta = {
1115 .displayPrimaryRed.x = metaValue.primaryRed.x,
1116 .displayPrimaryRed.y = metaValue.primaryRed.y,
1117 .displayPrimaryGreen.x = metaValue.primaryGreen.x,
1118 .displayPrimaryGreen.y = metaValue.primaryGreen.y,
1119 .displayPrimaryBlue.x = metaValue.primaryBlue.x,
1120 .displayPrimaryBlue.y = metaValue.primaryBlue.y,
1121 .whitePoint.x = metaValue.whitePoint.x,
1122 .whitePoint.y = metaValue.whitePoint.y,
1123 .maxLuminance = metaValue.maxLuminance,
1124 .minLuminance = metaValue.minLuminance};
1125 native_window_set_buffers_smpte2086_metadata(anw.get(), &meta);
1126 } else {
1127 ALOGE("%s Couldn't retrieve Smpte2086 metadata %s (%d)",
1128 __FUNCTION__, strerror(-res), res);
1129 }
1130 break;
1131 }
1132 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS: {
1133 std::optional<std::vector<uint8_t>> smpte2094_40;
1134 auto res = mapper.getSmpte2094_40(buffer, &smpte2094_40);
1135 if ((res == OK) && smpte2094_40.has_value()) {
1136 native_window_set_buffers_hdr10_plus_metadata(anw.get(),
1137 smpte2094_40.value().size(), smpte2094_40.value().data());
1138 } else {
1139 ALOGE("%s Couldn't retrieve Smpte2094_40 metadata %s (%d)",
1140 __FUNCTION__, strerror(-res), res);
1141 }
1142 break;
1143 }
1144 default:
1145 // No-op
1146 break;
1147 }
1148}
1149
1150
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -08001151}; // namespace camera3
1152
1153}; // namespace android