blob: 83f9a98bf4d7b225186a2049dae77c67a009016c [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 Peev2295df72021-11-12 18:14:10 -080057 int setId, bool isMultiResolution, int dynamicRangeProfile) :
Emilian Peevf4816702020-04-03 15:44:51 -070058 camera_stream(),
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080059 mId(id),
Zhijun He125684a2015-12-26 15:07:30 -080060 mSetId(setId),
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080061 mName(String8::format("Camera3Stream[%d]", id)),
62 mMaxSize(maxSize),
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -070063 mState(STATE_CONSTRUCTED),
Ruben Brunkc78ac262015-08-13 17:58:46 -070064 mStatusId(StatusTracker::NO_STATUS_ID),
Zhijun He5d677d12016-05-29 16:52:39 -070065 mStreamUnpreparable(true),
Emilian Peev050f5dc2017-05-18 14:43:56 +010066 mUsage(0),
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080067 mOldUsage(0),
68 mOldMaxBuffers(0),
Shuzhen Wangf9b4eb92019-06-10 11:06:01 -070069 mOldFormat(-1),
70 mOldDataSpace(HAL_DATASPACE_UNKNOWN),
Zhijun He125684a2015-12-26 15:07:30 -080071 mPrepared(false),
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -070072 mPrepareBlockRequest(true),
Zhijun He125684a2015-12-26 15:07:30 -080073 mPreparedBufferIdx(0),
Shuzhen Wang686f6442017-06-20 16:16:04 -070074 mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX),
Emilian Peev710c1422017-08-30 11:19:38 +010075 mBufferLimitLatency(kBufferLimitLatencyBinSize),
76 mFormatOverridden(false),
Yin-Chia Yeh90667662019-07-01 15:45:00 -070077 mOriginalFormat(format),
Shuzhen Wang92653952019-05-07 15:11:43 -070078 mDataSpaceOverridden(false),
Shuzhen Wang2f5010d2019-08-22 12:41:12 -070079 mOriginalDataSpace(dataSpace),
Shuzhen Wang26abaf42018-08-28 15:41:20 -070080 mPhysicalCameraId(physicalCameraId),
Shuzhen Wang83bff122020-11-20 15:51:39 -080081 mLastTimestamp(0),
82 mIsMultiResolution(isMultiResolution) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080083
Emilian Peevf4816702020-04-03 15:44:51 -070084 camera_stream::stream_type = type;
85 camera_stream::width = width;
86 camera_stream::height = height;
87 camera_stream::format = format;
88 camera_stream::data_space = dataSpace;
89 camera_stream::rotation = rotation;
90 camera_stream::max_buffers = 0;
91 camera_stream::physical_camera_id = mPhysicalCameraId.string();
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -080092 camera_stream::sensor_pixel_modes_used = sensorPixelModesUsed;
Emilian Peev2295df72021-11-12 18:14:10 -080093 camera_stream::dynamic_range_profile = dynamicRangeProfile;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080094
Yin-Chia Yehe9154ce2015-12-07 14:38:04 -080095 if ((format == HAL_PIXEL_FORMAT_BLOB || format == HAL_PIXEL_FORMAT_RAW_OPAQUE) &&
96 maxSize == 0) {
97 ALOGE("%s: BLOB or RAW_OPAQUE format with size == 0", __FUNCTION__);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -080098 mState = STATE_ERROR;
99 }
100}
101
102int Camera3Stream::getId() const {
103 return mId;
104}
105
Zhijun He125684a2015-12-26 15:07:30 -0800106int Camera3Stream::getStreamSetId() const {
107 return mSetId;
108}
109
Shuzhen Wang83bff122020-11-20 15:51:39 -0800110int Camera3Stream::getHalStreamGroupId() const {
111 return mIsMultiResolution ? mSetId : -1;
112}
113
114bool Camera3Stream::isMultiResolution() const {
115 return mIsMultiResolution;
116}
117
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800118uint32_t Camera3Stream::getWidth() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700119 return camera_stream::width;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800120}
121
122uint32_t Camera3Stream::getHeight() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700123 return camera_stream::height;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800124}
125
126int Camera3Stream::getFormat() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700127 return camera_stream::format;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800128}
129
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800130android_dataspace Camera3Stream::getDataSpace() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700131 return camera_stream::data_space;
Eino-Ville Talvala3d82c0d2015-02-23 15:19:19 -0800132}
133
Emilian Peev050f5dc2017-05-18 14:43:56 +0100134uint64_t Camera3Stream::getUsage() const {
135 return mUsage;
136}
137
138void Camera3Stream::setUsage(uint64_t usage) {
139 mUsage = usage;
140}
141
Emilian Peev710c1422017-08-30 11:19:38 +0100142void Camera3Stream::setFormatOverride(bool formatOverridden) {
143 mFormatOverridden = formatOverridden;
144}
145
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700146bool Camera3Stream::isFormatOverridden() const {
Emilian Peev710c1422017-08-30 11:19:38 +0100147 return mFormatOverridden;
148}
149
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700150int Camera3Stream::getOriginalFormat() const {
151 return mOriginalFormat;
Emilian Peev710c1422017-08-30 11:19:38 +0100152}
153
Emilian Peev2295df72021-11-12 18:14:10 -0800154int Camera3Stream::getDynamicRangeProfile() const {
155 return camera_stream::dynamic_range_profile;
156}
157
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700158void Camera3Stream::setDataSpaceOverride(bool dataSpaceOverridden) {
159 mDataSpaceOverridden = dataSpaceOverridden;
Eino-Ville Talvala91cd3f82017-08-21 16:12:50 -0700160}
161
162bool Camera3Stream::isDataSpaceOverridden() const {
163 return mDataSpaceOverridden;
164}
165
166android_dataspace Camera3Stream::getOriginalDataSpace() const {
167 return mOriginalDataSpace;
Emilian Peev710c1422017-08-30 11:19:38 +0100168}
169
Shuzhen Wang5c22c152017-12-31 17:12:25 -0800170const String8& Camera3Stream::physicalCameraId() const {
171 return mPhysicalCameraId;
172}
173
Shuzhen Wang316781a2020-08-18 18:11:01 -0700174int Camera3Stream::getMaxHalBuffers() const {
Emilian Peevf4816702020-04-03 15:44:51 -0700175 return camera_stream::max_buffers;
Shuzhen Wang316781a2020-08-18 18:11:01 -0700176}
177
Yin-Chia Yeh5fd603e2019-11-20 11:22:27 -0800178void Camera3Stream::setOfflineProcessingSupport(bool support) {
179 mSupportOfflineProcessing = support;
180}
181
182bool Camera3Stream::getOfflineProcessingSupport() const {
183 return mSupportOfflineProcessing;
184}
185
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000186status_t Camera3Stream::forceToIdle() {
187 ATRACE_CALL();
188 Mutex::Autolock l(mLock);
189 status_t res;
190
191 switch (mState) {
192 case STATE_ERROR:
193 case STATE_CONSTRUCTED:
194 case STATE_IN_CONFIG:
195 case STATE_PREPARING:
196 case STATE_IN_RECONFIG:
197 ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
198 res = NO_INIT;
199 break;
200 case STATE_CONFIGURED:
201 if (hasOutstandingBuffersLocked()) {
202 sp<StatusTracker> statusTracker = mStatusTracker.promote();
203 if (statusTracker != 0) {
204 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
205 }
206 }
207
208 mState = STATE_IN_IDLE;
209 res = OK;
210
211 break;
212 default:
213 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
214 res = NO_INIT;
215 }
216
217 return res;
218}
219
220status_t Camera3Stream::restoreConfiguredState() {
221 ATRACE_CALL();
222 Mutex::Autolock l(mLock);
223 status_t res;
224
225 switch (mState) {
226 case STATE_ERROR:
227 case STATE_CONSTRUCTED:
228 case STATE_IN_CONFIG:
229 case STATE_PREPARING:
230 case STATE_IN_RECONFIG:
231 case STATE_CONFIGURED:
232 ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
233 res = NO_INIT;
234 break;
235 case STATE_IN_IDLE:
236 if (hasOutstandingBuffersLocked()) {
237 sp<StatusTracker> statusTracker = mStatusTracker.promote();
238 if (statusTracker != 0) {
239 statusTracker->markComponentActive(mStatusId);
240 }
241 }
242
243 mState = STATE_CONFIGURED;
244 res = OK;
245
246 break;
247 default:
248 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
249 res = NO_INIT;
250 }
251
252 return res;
253}
254
Emilian Peevf4816702020-04-03 15:44:51 -0700255camera_stream* Camera3Stream::startConfiguration() {
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700256 ATRACE_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800257 Mutex::Autolock l(mLock);
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700258 status_t res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800259
260 switch (mState) {
261 case STATE_ERROR:
262 ALOGE("%s: In error state", __FUNCTION__);
263 return NULL;
264 case STATE_CONSTRUCTED:
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000265 case STATE_IN_IDLE:
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800266 // OK
267 break;
268 case STATE_IN_CONFIG:
269 case STATE_IN_RECONFIG:
270 // Can start config again with no trouble; but don't redo
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800271 // mOldUsage/mOldMaxBuffers
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800272 return this;
273 case STATE_CONFIGURED:
Chien-Yu Chen90746f42015-04-15 13:50:13 -0700274 if (hasOutstandingBuffersLocked()) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800275 ALOGE("%s: Cannot configure stream; has outstanding buffers",
276 __FUNCTION__);
277 return NULL;
278 }
279 break;
280 default:
281 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
282 return NULL;
283 }
284
Emilian Peev050f5dc2017-05-18 14:43:56 +0100285 mOldUsage = mUsage;
Emilian Peevf4816702020-04-03 15:44:51 -0700286 mOldMaxBuffers = camera_stream::max_buffers;
287 mOldFormat = camera_stream::format;
288 mOldDataSpace = camera_stream::data_space;
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700289
Emilian Peev050f5dc2017-05-18 14:43:56 +0100290 res = getEndpointUsage(&mUsage);
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700291 if (res != OK) {
292 ALOGE("%s: Cannot query consumer endpoint usage!",
293 __FUNCTION__);
294 return NULL;
295 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800296
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000297 if (mState == STATE_IN_IDLE) {
298 // Skip configuration.
299 return this;
300 }
301
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700302 // Stop tracking if currently doing so
303 if (mStatusId != StatusTracker::NO_STATUS_ID) {
304 sp<StatusTracker> statusTracker = mStatusTracker.promote();
305 if (statusTracker != 0) {
306 statusTracker->removeComponent(mStatusId);
307 }
308 mStatusId = StatusTracker::NO_STATUS_ID;
309 }
310
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800311 if (mState == STATE_CONSTRUCTED) {
312 mState = STATE_IN_CONFIG;
313 } else { // mState == STATE_CONFIGURED
Igor Murashkin13d315e2014-04-03 18:09:04 -0700314 LOG_ALWAYS_FATAL_IF(mState != STATE_CONFIGURED, "Invalid state: 0x%x", mState);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800315 mState = STATE_IN_RECONFIG;
316 }
317
318 return this;
319}
320
321bool Camera3Stream::isConfiguring() const {
322 Mutex::Autolock l(mLock);
323 return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
324}
325
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700326status_t Camera3Stream::finishConfiguration(/*out*/bool* streamReconfigured) {
Eino-Ville Talvalab2f5b192013-07-30 14:36:03 -0700327 ATRACE_CALL();
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700328 if (streamReconfigured != nullptr) {
329 *streamReconfigured = false;
330 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800331 Mutex::Autolock l(mLock);
332 switch (mState) {
333 case STATE_ERROR:
334 ALOGE("%s: In error state", __FUNCTION__);
335 return INVALID_OPERATION;
336 case STATE_IN_CONFIG:
337 case STATE_IN_RECONFIG:
338 // OK
339 break;
340 case STATE_CONSTRUCTED:
341 case STATE_CONFIGURED:
342 ALOGE("%s: Cannot finish configuration that hasn't been started",
343 __FUNCTION__);
344 return INVALID_OPERATION;
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000345 case STATE_IN_IDLE:
346 //Skip configuration in this state
347 return OK;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800348 default:
349 ALOGE("%s: Unknown state", __FUNCTION__);
350 return INVALID_OPERATION;
351 }
352
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700353 // Register for idle tracking
354 sp<StatusTracker> statusTracker = mStatusTracker.promote();
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700355 if (statusTracker != 0 && mStatusId == StatusTracker::NO_STATUS_ID) {
Yin-Chia Yeh87b3ec02019-06-03 10:44:39 -0700356 std::string name = std::string("Stream ") + std::to_string(mId);
357 mStatusId = statusTracker->addComponent(name.c_str());
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700358 }
359
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800360 // Check if the stream configuration is unchanged, and skip reallocation if
Emilian Peevf4816702020-04-03 15:44:51 -0700361 // so.
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800362 if (mState == STATE_IN_RECONFIG &&
Emilian Peev050f5dc2017-05-18 14:43:56 +0100363 mOldUsage == mUsage &&
Emilian Peevf4816702020-04-03 15:44:51 -0700364 mOldMaxBuffers == camera_stream::max_buffers &&
365 mOldDataSpace == camera_stream::data_space &&
366 mOldFormat == camera_stream::format) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800367 mState = STATE_CONFIGURED;
368 return OK;
369 }
370
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700371 // Reset prepared state, since buffer config has changed, and existing
372 // allocations are no longer valid
373 mPrepared = false;
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700374 mPrepareBlockRequest = true;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700375 mStreamUnpreparable = false;
376
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700377 bool reconfiguring = (mState == STATE_IN_RECONFIG);
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800378 status_t res;
379 res = configureQueueLocked();
Shuzhen Wang210ba5c2018-07-25 16:47:40 -0700380 // configureQueueLocked could return error in case of abandoned surface.
381 // Treat as non-fatal error.
382 if (res == NO_INIT || res == DEAD_OBJECT) {
383 ALOGE("%s: Unable to configure stream %d queue (non-fatal): %s (%d)",
384 __FUNCTION__, mId, strerror(-res), res);
385 mState = STATE_ABANDONED;
386 return res;
387 } else if (res != OK) {
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800388 ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
389 __FUNCTION__, mId, strerror(-res), res);
390 mState = STATE_ERROR;
391 return res;
392 }
393
Yin-Chia Yeh573a2702019-04-17 10:08:55 -0700394 if (reconfiguring && streamReconfigured != nullptr) {
395 *streamReconfigured = true;
396 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800397 mState = STATE_CONFIGURED;
398
399 return res;
400}
401
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700402status_t Camera3Stream::cancelConfiguration() {
403 ATRACE_CALL();
404 Mutex::Autolock l(mLock);
405 switch (mState) {
406 case STATE_ERROR:
407 ALOGE("%s: In error state", __FUNCTION__);
408 return INVALID_OPERATION;
409 case STATE_IN_CONFIG:
410 case STATE_IN_RECONFIG:
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000411 case STATE_IN_IDLE:
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700412 // OK
413 break;
414 case STATE_CONSTRUCTED:
415 case STATE_CONFIGURED:
416 ALOGE("%s: Cannot cancel configuration that hasn't been started",
417 __FUNCTION__);
418 return INVALID_OPERATION;
419 default:
420 ALOGE("%s: Unknown state", __FUNCTION__);
421 return INVALID_OPERATION;
422 }
423
Emilian Peev050f5dc2017-05-18 14:43:56 +0100424 mUsage = mOldUsage;
Emilian Peevf4816702020-04-03 15:44:51 -0700425 camera_stream::max_buffers = mOldMaxBuffers;
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700426
Emilian Peevac3ce6c2017-12-12 15:27:02 +0000427 mState = ((mState == STATE_IN_RECONFIG) || (mState == STATE_IN_IDLE)) ? STATE_CONFIGURED :
428 STATE_CONSTRUCTED;
429
Eino-Ville Talvala17543512014-08-06 14:32:02 -0700430 return OK;
431}
432
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700433bool Camera3Stream::isUnpreparable() {
434 ATRACE_CALL();
435
436 Mutex::Autolock l(mLock);
437 return mStreamUnpreparable;
438}
439
Emilian Peevf0348ae2021-01-13 13:39:45 -0800440void Camera3Stream::markUnpreparable() {
441 ATRACE_CALL();
442
443 Mutex::Autolock l(mLock);
444 mStreamUnpreparable = true;
445}
446
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700447status_t Camera3Stream::startPrepare(int maxCount, bool blockRequest) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700448 ATRACE_CALL();
449
450 Mutex::Autolock l(mLock);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700451
Ruben Brunkc78ac262015-08-13 17:58:46 -0700452 if (maxCount < 0) {
453 ALOGE("%s: Stream %d: Can't prepare stream if max buffer count (%d) is < 0",
454 __FUNCTION__, mId, maxCount);
455 return BAD_VALUE;
456 }
457
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700458 // This function should be only called when the stream is configured already.
459 if (mState != STATE_CONFIGURED) {
460 ALOGE("%s: Stream %d: Can't prepare stream if stream is not in CONFIGURED "
461 "state %d", __FUNCTION__, mId, mState);
462 return INVALID_OPERATION;
463 }
464
465 // This function can't be called if the stream has already received filled
466 // buffers
467 if (mStreamUnpreparable) {
468 ALOGE("%s: Stream %d: Can't prepare stream that's already in use",
469 __FUNCTION__, mId);
470 return INVALID_OPERATION;
471 }
472
473 if (getHandoutOutputBufferCountLocked() > 0) {
474 ALOGE("%s: Stream %d: Can't prepare stream that has outstanding buffers",
475 __FUNCTION__, mId);
476 return INVALID_OPERATION;
477 }
478
Ruben Brunkc78ac262015-08-13 17:58:46 -0700479 size_t pipelineMax = getBufferCountLocked();
480 size_t clampedCount = (pipelineMax < static_cast<size_t>(maxCount)) ?
481 pipelineMax : static_cast<size_t>(maxCount);
482 size_t bufferCount = (maxCount == Camera3StreamInterface::ALLOCATE_PIPELINE_MAX) ?
483 pipelineMax : clampedCount;
484
485 mPrepared = bufferCount <= mLastMaxCount;
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700486 mPrepareBlockRequest = blockRequest;
Ruben Brunkc78ac262015-08-13 17:58:46 -0700487
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700488 if (mPrepared) return OK;
489
Ruben Brunkc78ac262015-08-13 17:58:46 -0700490 mLastMaxCount = bufferCount;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700491
Emilian Peevf4816702020-04-03 15:44:51 -0700492 mPreparedBuffers.insertAt(camera_stream_buffer_t(), /*index*/0, bufferCount);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700493 mPreparedBufferIdx = 0;
494
495 mState = STATE_PREPARING;
496
497 return NOT_ENOUGH_DATA;
498}
499
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700500bool Camera3Stream::isBlockedByPrepare() const {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700501 Mutex::Autolock l(mLock);
Shuzhen Wangb3a0fb52018-09-13 17:24:08 -0700502 return mState == STATE_PREPARING && mPrepareBlockRequest;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700503}
504
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700505bool Camera3Stream::isAbandoned() const {
506 Mutex::Autolock l(mLock);
507 return mState == STATE_ABANDONED;
508}
509
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700510status_t Camera3Stream::prepareNextBuffer() {
511 ATRACE_CALL();
512
513 Mutex::Autolock l(mLock);
514 status_t res = OK;
515
516 // This function should be only called when the stream is preparing
517 if (mState != STATE_PREPARING) {
518 ALOGE("%s: Stream %d: Can't prepare buffer if stream is not in PREPARING "
519 "state %d", __FUNCTION__, mId, mState);
520 return INVALID_OPERATION;
521 }
522
523 // Get next buffer - this may allocate, and take a while for large buffers
524 res = getBufferLocked( &mPreparedBuffers.editItemAt(mPreparedBufferIdx) );
525 if (res != OK) {
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800526 ALOGE("%s: Stream %d: Unable to allocate buffer %zu during preparation",
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700527 __FUNCTION__, mId, mPreparedBufferIdx);
528 return NO_INIT;
529 }
530
531 mPreparedBufferIdx++;
532
533 // Check if we still have buffers left to allocate
534 if (mPreparedBufferIdx < mPreparedBuffers.size()) {
535 return NOT_ENOUGH_DATA;
536 }
537
538 // Done with prepare - mark stream as such, and return all buffers
539 // via cancelPrepare
540 mPrepared = true;
541
542 return cancelPrepareLocked();
543}
544
545status_t Camera3Stream::cancelPrepare() {
546 ATRACE_CALL();
547
548 Mutex::Autolock l(mLock);
549
550 return cancelPrepareLocked();
551}
552
553status_t Camera3Stream::cancelPrepareLocked() {
554 status_t res = OK;
555
556 // This function should be only called when the stream is mid-preparing.
557 if (mState != STATE_PREPARING) {
558 ALOGE("%s: Stream %d: Can't cancel prepare stream if stream is not in "
559 "PREPARING state %d", __FUNCTION__, mId, mState);
560 return INVALID_OPERATION;
561 }
562
563 // Return all valid buffers to stream, in ERROR state to indicate
564 // they weren't filled.
565 for (size_t i = 0; i < mPreparedBufferIdx; i++) {
566 mPreparedBuffers.editItemAt(i).release_fence = -1;
Emilian Peevf4816702020-04-03 15:44:51 -0700567 mPreparedBuffers.editItemAt(i).status = CAMERA_BUFFER_STATUS_ERROR;
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700568 returnBufferLocked(mPreparedBuffers[i], /*timestamp*/0, /*readoutTimestamp*/0,
569 /*transform*/ -1);
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -0700570 }
571 mPreparedBuffers.clear();
572 mPreparedBufferIdx = 0;
573
574 mState = STATE_CONFIGURED;
575
576 return res;
577}
578
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -0700579status_t Camera3Stream::tearDown() {
580 ATRACE_CALL();
581 Mutex::Autolock l(mLock);
582
583 status_t res = OK;
584
585 // This function should be only called when the stream is configured.
586 if (mState != STATE_CONFIGURED) {
587 ALOGE("%s: Stream %d: Can't tear down stream if stream is not in "
588 "CONFIGURED state %d", __FUNCTION__, mId, mState);
589 return INVALID_OPERATION;
590 }
591
592 // If any buffers have been handed to the HAL, the stream cannot be torn down.
593 if (getHandoutOutputBufferCountLocked() > 0) {
594 ALOGE("%s: Stream %d: Can't tear down a stream that has outstanding buffers",
595 __FUNCTION__, mId);
596 return INVALID_OPERATION;
597 }
598
599 // Free buffers by disconnecting and then reconnecting to the buffer queue
600 // Only unused buffers will be dropped immediately; buffers that have been filled
601 // and are waiting to be acquired by the consumer and buffers that are currently
602 // acquired will be freed once they are released by the consumer.
603
604 res = disconnectLocked();
605 if (res != OK) {
606 if (res == -ENOTCONN) {
607 // queue has been disconnected, nothing left to do, so exit with success
608 return OK;
609 }
610 ALOGE("%s: Stream %d: Unable to disconnect to tear down buffers: %s (%d)",
611 __FUNCTION__, mId, strerror(-res), res);
612 return res;
613 }
614
615 mState = STATE_IN_CONFIG;
616
617 res = configureQueueLocked();
618 if (res != OK) {
619 ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
620 __FUNCTION__, mId, strerror(-res), res);
621 mState = STATE_ERROR;
622 return res;
623 }
624
625 // Reset prepared state, since we've reconnected to the queue and can prepare again.
626 mPrepared = false;
627 mStreamUnpreparable = false;
628
629 mState = STATE_CONFIGURED;
630
631 return OK;
632}
633
Emilian Peevf4816702020-04-03 15:44:51 -0700634status_t Camera3Stream::getBuffer(camera_stream_buffer *buffer,
Yin-Chia Yehb3a80b12018-09-04 12:13:05 -0700635 nsecs_t waitBufferTimeout,
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800636 const std::vector<size_t>& surface_ids) {
Jayant Chowdharyd4776262020-06-23 23:45:57 -0700637 ATRACE_HFR_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800638 Mutex::Autolock l(mLock);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700639 status_t res = OK;
Igor Murashkin2fba5842013-04-22 14:03:54 -0700640
Zhijun He6adc9cc2014-04-15 14:09:55 -0700641 // This function should be only called when the stream is configured already.
642 if (mState != STATE_CONFIGURED) {
643 ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
644 __FUNCTION__, mId, mState);
Yin-Chia Yehcd333fe2019-02-08 13:45:41 -0800645 if (mState == STATE_ABANDONED) {
646 return DEAD_OBJECT;
647 } else {
648 return INVALID_OPERATION;
649 }
Zhijun He6adc9cc2014-04-15 14:09:55 -0700650 }
651
652 // Wait for new buffer returned back if we are running into the limit.
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800653 size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked();
654 if (numOutstandingBuffers == camera_stream::max_buffers) {
Zhijun He6adc9cc2014-04-15 14:09:55 -0700655 ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.",
Emilian Peevf4816702020-04-03 15:44:51 -0700656 __FUNCTION__, camera_stream::max_buffers);
Shuzhen Wang686f6442017-06-20 16:16:04 -0700657 nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
Yin-Chia Yehb3a80b12018-09-04 12:13:05 -0700658 if (waitBufferTimeout < kWaitForBufferDuration) {
659 waitBufferTimeout = kWaitForBufferDuration;
660 }
661 res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
Shuzhen Wang686f6442017-06-20 16:16:04 -0700662 nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
663 mBufferLimitLatency.add(waitStart, waitEnd);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700664 if (res != OK) {
665 if (res == TIMED_OUT) {
Chien-Yu Chen85a64552015-08-28 15:46:12 -0700666 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
Yin-Chia Yehb3a80b12018-09-04 12:13:05 -0700667 __FUNCTION__, waitBufferTimeout / 1000000LL,
Emilian Peevf4816702020-04-03 15:44:51 -0700668 camera_stream::max_buffers);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700669 }
670 return res;
671 }
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800672
673 size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked();
674 if (updatedNumOutstandingBuffers >= numOutstandingBuffers) {
675 ALOGE("%s: outsanding buffer count goes from %zu to %zu, "
676 "getBuffer(s) call must not run in parallel!", __FUNCTION__,
677 numOutstandingBuffers, updatedNumOutstandingBuffers);
678 return INVALID_OPERATION;
679 }
Zhijun He6adc9cc2014-04-15 14:09:55 -0700680 }
681
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800682 res = getBufferLocked(buffer, surface_ids);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700683 if (res == OK) {
684 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700685 if (buffer->buffer) {
Emilian Peev889234d2017-07-18 18:21:26 -0700686 Mutex::Autolock l(mOutstandingBuffersLock);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700687 mOutstandingBuffers.push_back(*buffer->buffer);
688 }
Igor Murashkin2fba5842013-04-22 14:03:54 -0700689 }
690
691 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800692}
693
Emilian Peevf4816702020-04-03 15:44:51 -0700694bool Camera3Stream::isOutstandingBuffer(const camera_stream_buffer &buffer) const{
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700695 if (buffer.buffer == nullptr) {
696 return false;
697 }
698
Emilian Peev889234d2017-07-18 18:21:26 -0700699 Mutex::Autolock l(mOutstandingBuffersLock);
700
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700701 for (auto b : mOutstandingBuffers) {
702 if (b == *buffer.buffer) {
703 return true;
704 }
705 }
706 return false;
707}
708
Emilian Peevf4816702020-04-03 15:44:51 -0700709void Camera3Stream::removeOutstandingBuffer(const camera_stream_buffer &buffer) {
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700710 if (buffer.buffer == nullptr) {
711 return;
712 }
713
Emilian Peev889234d2017-07-18 18:21:26 -0700714 Mutex::Autolock l(mOutstandingBuffersLock);
715
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700716 for (auto b = mOutstandingBuffers.begin(); b != mOutstandingBuffers.end(); b++) {
717 if (*b == *buffer.buffer) {
718 mOutstandingBuffers.erase(b);
719 return;
720 }
721 }
722}
723
Emilian Peevf4816702020-04-03 15:44:51 -0700724status_t Camera3Stream::returnBuffer(const camera_stream_buffer &buffer,
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700725 nsecs_t timestamp, nsecs_t readoutTimestamp, bool timestampIncreasing,
Emilian Peev5104fe92021-10-21 14:27:09 -0700726 const std::vector<size_t>& surface_ids, uint64_t frameNumber, int32_t transform) {
Jayant Chowdharyd4776262020-06-23 23:45:57 -0700727 ATRACE_HFR_CALL();
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800728 Mutex::Autolock l(mLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700729
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700730 // Check if this buffer is outstanding.
731 if (!isOutstandingBuffer(buffer)) {
732 ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
733 return BAD_VALUE;
734 }
735
Shuzhen Wang1c484a62017-07-14 15:14:19 -0700736 removeOutstandingBuffer(buffer);
737
Shuzhen Wangf0c4a6b2018-09-05 09:36:14 -0700738 // Buffer status may be changed, so make a copy of the stream_buffer struct.
Emilian Peevf4816702020-04-03 15:44:51 -0700739 camera_stream_buffer b = buffer;
Shuzhen Wang26abaf42018-08-28 15:41:20 -0700740 if (timestampIncreasing && timestamp != 0 && timestamp <= mLastTimestamp) {
Shuzhen Wangf0c4a6b2018-09-05 09:36:14 -0700741 ALOGE("%s: Stream %d: timestamp %" PRId64 " is not increasing. Prev timestamp %" PRId64,
Shuzhen Wang26abaf42018-08-28 15:41:20 -0700742 __FUNCTION__, mId, timestamp, mLastTimestamp);
Emilian Peevf4816702020-04-03 15:44:51 -0700743 b.status = CAMERA_BUFFER_STATUS_ERROR;
Shuzhen Wang26abaf42018-08-28 15:41:20 -0700744 }
745 mLastTimestamp = timestamp;
746
Igor Murashkin13d315e2014-04-03 18:09:04 -0700747 /**
748 * TODO: Check that the state is valid first.
749 *
750 * <HAL3.2 IN_CONFIG and IN_RECONFIG in addition to CONFIGURED.
751 * >= HAL3.2 CONFIGURED only
752 *
753 * Do this for getBuffer as well.
754 */
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700755 status_t res = returnBufferLocked(b, timestamp, readoutTimestamp, transform, surface_ids);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700756 if (res == OK) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000757 fireBufferListenersLocked(b, /*acquired*/false, /*output*/true, timestamp, frameNumber);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700758 }
759
Chien-Yu Chenb83c1fe2015-09-10 16:15:21 -0700760 // Even if returning the buffer failed, we still want to signal whoever is waiting for the
761 // buffer to be returned.
762 mOutputBufferReturnedSignal.signal();
763
Igor Murashkin2fba5842013-04-22 14:03:54 -0700764 return res;
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800765}
766
Shuzhen Wang83bff122020-11-20 15:51:39 -0800767status_t Camera3Stream::getInputBuffer(camera_stream_buffer *buffer,
768 Size* size, bool respectHalLimit) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700769 ATRACE_CALL();
770 Mutex::Autolock l(mLock);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700771 status_t res = OK;
Igor Murashkin2fba5842013-04-22 14:03:54 -0700772
Shuzhen Wang83bff122020-11-20 15:51:39 -0800773 if (size == nullptr) {
774 ALOGE("%s: size must not be null", __FUNCTION__);
775 return BAD_VALUE;
776 }
Zhijun He6adc9cc2014-04-15 14:09:55 -0700777 // This function should be only called when the stream is configured already.
778 if (mState != STATE_CONFIGURED) {
779 ALOGE("%s: Stream %d: Can't get input buffers if stream is not in CONFIGURED state %d",
780 __FUNCTION__, mId, mState);
781 return INVALID_OPERATION;
782 }
783
784 // Wait for new buffer returned back if we are running into the limit.
Emilian Peevf4816702020-04-03 15:44:51 -0700785 if (getHandoutInputBufferCountLocked() == camera_stream::max_buffers && respectHalLimit) {
Zhijun He6adc9cc2014-04-15 14:09:55 -0700786 ALOGV("%s: Already dequeued max input buffers (%d), wait for next returned one.",
Emilian Peevf4816702020-04-03 15:44:51 -0700787 __FUNCTION__, camera_stream::max_buffers);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700788 res = mInputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
789 if (res != OK) {
790 if (res == TIMED_OUT) {
791 ALOGE("%s: wait for input buffer return timed out after %lldms", __FUNCTION__,
792 kWaitForBufferDuration / 1000000LL);
793 }
794 return res;
795 }
796 }
797
Shuzhen Wang83bff122020-11-20 15:51:39 -0800798 res = getInputBufferLocked(buffer, size);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700799 if (res == OK) {
800 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700801 if (buffer->buffer) {
Emilian Peev889234d2017-07-18 18:21:26 -0700802 Mutex::Autolock l(mOutstandingBuffersLock);
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700803 mOutstandingBuffers.push_back(*buffer->buffer);
804 }
Igor Murashkin2fba5842013-04-22 14:03:54 -0700805 }
806
807 return res;
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700808}
809
Emilian Peevf4816702020-04-03 15:44:51 -0700810status_t Camera3Stream::returnInputBuffer(const camera_stream_buffer &buffer) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700811 ATRACE_CALL();
812 Mutex::Autolock l(mLock);
Igor Murashkin2fba5842013-04-22 14:03:54 -0700813
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700814 // Check if this buffer is outstanding.
815 if (!isOutstandingBuffer(buffer)) {
816 ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
817 return BAD_VALUE;
818 }
819
Shuzhen Wang1c484a62017-07-14 15:14:19 -0700820 removeOutstandingBuffer(buffer);
821
Igor Murashkin2fba5842013-04-22 14:03:54 -0700822 status_t res = returnInputBufferLocked(buffer);
823 if (res == OK) {
824 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
Zhijun He6adc9cc2014-04-15 14:09:55 -0700825 mInputBufferReturnedSignal.signal();
Igor Murashkin2fba5842013-04-22 14:03:54 -0700826 }
Chien-Yu Chene02e9322016-04-11 16:59:33 -0700827
Igor Murashkin2fba5842013-04-22 14:03:54 -0700828 return res;
829}
830
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700831status_t Camera3Stream::getInputBufferProducer(sp<IGraphicBufferProducer> *producer) {
832 ATRACE_CALL();
833 Mutex::Autolock l(mLock);
834
835 return getInputBufferProducerLocked(producer);
836}
837
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800838void Camera3Stream::fireBufferRequestForFrameNumber(uint64_t frameNumber,
839 const CameraMetadata& settings) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000840 ATRACE_CALL();
841 Mutex::Autolock l(mLock);
842
843 for (auto &it : mBufferListenerList) {
844 sp<Camera3StreamBufferListener> listener = it.promote();
845 if (listener.get() != nullptr) {
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800846 listener->onBufferRequestForFrameNumber(frameNumber, getId(), settings);
Emilian Peev538c90e2018-12-17 18:03:19 +0000847 }
848 }
849}
850
Igor Murashkin2fba5842013-04-22 14:03:54 -0700851void Camera3Stream::fireBufferListenersLocked(
Emilian Peevf4816702020-04-03 15:44:51 -0700852 const camera_stream_buffer& buffer, bool acquired, bool output, nsecs_t timestamp,
Emilian Peev538c90e2018-12-17 18:03:19 +0000853 uint64_t frameNumber) {
Igor Murashkin2fba5842013-04-22 14:03:54 -0700854 List<wp<Camera3StreamBufferListener> >::iterator it, end;
855
856 // TODO: finish implementing
857
858 Camera3StreamBufferListener::BufferInfo info =
859 Camera3StreamBufferListener::BufferInfo();
860 info.mOutput = output;
Emilian Peevf4816702020-04-03 15:44:51 -0700861 info.mError = (buffer.status == CAMERA_BUFFER_STATUS_ERROR);
Emilian Peev538c90e2018-12-17 18:03:19 +0000862 info.mFrameNumber = frameNumber;
863 info.mTimestamp = timestamp;
Shuzhen Wange8675782019-12-05 09:12:14 -0800864 info.mStreamId = getId();
865
Igor Murashkin2fba5842013-04-22 14:03:54 -0700866 // TODO: rest of fields
867
868 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
869 it != end;
870 ++it) {
871
872 sp<Camera3StreamBufferListener> listener = it->promote();
873 if (listener != 0) {
874 if (acquired) {
875 listener->onBufferAcquired(info);
876 } else {
877 listener->onBufferReleased(info);
878 }
879 }
880 }
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700881}
882
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800883bool Camera3Stream::hasOutstandingBuffers() const {
884 ATRACE_CALL();
885 Mutex::Autolock l(mLock);
886 return hasOutstandingBuffersLocked();
887}
888
Yin-Chia Yehd5cd5ff2018-10-01 14:43:04 -0700889size_t Camera3Stream::getOutstandingBuffersCount() const {
890 ATRACE_CALL();
891 Mutex::Autolock l(mLock);
892 return getHandoutOutputBufferCountLocked();
893}
894
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -0700895status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) {
896 Mutex::Autolock l(mLock);
897 sp<StatusTracker> oldTracker = mStatusTracker.promote();
898 if (oldTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
899 oldTracker->removeComponent(mStatusId);
900 }
901 mStatusId = StatusTracker::NO_STATUS_ID;
902 mStatusTracker = statusTracker;
903
904 return OK;
905}
906
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800907status_t Camera3Stream::disconnect() {
908 ATRACE_CALL();
909 Mutex::Autolock l(mLock);
Igor Murashkine2172be2013-05-28 15:31:39 -0700910 ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId);
911 status_t res = disconnectLocked();
912
Shuzhen Wang686f6442017-06-20 16:16:04 -0700913 mBufferLimitLatency.log("Stream %d latency histogram for wait on max_buffers", mId);
914 mBufferLimitLatency.reset();
915
Igor Murashkine2172be2013-05-28 15:31:39 -0700916 if (res == -ENOTCONN) {
917 // "Already disconnected" -- not an error
918 return OK;
919 } else {
920 return res;
921 }
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -0800922}
923
Shuzhen Wang686f6442017-06-20 16:16:04 -0700924void Camera3Stream::dump(int fd, const Vector<String16> &args) const
925{
926 (void)args;
927 mBufferLimitLatency.dump(fd,
928 " Latency histogram for wait on max_buffers");
929}
930
Emilian Peevf4816702020-04-03 15:44:51 -0700931status_t Camera3Stream::getBufferLocked(camera_stream_buffer *,
Shuzhen Wangbee0f0a2017-01-24 14:51:37 -0800932 const std::vector<size_t>&) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700933 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
934 return INVALID_OPERATION;
935}
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -0800936
937status_t Camera3Stream::getBuffersLocked(std::vector<OutstandingBuffer>*) {
938 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
939 return INVALID_OPERATION;
940}
941
Emilian Peevf4816702020-04-03 15:44:51 -0700942status_t Camera3Stream::returnBufferLocked(const camera_stream_buffer &,
Shuzhen Wang90708ea2021-11-04 11:40:49 -0700943 nsecs_t, nsecs_t, int32_t, const std::vector<size_t>&) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700944 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
945 return INVALID_OPERATION;
946}
Shuzhen Wang83bff122020-11-20 15:51:39 -0800947status_t Camera3Stream::getInputBufferLocked(camera_stream_buffer *, Size *) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700948 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
949 return INVALID_OPERATION;
950}
951status_t Camera3Stream::returnInputBufferLocked(
Emilian Peevf4816702020-04-03 15:44:51 -0700952 const camera_stream_buffer &) {
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700953 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
954 return INVALID_OPERATION;
955}
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -0800956status_t Camera3Stream::getInputBufferProducerLocked(sp<IGraphicBufferProducer>*) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700957 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
958 return INVALID_OPERATION;
959}
Igor Murashkin5a269fa2013-04-15 14:59:22 -0700960
Igor Murashkin2fba5842013-04-22 14:03:54 -0700961void Camera3Stream::addBufferListener(
962 wp<Camera3StreamBufferListener> listener) {
963 Mutex::Autolock l(mLock);
Zhijun Hef0d962a2014-06-30 10:24:11 -0700964
965 List<wp<Camera3StreamBufferListener> >::iterator it, end;
966 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
967 it != end;
968 ) {
969 if (*it == listener) {
970 ALOGE("%s: Try to add the same listener twice, ignoring...", __FUNCTION__);
971 return;
972 }
973 it++;
974 }
975
Igor Murashkin2fba5842013-04-22 14:03:54 -0700976 mBufferListenerList.push_back(listener);
977}
978
979void Camera3Stream::removeBufferListener(
980 const sp<Camera3StreamBufferListener>& listener) {
981 Mutex::Autolock l(mLock);
982
983 bool erased = true;
984 List<wp<Camera3StreamBufferListener> >::iterator it, end;
985 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
986 it != end;
987 ) {
988
989 if (*it == listener) {
990 it = mBufferListenerList.erase(it);
991 erased = true;
992 } else {
993 ++it;
994 }
995 }
996
997 if (!erased) {
998 ALOGW("%s: Could not find listener to remove, already removed",
999 __FUNCTION__);
1000 }
1001}
1002
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07001003void Camera3Stream::setBufferFreedListener(
Yin-Chia Yehdb1e8642017-07-14 15:19:30 -07001004 wp<Camera3StreamBufferFreedListener> listener) {
Yin-Chia Yehbe83fa72017-03-30 13:35:36 -07001005 Mutex::Autolock l(mLock);
1006 // Only allow set listener during stream configuration because stream is guaranteed to be IDLE
1007 // at this state, so setBufferFreedListener won't collide with onBufferFreed callbacks
1008 if (mState != STATE_IN_CONFIG && mState != STATE_IN_RECONFIG) {
1009 ALOGE("%s: listener must be set during stream configuration!",__FUNCTION__);
1010 return;
1011 }
1012 mBufferFreedListener = listener;
1013}
1014
Yin-Chia Yeh14ef48d2020-02-10 15:06:37 -08001015status_t Camera3Stream::getBuffers(std::vector<OutstandingBuffer>* buffers,
1016 nsecs_t waitBufferTimeout) {
1017 ATRACE_CALL();
1018 Mutex::Autolock l(mLock);
1019 status_t res = OK;
1020
1021 if (buffers == nullptr) {
1022 ALOGI("%s: buffers must not be null!", __FUNCTION__);
1023 return BAD_VALUE;
1024 }
1025
1026 size_t numBuffersRequested = buffers->size();
1027 if (numBuffersRequested == 0) {
1028 ALOGE("%s: 0 buffers are requested!", __FUNCTION__);
1029 return BAD_VALUE;
1030 }
1031
1032 // This function should be only called when the stream is configured already.
1033 if (mState != STATE_CONFIGURED) {
1034 ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
1035 __FUNCTION__, mId, mState);
1036 if (mState == STATE_ABANDONED) {
1037 return DEAD_OBJECT;
1038 } else {
1039 return INVALID_OPERATION;
1040 }
1041 }
1042
1043 size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked();
1044 // Wait for new buffer returned back if we are running into the limit.
1045 while (numOutstandingBuffers + numBuffersRequested > camera_stream::max_buffers) {
1046 ALOGV("%s: Already dequeued %zu output buffers and requesting %zu (max is %d), waiting.",
1047 __FUNCTION__, numOutstandingBuffers, numBuffersRequested,
1048 camera_stream::max_buffers);
1049 nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
1050 if (waitBufferTimeout < kWaitForBufferDuration) {
1051 waitBufferTimeout = kWaitForBufferDuration;
1052 }
1053 res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
1054 nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
1055 mBufferLimitLatency.add(waitStart, waitEnd);
1056 if (res != OK) {
1057 if (res == TIMED_OUT) {
1058 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
1059 __FUNCTION__, waitBufferTimeout / 1000000LL,
1060 camera_stream::max_buffers);
1061 }
1062 return res;
1063 }
1064 size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked();
1065 if (updatedNumOutstandingBuffers >= numOutstandingBuffers) {
1066 ALOGE("%s: outsanding buffer count goes from %zu to %zu, "
1067 "getBuffer(s) call must not run in parallel!", __FUNCTION__,
1068 numOutstandingBuffers, updatedNumOutstandingBuffers);
1069 return INVALID_OPERATION;
1070 }
1071 numOutstandingBuffers = updatedNumOutstandingBuffers;
1072 }
1073
1074 res = getBuffersLocked(buffers);
1075 if (res == OK) {
1076 for (auto& outstandingBuffer : *buffers) {
1077 camera_stream_buffer* buffer = outstandingBuffer.outBuffer;
1078 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
1079 if (buffer->buffer) {
1080 Mutex::Autolock l(mOutstandingBuffersLock);
1081 mOutstandingBuffers.push_back(*buffer->buffer);
1082 }
1083 }
1084 }
1085
1086 return res;
1087}
1088
Emilian Peev2295df72021-11-12 18:14:10 -08001089void Camera3Stream::queueHDRMetadata(buffer_handle_t buffer, sp<ANativeWindow>& anw,
1090 int dynamicRangeProfile) {
1091 auto& mapper = GraphicBufferMapper::get();
1092 switch (dynamicRangeProfile) {
1093 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10: {
1094 std::optional<ui::Smpte2086> smpte2086;
1095 auto res = mapper.getSmpte2086(buffer, &smpte2086);
1096 if ((res == OK) && smpte2086.has_value()) {
1097 const auto& metaValue = smpte2086.value();
1098 android_smpte2086_metadata meta = {
1099 .displayPrimaryRed.x = metaValue.primaryRed.x,
1100 .displayPrimaryRed.y = metaValue.primaryRed.y,
1101 .displayPrimaryGreen.x = metaValue.primaryGreen.x,
1102 .displayPrimaryGreen.y = metaValue.primaryGreen.y,
1103 .displayPrimaryBlue.x = metaValue.primaryBlue.x,
1104 .displayPrimaryBlue.y = metaValue.primaryBlue.y,
1105 .whitePoint.x = metaValue.whitePoint.x,
1106 .whitePoint.y = metaValue.whitePoint.y,
1107 .maxLuminance = metaValue.maxLuminance,
1108 .minLuminance = metaValue.minLuminance};
1109 native_window_set_buffers_smpte2086_metadata(anw.get(), &meta);
1110 } else {
1111 ALOGE("%s Couldn't retrieve Smpte2086 metadata %s (%d)",
1112 __FUNCTION__, strerror(-res), res);
1113 }
1114 break;
1115 }
1116 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS: {
1117 std::optional<std::vector<uint8_t>> smpte2094_40;
1118 auto res = mapper.getSmpte2094_40(buffer, &smpte2094_40);
1119 if ((res == OK) && smpte2094_40.has_value()) {
1120 native_window_set_buffers_hdr10_plus_metadata(anw.get(),
1121 smpte2094_40.value().size(), smpte2094_40.value().data());
1122 } else {
1123 ALOGE("%s Couldn't retrieve Smpte2094_40 metadata %s (%d)",
1124 __FUNCTION__, strerror(-res), res);
1125 }
1126 break;
1127 }
1128 default:
1129 // No-op
1130 break;
1131 }
1132}
1133
1134
Eino-Ville Talvalafd58f1a2013-03-06 16:20:06 -08001135}; // namespace camera3
1136
1137}; // namespace android