1 /*
2 * Copyright (C) 2013-2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <vector>
18 #include "system/window.h"
19 #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>
25 #include <camera/StringUtils.h>
26 #include "device3/Camera3Stream.h"
27 #include "device3/StatusTracker.h"
28 #include "utils/TraceHFR.h"
29 #include "ui/GraphicBufferMapper.h"
30
31 #include <cutils/properties.h>
32 #include <com_android_internal_camera_flags.h>
33
34 namespace flags = com::android::internal::camera::flags;
35
36 namespace android {
37
38 namespace camera3 {
39
~Camera3Stream()40 Camera3Stream::~Camera3Stream() {
41 sp<StatusTracker> statusTracker = mStatusTracker.promote();
42 if (statusTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
43 statusTracker->removeComponent(mStatusId);
44 }
45 }
46
cast(camera_stream * stream)47 Camera3Stream* Camera3Stream::cast(camera_stream *stream) {
48 return static_cast<Camera3Stream*>(stream);
49 }
50
cast(const camera_stream * stream)51 const Camera3Stream* Camera3Stream::cast(const camera_stream *stream) {
52 return static_cast<const Camera3Stream*>(stream);
53 }
54
Camera3Stream(int id,camera_stream_type type,uint32_t width,uint32_t height,size_t maxSize,int format,android_dataspace dataSpace,camera_stream_rotation_t rotation,const std::string & physicalCameraId,const std::unordered_set<int32_t> & sensorPixelModesUsed,int setId,bool isMultiResolution,int64_t dynamicRangeProfile,int64_t streamUseCase,bool deviceTimeBaseIsRealtime,int timestampBase,int32_t colorSpace)55 Camera3Stream::Camera3Stream(int id,
56 camera_stream_type type,
57 uint32_t width, uint32_t height, size_t maxSize, int format,
58 android_dataspace dataSpace, camera_stream_rotation_t rotation,
59 const std::string& physicalCameraId,
60 const std::unordered_set<int32_t> &sensorPixelModesUsed,
61 int setId, bool isMultiResolution, int64_t dynamicRangeProfile,
62 int64_t streamUseCase, bool deviceTimeBaseIsRealtime, int timestampBase,
63 int32_t colorSpace) :
64 camera_stream(),
65 mId(id),
66 mSetId(setId),
67 mName(fmt::sprintf("Camera3Stream[%d]", id)),
68 mMaxSize(maxSize),
69 mState(STATE_CONSTRUCTED),
70 mStatusId(StatusTracker::NO_STATUS_ID),
71 mStreamUnpreparable(true),
72 mUsage(0),
73 mOldUsage(0),
74 mOldMaxBuffers(0),
75 mOldFormat(-1),
76 mOldDataSpace(HAL_DATASPACE_UNKNOWN),
77 mPrepared(false),
78 mPrepareBlockRequest(true),
79 mPreparedBufferIdx(0),
80 mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX),
81 mBufferLimitLatency(kBufferLimitLatencyBinSize),
82 mFormatOverridden(false),
83 mOriginalFormat(format),
84 mDataSpaceOverridden(false),
85 mOriginalDataSpace(dataSpace),
86 mPhysicalCameraId(physicalCameraId),
87 mLastTimestamp(0),
88 mIsMultiResolution(isMultiResolution),
89 mDeviceTimeBaseIsRealtime(deviceTimeBaseIsRealtime),
90 mTimestampBase(timestampBase) {
91
92 camera_stream::stream_type = type;
93 camera_stream::width = width;
94 camera_stream::height = height;
95 camera_stream::format = format;
96 camera_stream::data_space = dataSpace;
97 camera_stream::rotation = rotation;
98 camera_stream::max_buffers = 0;
99 camera_stream::physical_camera_id = mPhysicalCameraId;
100 camera_stream::sensor_pixel_modes_used = sensorPixelModesUsed;
101 camera_stream::dynamic_range_profile = dynamicRangeProfile;
102 camera_stream::use_case = streamUseCase;
103 camera_stream::color_space = colorSpace;
104
105 if ((format == HAL_PIXEL_FORMAT_BLOB || format == HAL_PIXEL_FORMAT_RAW_OPAQUE) &&
106 maxSize == 0) {
107 ALOGE("%s: BLOB or RAW_OPAQUE format with size == 0", __FUNCTION__);
108 mState = STATE_ERROR;
109 }
110 }
111
getId() const112 int Camera3Stream::getId() const {
113 return mId;
114 }
115
getStreamSetId() const116 int Camera3Stream::getStreamSetId() const {
117 return mSetId;
118 }
119
getHalStreamGroupId() const120 int Camera3Stream::getHalStreamGroupId() const {
121 return mIsMultiResolution ? mSetId : -1;
122 }
123
isMultiResolution() const124 bool Camera3Stream::isMultiResolution() const {
125 return mIsMultiResolution;
126 }
127
getWidth() const128 uint32_t Camera3Stream::getWidth() const {
129 return camera_stream::width;
130 }
131
getHeight() const132 uint32_t Camera3Stream::getHeight() const {
133 return camera_stream::height;
134 }
135
getFormat() const136 int Camera3Stream::getFormat() const {
137 return camera_stream::format;
138 }
139
getDataSpace() const140 android_dataspace Camera3Stream::getDataSpace() const {
141 return camera_stream::data_space;
142 }
143
getColorSpace() const144 int32_t Camera3Stream::getColorSpace() const {
145 return camera_stream::color_space;
146 }
147
getUsage() const148 uint64_t Camera3Stream::getUsage() const {
149 return mUsage;
150 }
151
setUsage(uint64_t usage)152 void Camera3Stream::setUsage(uint64_t usage) {
153 mUsage = usage;
154 }
155
setFormatOverride(bool formatOverridden)156 void Camera3Stream::setFormatOverride(bool formatOverridden) {
157 mFormatOverridden = formatOverridden;
158 }
159
isFormatOverridden() const160 bool Camera3Stream::isFormatOverridden() const {
161 return mFormatOverridden;
162 }
163
getOriginalFormat() const164 int Camera3Stream::getOriginalFormat() const {
165 return mOriginalFormat;
166 }
167
getDynamicRangeProfile() const168 int64_t Camera3Stream::getDynamicRangeProfile() const {
169 return camera_stream::dynamic_range_profile;
170 }
171
setDataSpaceOverride(bool dataSpaceOverridden)172 void Camera3Stream::setDataSpaceOverride(bool dataSpaceOverridden) {
173 mDataSpaceOverridden = dataSpaceOverridden;
174 }
175
isDataSpaceOverridden() const176 bool Camera3Stream::isDataSpaceOverridden() const {
177 return mDataSpaceOverridden;
178 }
179
getOriginalDataSpace() const180 android_dataspace Camera3Stream::getOriginalDataSpace() const {
181 return mOriginalDataSpace;
182 }
183
physicalCameraId() const184 const std::string& Camera3Stream::physicalCameraId() const {
185 return mPhysicalCameraId;
186 }
187
getMaxHalBuffers() const188 int Camera3Stream::getMaxHalBuffers() const {
189 return camera_stream::max_buffers;
190 }
191
getStreamUseCase() const192 int64_t Camera3Stream::getStreamUseCase() const {
193 return camera_stream::use_case;
194 }
195
getTimestampBase() const196 int Camera3Stream::getTimestampBase() const {
197 return mTimestampBase;
198 }
199
isDeviceTimeBaseRealtime() const200 bool Camera3Stream::isDeviceTimeBaseRealtime() const {
201 return mDeviceTimeBaseIsRealtime;
202 }
203
setOfflineProcessingSupport(bool support)204 void Camera3Stream::setOfflineProcessingSupport(bool support) {
205 mSupportOfflineProcessing = support;
206 }
207
getOfflineProcessingSupport() const208 bool Camera3Stream::getOfflineProcessingSupport() const {
209 return mSupportOfflineProcessing;
210 }
211
forceToIdle()212 status_t Camera3Stream::forceToIdle() {
213 ATRACE_CALL();
214 Mutex::Autolock l(mLock);
215 status_t res;
216
217 switch (mState) {
218 case STATE_ERROR:
219 case STATE_CONSTRUCTED:
220 case STATE_IN_CONFIG:
221 case STATE_PREPARING:
222 case STATE_IN_RECONFIG:
223 ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
224 res = NO_INIT;
225 break;
226 case STATE_CONFIGURED:
227 if (hasOutstandingBuffersLocked()) {
228 sp<StatusTracker> statusTracker = mStatusTracker.promote();
229 if (statusTracker != 0) {
230 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
231 }
232 }
233
234 mState = STATE_IN_IDLE;
235 res = OK;
236
237 break;
238 default:
239 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
240 res = NO_INIT;
241 }
242
243 return res;
244 }
245
restoreConfiguredState()246 status_t Camera3Stream::restoreConfiguredState() {
247 ATRACE_CALL();
248 Mutex::Autolock l(mLock);
249 status_t res;
250
251 switch (mState) {
252 case STATE_ERROR:
253 case STATE_CONSTRUCTED:
254 case STATE_IN_CONFIG:
255 case STATE_PREPARING:
256 case STATE_IN_RECONFIG:
257 case STATE_CONFIGURED:
258 ALOGE("%s: Invalid state: %d", __FUNCTION__, mState);
259 res = NO_INIT;
260 break;
261 case STATE_IN_IDLE:
262 if (hasOutstandingBuffersLocked()) {
263 sp<StatusTracker> statusTracker = mStatusTracker.promote();
264 if (statusTracker != 0) {
265 statusTracker->markComponentActive(mStatusId);
266 }
267 }
268
269 mState = STATE_CONFIGURED;
270 res = OK;
271
272 break;
273 default:
274 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
275 res = NO_INIT;
276 }
277
278 return res;
279 }
280
startConfiguration()281 camera_stream* Camera3Stream::startConfiguration() {
282 ATRACE_CALL();
283 Mutex::Autolock l(mLock);
284 status_t res;
285
286 switch (mState) {
287 case STATE_ERROR:
288 ALOGE("%s: In error state", __FUNCTION__);
289 return NULL;
290 case STATE_CONSTRUCTED:
291 case STATE_IN_IDLE:
292 // OK
293 break;
294 case STATE_IN_CONFIG:
295 case STATE_IN_RECONFIG:
296 // Can start config again with no trouble; but don't redo
297 // mOldUsage/mOldMaxBuffers
298 return this;
299 case STATE_CONFIGURED:
300 if (hasOutstandingBuffersLocked()) {
301 ALOGE("%s: Cannot configure stream; has outstanding buffers",
302 __FUNCTION__);
303 return NULL;
304 }
305 break;
306 default:
307 ALOGE("%s: Unknown state %d", __FUNCTION__, mState);
308 return NULL;
309 }
310
311 mOldUsage = mUsage;
312 mOldMaxBuffers = camera_stream::max_buffers;
313 mOldFormat = camera_stream::format;
314 mOldDataSpace = camera_stream::data_space;
315
316 res = getEndpointUsage(&mUsage);
317 if (res != OK) {
318 ALOGE("%s: Cannot query consumer endpoint usage!",
319 __FUNCTION__);
320 return NULL;
321 }
322
323 if (mState == STATE_IN_IDLE) {
324 // Skip configuration.
325 return this;
326 }
327
328 // Stop tracking if currently doing so
329 if (mStatusId != StatusTracker::NO_STATUS_ID) {
330 sp<StatusTracker> statusTracker = mStatusTracker.promote();
331 if (statusTracker != 0) {
332 statusTracker->removeComponent(mStatusId);
333 }
334 mStatusId = StatusTracker::NO_STATUS_ID;
335 }
336
337 if (mState == STATE_CONSTRUCTED) {
338 mState = STATE_IN_CONFIG;
339 } else { // mState == STATE_CONFIGURED
340 LOG_ALWAYS_FATAL_IF(mState != STATE_CONFIGURED, "Invalid state: 0x%x", mState);
341 mState = STATE_IN_RECONFIG;
342 }
343
344 return this;
345 }
346
isConfiguring() const347 bool Camera3Stream::isConfiguring() const {
348 Mutex::Autolock l(mLock);
349 return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
350 }
351
finishConfiguration(bool * streamReconfigured)352 status_t Camera3Stream::finishConfiguration(/*out*/bool* streamReconfigured) {
353 ATRACE_CALL();
354 if (streamReconfigured != nullptr) {
355 *streamReconfigured = false;
356 }
357 Mutex::Autolock l(mLock);
358 switch (mState) {
359 case STATE_ERROR:
360 ALOGE("%s: In error state", __FUNCTION__);
361 return INVALID_OPERATION;
362 case STATE_IN_CONFIG:
363 case STATE_IN_RECONFIG:
364 // OK
365 break;
366 case STATE_CONSTRUCTED:
367 case STATE_CONFIGURED:
368 ALOGE("%s: Cannot finish configuration that hasn't been started",
369 __FUNCTION__);
370 return INVALID_OPERATION;
371 case STATE_IN_IDLE:
372 //Skip configuration in this state
373 return OK;
374 default:
375 ALOGE("%s: Unknown state", __FUNCTION__);
376 return INVALID_OPERATION;
377 }
378
379 // Register for idle tracking
380 sp<StatusTracker> statusTracker = mStatusTracker.promote();
381 if (statusTracker != 0 && mStatusId == StatusTracker::NO_STATUS_ID) {
382 std::string name = std::string("Stream ") + std::to_string(mId);
383 mStatusId = statusTracker->addComponent(name);
384 }
385
386 // Check if the stream configuration is unchanged, and skip reallocation if
387 // so.
388 if (mState == STATE_IN_RECONFIG &&
389 mOldUsage == mUsage &&
390 mOldMaxBuffers == camera_stream::max_buffers &&
391 mOldDataSpace == camera_stream::data_space &&
392 mOldFormat == camera_stream::format) {
393 mState = STATE_CONFIGURED;
394 if (flags::enable_stream_reconfiguration_for_unchanged_streams()
395 && streamReconfigured != nullptr) {
396 *streamReconfigured = true;
397 }
398 return OK;
399 }
400
401 // Reset prepared state, since buffer config has changed, and existing
402 // allocations are no longer valid
403 mPrepared = false;
404 mPrepareBlockRequest = true;
405 mStreamUnpreparable = false;
406
407 bool reconfiguring = (mState == STATE_IN_RECONFIG);
408 status_t res;
409 res = configureQueueLocked();
410 // configureQueueLocked could return error in case of abandoned surface.
411 // Treat as non-fatal error.
412 if (res == NO_INIT || res == DEAD_OBJECT) {
413 ALOGE("%s: Unable to configure stream %d queue (non-fatal): %s (%d)",
414 __FUNCTION__, mId, strerror(-res), res);
415 mState = STATE_ABANDONED;
416 return res;
417 } else if (res != OK) {
418 ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
419 __FUNCTION__, mId, strerror(-res), res);
420 mState = STATE_ERROR;
421 return res;
422 }
423
424 if (reconfiguring && streamReconfigured != nullptr) {
425 *streamReconfigured = true;
426 }
427 mState = STATE_CONFIGURED;
428
429 return res;
430 }
431
cancelConfiguration()432 status_t Camera3Stream::cancelConfiguration() {
433 ATRACE_CALL();
434 Mutex::Autolock l(mLock);
435 switch (mState) {
436 case STATE_ERROR:
437 ALOGE("%s: In error state", __FUNCTION__);
438 return INVALID_OPERATION;
439 case STATE_IN_CONFIG:
440 case STATE_IN_RECONFIG:
441 case STATE_IN_IDLE:
442 // OK
443 break;
444 case STATE_CONSTRUCTED:
445 case STATE_CONFIGURED:
446 ALOGE("%s: Cannot cancel configuration that hasn't been started",
447 __FUNCTION__);
448 return INVALID_OPERATION;
449 default:
450 ALOGE("%s: Unknown state", __FUNCTION__);
451 return INVALID_OPERATION;
452 }
453
454 mUsage = mOldUsage;
455 camera_stream::max_buffers = mOldMaxBuffers;
456
457 mState = ((mState == STATE_IN_RECONFIG) || (mState == STATE_IN_IDLE)) ? STATE_CONFIGURED :
458 STATE_CONSTRUCTED;
459
460 return OK;
461 }
462
isUnpreparable()463 bool Camera3Stream::isUnpreparable() {
464 ATRACE_CALL();
465
466 Mutex::Autolock l(mLock);
467 return mStreamUnpreparable;
468 }
469
markUnpreparable()470 void Camera3Stream::markUnpreparable() {
471 ATRACE_CALL();
472
473 Mutex::Autolock l(mLock);
474 mStreamUnpreparable = true;
475 }
476
startPrepare(int maxCount,bool blockRequest)477 status_t Camera3Stream::startPrepare(int maxCount, bool blockRequest) {
478 ATRACE_CALL();
479
480 Mutex::Autolock l(mLock);
481
482 if (maxCount < 0) {
483 ALOGE("%s: Stream %d: Can't prepare stream if max buffer count (%d) is < 0",
484 __FUNCTION__, mId, maxCount);
485 return BAD_VALUE;
486 }
487
488 // This function should be only called when the stream is configured already.
489 if (mState != STATE_CONFIGURED) {
490 ALOGE("%s: Stream %d: Can't prepare stream if stream is not in CONFIGURED "
491 "state %d", __FUNCTION__, mId, mState);
492 return INVALID_OPERATION;
493 }
494
495 // This function can't be called if the stream has already received filled
496 // buffers
497 if (mStreamUnpreparable) {
498 ALOGE("%s: Stream %d: Can't prepare stream that's already in use",
499 __FUNCTION__, mId);
500 return INVALID_OPERATION;
501 }
502
503 if (getHandoutOutputBufferCountLocked() > 0) {
504 ALOGE("%s: Stream %d: Can't prepare stream that has outstanding buffers",
505 __FUNCTION__, mId);
506 return INVALID_OPERATION;
507 }
508
509 size_t pipelineMax = getBufferCountLocked();
510 size_t clampedCount = (pipelineMax < static_cast<size_t>(maxCount)) ?
511 pipelineMax : static_cast<size_t>(maxCount);
512 size_t bufferCount = (maxCount == Camera3StreamInterface::ALLOCATE_PIPELINE_MAX) ?
513 pipelineMax : clampedCount;
514
515 mPrepared = bufferCount <= mLastMaxCount;
516 mPrepareBlockRequest = blockRequest;
517
518 if (mPrepared) return OK;
519
520 mLastMaxCount = bufferCount;
521
522 mPreparedBuffers.insertAt(camera_stream_buffer_t(), /*index*/0, bufferCount);
523 mPreparedBufferIdx = 0;
524
525 mState = STATE_PREPARING;
526
527 return NOT_ENOUGH_DATA;
528 }
529
isBlockedByPrepare() const530 bool Camera3Stream::isBlockedByPrepare() const {
531 Mutex::Autolock l(mLock);
532 return mState == STATE_PREPARING && mPrepareBlockRequest;
533 }
534
isAbandoned() const535 bool Camera3Stream::isAbandoned() const {
536 Mutex::Autolock l(mLock);
537 return mState == STATE_ABANDONED;
538 }
539
prepareNextBuffer()540 status_t Camera3Stream::prepareNextBuffer() {
541 ATRACE_CALL();
542
543 Mutex::Autolock l(mLock);
544 status_t res = OK;
545
546 // This function should be only called when the stream is preparing
547 if (mState != STATE_PREPARING) {
548 ALOGE("%s: Stream %d: Can't prepare buffer if stream is not in PREPARING "
549 "state %d", __FUNCTION__, mId, mState);
550 return INVALID_OPERATION;
551 }
552
553 // Get next buffer - this may allocate, and take a while for large buffers
554 res = getBufferLocked( &mPreparedBuffers.editItemAt(mPreparedBufferIdx) );
555 if (res != OK) {
556 ALOGE("%s: Stream %d: Unable to allocate buffer %zu during preparation",
557 __FUNCTION__, mId, mPreparedBufferIdx);
558 return NO_INIT;
559 }
560
561 mPreparedBufferIdx++;
562
563 // Check if we still have buffers left to allocate
564 if (mPreparedBufferIdx < mPreparedBuffers.size()) {
565 return NOT_ENOUGH_DATA;
566 }
567
568 // Done with prepare - mark stream as such, and return all buffers
569 // via cancelPrepare
570 mPrepared = true;
571
572 return cancelPrepareLocked();
573 }
574
cancelPrepare()575 status_t Camera3Stream::cancelPrepare() {
576 ATRACE_CALL();
577
578 Mutex::Autolock l(mLock);
579
580 return cancelPrepareLocked();
581 }
582
cancelPrepareLocked()583 status_t Camera3Stream::cancelPrepareLocked() {
584 status_t res = OK;
585
586 // This function should be only called when the stream is mid-preparing.
587 if (mState != STATE_PREPARING) {
588 ALOGE("%s: Stream %d: Can't cancel prepare stream if stream is not in "
589 "PREPARING state %d", __FUNCTION__, mId, mState);
590 return INVALID_OPERATION;
591 }
592
593 // Return all valid buffers to stream, in ERROR state to indicate
594 // they weren't filled.
595 for (size_t i = 0; i < mPreparedBufferIdx; i++) {
596 mPreparedBuffers.editItemAt(i).release_fence = -1;
597 mPreparedBuffers.editItemAt(i).status = CAMERA_BUFFER_STATUS_ERROR;
598 returnBufferLocked(mPreparedBuffers[i], /*timestamp*/0, /*readoutTimestamp*/0,
599 /*transform*/ -1);
600 }
601 mPreparedBuffers.clear();
602 mPreparedBufferIdx = 0;
603
604 mState = STATE_CONFIGURED;
605
606 return res;
607 }
608
tearDown()609 status_t Camera3Stream::tearDown() {
610 ATRACE_CALL();
611 Mutex::Autolock l(mLock);
612
613 status_t res = OK;
614
615 // This function should be only called when the stream is configured.
616 if (mState != STATE_CONFIGURED) {
617 ALOGE("%s: Stream %d: Can't tear down stream if stream is not in "
618 "CONFIGURED state %d", __FUNCTION__, mId, mState);
619 return INVALID_OPERATION;
620 }
621
622 // If any buffers have been handed to the HAL, the stream cannot be torn down.
623 if (getHandoutOutputBufferCountLocked() > 0) {
624 ALOGE("%s: Stream %d: Can't tear down a stream that has outstanding buffers",
625 __FUNCTION__, mId);
626 return INVALID_OPERATION;
627 }
628
629 // Free buffers by disconnecting and then reconnecting to the buffer queue
630 // Only unused buffers will be dropped immediately; buffers that have been filled
631 // and are waiting to be acquired by the consumer and buffers that are currently
632 // acquired will be freed once they are released by the consumer.
633
634 res = disconnectLocked();
635 if (res != OK) {
636 if (res == -ENOTCONN) {
637 // queue has been disconnected, nothing left to do, so exit with success
638 return OK;
639 }
640 ALOGE("%s: Stream %d: Unable to disconnect to tear down buffers: %s (%d)",
641 __FUNCTION__, mId, strerror(-res), res);
642 return res;
643 }
644
645 mState = STATE_IN_CONFIG;
646
647 res = configureQueueLocked();
648 if (res != OK) {
649 ALOGE("%s: Unable to configure stream %d queue: %s (%d)",
650 __FUNCTION__, mId, strerror(-res), res);
651 mState = STATE_ERROR;
652 return res;
653 }
654
655 // Reset prepared state, since we've reconnected to the queue and can prepare again.
656 mPrepared = false;
657 mStreamUnpreparable = false;
658
659 mState = STATE_CONFIGURED;
660
661 return OK;
662 }
663
getBuffer(camera_stream_buffer * buffer,nsecs_t waitBufferTimeout,const std::vector<size_t> & surface_ids)664 status_t Camera3Stream::getBuffer(camera_stream_buffer *buffer,
665 nsecs_t waitBufferTimeout,
666 const std::vector<size_t>& surface_ids) {
667 ATRACE_HFR_CALL();
668 Mutex::Autolock l(mLock);
669 status_t res = OK;
670
671 // This function should be only called when the stream is configured already.
672 if (mState != STATE_CONFIGURED) {
673 ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
674 __FUNCTION__, mId, mState);
675 if (mState == STATE_ABANDONED) {
676 return DEAD_OBJECT;
677 } else {
678 return INVALID_OPERATION;
679 }
680 }
681
682 // Wait for new buffer returned back if we are running into the limit. There
683 // are 2 limits:
684 // 1. The number of HAL buffers is greater than max_buffers
685 // 2. The number of HAL buffers + cached buffers is greater than max_buffers
686 // + maxCachedBuffers
687 size_t numOutstandingBuffers = getHandoutOutputBufferCountLocked();
688 size_t numCachedBuffers = getCachedOutputBufferCountLocked();
689 size_t maxNumCachedBuffers = getMaxCachedOutputBuffersLocked();
690 while (numOutstandingBuffers == camera_stream::max_buffers ||
691 numOutstandingBuffers + numCachedBuffers ==
692 camera_stream::max_buffers + maxNumCachedBuffers) {
693 ALOGV("%s: Already dequeued max output buffers (%d(+%zu)), wait for next returned one.",
694 __FUNCTION__, camera_stream::max_buffers, maxNumCachedBuffers);
695 nsecs_t waitStart = systemTime(SYSTEM_TIME_MONOTONIC);
696 if (waitBufferTimeout < kWaitForBufferDuration) {
697 waitBufferTimeout = kWaitForBufferDuration;
698 }
699 res = mOutputBufferReturnedSignal.waitRelative(mLock, waitBufferTimeout);
700 nsecs_t waitEnd = systemTime(SYSTEM_TIME_MONOTONIC);
701 mBufferLimitLatency.add(waitStart, waitEnd);
702 if (res != OK) {
703 if (res == TIMED_OUT) {
704 ALOGE("%s: wait for output buffer return timed out after %lldms (max_buffers %d)",
705 __FUNCTION__, waitBufferTimeout / 1000000LL,
706 camera_stream::max_buffers);
707 }
708 return res;
709 }
710
711 size_t updatedNumOutstandingBuffers = getHandoutOutputBufferCountLocked();
712 size_t updatedNumCachedBuffers = getCachedOutputBufferCountLocked();
713 if (updatedNumOutstandingBuffers >= numOutstandingBuffers &&
714 updatedNumCachedBuffers == numCachedBuffers) {
715 ALOGE("%s: outstanding buffer count goes from %zu to %zu, "
716 "getBuffer(s) call must not run in parallel!", __FUNCTION__,
717 numOutstandingBuffers, updatedNumOutstandingBuffers);
718 return INVALID_OPERATION;
719 }
720 numOutstandingBuffers = updatedNumOutstandingBuffers;
721 numCachedBuffers = updatedNumCachedBuffers;
722 }
723
724 res = getBufferLocked(buffer, surface_ids);
725 if (res == OK) {
726 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
727 if (buffer->buffer) {
728 Mutex::Autolock l(mOutstandingBuffersLock);
729 mOutstandingBuffers.push_back(*buffer->buffer);
730 }
731 }
732
733 return res;
734 }
735
isOutstandingBuffer(const camera_stream_buffer & buffer) const736 bool Camera3Stream::isOutstandingBuffer(const camera_stream_buffer &buffer) const{
737 if (buffer.buffer == nullptr) {
738 return false;
739 }
740
741 Mutex::Autolock l(mOutstandingBuffersLock);
742
743 for (auto b : mOutstandingBuffers) {
744 if (b == *buffer.buffer) {
745 return true;
746 }
747 }
748 return false;
749 }
750
removeOutstandingBuffer(const camera_stream_buffer & buffer)751 void Camera3Stream::removeOutstandingBuffer(const camera_stream_buffer &buffer) {
752 if (buffer.buffer == nullptr) {
753 return;
754 }
755
756 Mutex::Autolock l(mOutstandingBuffersLock);
757
758 for (auto b = mOutstandingBuffers.begin(); b != mOutstandingBuffers.end(); b++) {
759 if (*b == *buffer.buffer) {
760 mOutstandingBuffers.erase(b);
761 return;
762 }
763 }
764 }
765
returnBuffer(const camera_stream_buffer & buffer,nsecs_t timestamp,nsecs_t readoutTimestamp,bool timestampIncreasing,const std::vector<size_t> & surface_ids,uint64_t frameNumber,int32_t transform)766 status_t Camera3Stream::returnBuffer(const camera_stream_buffer &buffer,
767 nsecs_t timestamp, nsecs_t readoutTimestamp, bool timestampIncreasing,
768 const std::vector<size_t>& surface_ids, uint64_t frameNumber, int32_t transform) {
769 ATRACE_HFR_CALL();
770 Mutex::Autolock l(mLock);
771
772 // Check if this buffer is outstanding.
773 if (!isOutstandingBuffer(buffer)) {
774 ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
775 return BAD_VALUE;
776 }
777
778 removeOutstandingBuffer(buffer);
779
780 // Buffer status may be changed, so make a copy of the stream_buffer struct.
781 camera_stream_buffer b = buffer;
782 if (timestampIncreasing && timestamp != 0 && timestamp <= mLastTimestamp
783 && b.status != CAMERA_BUFFER_STATUS_ERROR) {
784 ALOGE("%s: Stream %d: timestamp %" PRId64 " is not increasing. Prev timestamp %" PRId64,
785 __FUNCTION__, mId, timestamp, mLastTimestamp);
786 b.status = CAMERA_BUFFER_STATUS_ERROR;
787 }
788 mLastTimestamp = timestamp;
789
790 /**
791 * TODO: Check that the state is valid first.
792 *
793 * <HAL3.2 IN_CONFIG and IN_RECONFIG in addition to CONFIGURED.
794 * >= HAL3.2 CONFIGURED only
795 *
796 * Do this for getBuffer as well.
797 */
798 status_t res = returnBufferLocked(b, timestamp, readoutTimestamp, transform, surface_ids);
799 if (res == OK) {
800 fireBufferListenersLocked(b, /*acquired*/false, /*output*/true, timestamp, frameNumber);
801 }
802
803 // Even if returning the buffer failed, we still want to signal whoever is waiting for the
804 // buffer to be returned.
805 mOutputBufferReturnedSignal.signal();
806
807 return res;
808 }
809
getInputBuffer(camera_stream_buffer * buffer,Size * size,bool respectHalLimit)810 status_t Camera3Stream::getInputBuffer(camera_stream_buffer *buffer,
811 Size* size, bool respectHalLimit) {
812 ATRACE_CALL();
813 Mutex::Autolock l(mLock);
814 status_t res = OK;
815
816 if (size == nullptr) {
817 ALOGE("%s: size must not be null", __FUNCTION__);
818 return BAD_VALUE;
819 }
820 // This function should be only called when the stream is configured already.
821 if (mState != STATE_CONFIGURED) {
822 ALOGE("%s: Stream %d: Can't get input buffers if stream is not in CONFIGURED state %d",
823 __FUNCTION__, mId, mState);
824 return INVALID_OPERATION;
825 }
826
827 // Wait for new buffer returned back if we are running into the limit.
828 if (getHandoutInputBufferCountLocked() == camera_stream::max_buffers && respectHalLimit) {
829 ALOGV("%s: Already dequeued max input buffers (%d), wait for next returned one.",
830 __FUNCTION__, camera_stream::max_buffers);
831 res = mInputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
832 if (res != OK) {
833 if (res == TIMED_OUT) {
834 ALOGE("%s: wait for input buffer return timed out after %lldms", __FUNCTION__,
835 kWaitForBufferDuration / 1000000LL);
836 }
837 return res;
838 }
839 }
840
841 res = getInputBufferLocked(buffer, size);
842 if (res == OK) {
843 fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
844 if (buffer->buffer) {
845 Mutex::Autolock l(mOutstandingBuffersLock);
846 mOutstandingBuffers.push_back(*buffer->buffer);
847 }
848 }
849
850 return res;
851 }
852
returnInputBuffer(const camera_stream_buffer & buffer)853 status_t Camera3Stream::returnInputBuffer(const camera_stream_buffer &buffer) {
854 ATRACE_CALL();
855 Mutex::Autolock l(mLock);
856
857 // Check if this buffer is outstanding.
858 if (!isOutstandingBuffer(buffer)) {
859 ALOGE("%s: Stream %d: Returning an unknown buffer.", __FUNCTION__, mId);
860 return BAD_VALUE;
861 }
862
863 removeOutstandingBuffer(buffer);
864
865 status_t res = returnInputBufferLocked(buffer);
866 if (res == OK) {
867 fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
868 mInputBufferReturnedSignal.signal();
869 }
870
871 return res;
872 }
873
874 #if WB_CAMERA3_AND_PROCESSORS_WITH_DEPENDENCIES
getInputSurface(sp<Surface> * surface)875 status_t Camera3Stream::getInputSurface(sp<Surface> *surface) {
876 ATRACE_CALL();
877 Mutex::Autolock l(mLock);
878
879 return getInputSurfaceLocked(surface);
880 }
881 #else
getInputBufferProducer(sp<IGraphicBufferProducer> * producer)882 status_t Camera3Stream::getInputBufferProducer(sp<IGraphicBufferProducer> *producer) {
883 ATRACE_CALL();
884 Mutex::Autolock l(mLock);
885
886 return getInputBufferProducerLocked(producer);
887 }
888 #endif
889
fireBufferRequestForFrameNumber(uint64_t frameNumber,const CameraMetadata & settings)890 void Camera3Stream::fireBufferRequestForFrameNumber(uint64_t frameNumber,
891 const CameraMetadata& settings) {
892 ATRACE_CALL();
893 Mutex::Autolock l(mLock);
894
895 for (auto &it : mBufferListenerList) {
896 sp<Camera3StreamBufferListener> listener = it.promote();
897 if (listener.get() != nullptr) {
898 listener->onBufferRequestForFrameNumber(frameNumber, getId(), settings);
899 }
900 }
901 }
902
fireBufferListenersLocked(const camera_stream_buffer & buffer,bool acquired,bool output,nsecs_t timestamp,uint64_t frameNumber)903 void Camera3Stream::fireBufferListenersLocked(
904 const camera_stream_buffer& buffer, bool acquired, bool output, nsecs_t timestamp,
905 uint64_t frameNumber) {
906 List<wp<Camera3StreamBufferListener> >::iterator it, end;
907
908 // TODO: finish implementing
909
910 Camera3StreamBufferListener::BufferInfo info =
911 Camera3StreamBufferListener::BufferInfo();
912 info.mOutput = output;
913 info.mError = (buffer.status == CAMERA_BUFFER_STATUS_ERROR);
914 info.mFrameNumber = frameNumber;
915 info.mTimestamp = timestamp;
916 info.mStreamId = getId();
917
918 // TODO: rest of fields
919
920 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
921 it != end;
922 ++it) {
923
924 sp<Camera3StreamBufferListener> listener = it->promote();
925 if (listener != 0) {
926 if (acquired) {
927 listener->onBufferAcquired(info);
928 } else {
929 listener->onBufferReleased(info);
930 }
931 }
932 }
933 }
934
hasOutstandingBuffers() const935 bool Camera3Stream::hasOutstandingBuffers() const {
936 ATRACE_CALL();
937 Mutex::Autolock l(mLock);
938 return hasOutstandingBuffersLocked();
939 }
940
getOutstandingBuffersCount() const941 size_t Camera3Stream::getOutstandingBuffersCount() const {
942 ATRACE_CALL();
943 Mutex::Autolock l(mLock);
944 return getHandoutOutputBufferCountLocked();
945 }
946
setStatusTracker(sp<StatusTracker> statusTracker)947 status_t Camera3Stream::setStatusTracker(sp<StatusTracker> statusTracker) {
948 Mutex::Autolock l(mLock);
949 sp<StatusTracker> oldTracker = mStatusTracker.promote();
950 if (oldTracker != 0 && mStatusId != StatusTracker::NO_STATUS_ID) {
951 oldTracker->removeComponent(mStatusId);
952 }
953 mStatusId = StatusTracker::NO_STATUS_ID;
954 mStatusTracker = statusTracker;
955
956 return OK;
957 }
958
disconnect()959 status_t Camera3Stream::disconnect() {
960 ATRACE_CALL();
961 Mutex::Autolock l(mLock);
962 ALOGV("%s: Stream %d: Disconnecting...", __FUNCTION__, mId);
963 status_t res = disconnectLocked();
964
965 mBufferLimitLatency.log("Stream %d latency histogram for wait on max_buffers", mId);
966 mBufferLimitLatency.reset();
967
968 if (res == -ENOTCONN) {
969 // "Already disconnected" -- not an error
970 return OK;
971 } else {
972 return res;
973 }
974 }
975
dump(int fd,const Vector<String16> & args)976 void Camera3Stream::dump(int fd, [[maybe_unused]] const Vector<String16> &args)
977 {
978 mBufferLimitLatency.dump(fd,
979 " Latency histogram for wait on max_buffers");
980 }
981
getBufferLocked(camera_stream_buffer *,const std::vector<size_t> &)982 status_t Camera3Stream::getBufferLocked(camera_stream_buffer *,
983 const std::vector<size_t>&) {
984 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
985 return INVALID_OPERATION;
986 }
987
returnBufferLocked(const camera_stream_buffer &,nsecs_t,nsecs_t,int32_t,const std::vector<size_t> &)988 status_t Camera3Stream::returnBufferLocked(const camera_stream_buffer &,
989 nsecs_t, nsecs_t, int32_t, const std::vector<size_t>&) {
990 ALOGE("%s: This type of stream does not support output", __FUNCTION__);
991 return INVALID_OPERATION;
992 }
getInputBufferLocked(camera_stream_buffer *,Size *)993 status_t Camera3Stream::getInputBufferLocked(camera_stream_buffer *, Size *) {
994 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
995 return INVALID_OPERATION;
996 }
returnInputBufferLocked(const camera_stream_buffer &)997 status_t Camera3Stream::returnInputBufferLocked(
998 const camera_stream_buffer &) {
999 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
1000 return INVALID_OPERATION;
1001 }
1002 #if WB_CAMERA3_AND_PROCESSORS_WITH_DEPENDENCIES
getInputSurfaceLocked(sp<Surface> *)1003 status_t Camera3Stream::getInputSurfaceLocked(sp<Surface>*) {
1004 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
1005 return INVALID_OPERATION;
1006 }
1007 #else
getInputBufferProducerLocked(sp<IGraphicBufferProducer> *)1008 status_t Camera3Stream::getInputBufferProducerLocked(sp<IGraphicBufferProducer>*) {
1009 ALOGE("%s: This type of stream does not support input", __FUNCTION__);
1010 return INVALID_OPERATION;
1011 }
1012 #endif
1013
addBufferListener(wp<Camera3StreamBufferListener> listener)1014 void Camera3Stream::addBufferListener(
1015 wp<Camera3StreamBufferListener> listener) {
1016 Mutex::Autolock l(mLock);
1017
1018 List<wp<Camera3StreamBufferListener> >::iterator it, end;
1019 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
1020 it != end;
1021 ) {
1022 if (*it == listener) {
1023 ALOGE("%s: Try to add the same listener twice, ignoring...", __FUNCTION__);
1024 return;
1025 }
1026 it++;
1027 }
1028
1029 mBufferListenerList.push_back(listener);
1030 }
1031
removeBufferListener(const sp<Camera3StreamBufferListener> & listener)1032 void Camera3Stream::removeBufferListener(
1033 const sp<Camera3StreamBufferListener>& listener) {
1034 Mutex::Autolock l(mLock);
1035
1036 bool erased = true;
1037 List<wp<Camera3StreamBufferListener> >::iterator it, end;
1038 for (it = mBufferListenerList.begin(), end = mBufferListenerList.end();
1039 it != end;
1040 ) {
1041
1042 if (*it == listener) {
1043 it = mBufferListenerList.erase(it);
1044 erased = true;
1045 } else {
1046 ++it;
1047 }
1048 }
1049
1050 if (!erased) {
1051 ALOGW("%s: Could not find listener to remove, already removed",
1052 __FUNCTION__);
1053 }
1054 }
1055
setBufferFreedListener(wp<Camera3StreamBufferFreedListener> listener)1056 void Camera3Stream::setBufferFreedListener(
1057 wp<Camera3StreamBufferFreedListener> listener) {
1058 Mutex::Autolock l(mLock);
1059 // Only allow set listener during stream configuration because stream is guaranteed to be IDLE
1060 // at this state, so setBufferFreedListener won't collide with onBufferFreed callbacks
1061 if (mState != STATE_IN_CONFIG && mState != STATE_IN_RECONFIG) {
1062 ALOGE("%s: listener must be set during stream configuration!",__FUNCTION__);
1063 return;
1064 }
1065 mBufferFreedListener = listener;
1066 }
1067
queueHDRMetadata(buffer_handle_t buffer,sp<ANativeWindow> & anw,int64_t dynamicRangeProfile)1068 void Camera3Stream::queueHDRMetadata(buffer_handle_t buffer, sp<ANativeWindow>& anw,
1069 int64_t dynamicRangeProfile) {
1070 auto& mapper = GraphicBufferMapper::get();
1071 switch (dynamicRangeProfile) {
1072 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10: {
1073 std::optional<ui::Smpte2086> smpte2086;
1074 auto res = mapper.getSmpte2086(buffer, &smpte2086);
1075 if ((res == OK) && smpte2086.has_value()) {
1076 const auto& metaValue = smpte2086.value();
1077 android_smpte2086_metadata meta = {
1078 .displayPrimaryRed.x = metaValue.primaryRed.x,
1079 .displayPrimaryRed.y = metaValue.primaryRed.y,
1080 .displayPrimaryGreen.x = metaValue.primaryGreen.x,
1081 .displayPrimaryGreen.y = metaValue.primaryGreen.y,
1082 .displayPrimaryBlue.x = metaValue.primaryBlue.x,
1083 .displayPrimaryBlue.y = metaValue.primaryBlue.y,
1084 .whitePoint.x = metaValue.whitePoint.x,
1085 .whitePoint.y = metaValue.whitePoint.y,
1086 .maxLuminance = metaValue.maxLuminance,
1087 .minLuminance = metaValue.minLuminance};
1088 native_window_set_buffers_smpte2086_metadata(anw.get(), &meta);
1089 } else {
1090 ALOGE("%s Couldn't retrieve Smpte2086 metadata %s (%d)",
1091 __FUNCTION__, strerror(-res), res);
1092 }
1093 break;
1094 }
1095 case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS: {
1096 std::optional<std::vector<uint8_t>> smpte2094_40;
1097 auto res = mapper.getSmpte2094_40(buffer, &smpte2094_40);
1098 if ((res == OK) && smpte2094_40.has_value()) {
1099 native_window_set_buffers_hdr10_plus_metadata(anw.get(),
1100 smpte2094_40.value().size(), smpte2094_40.value().data());
1101 } else {
1102 ALOGE("%s Couldn't retrieve Smpte2094_40 metadata %s (%d)",
1103 __FUNCTION__, strerror(-res), res);
1104 }
1105 break;
1106 }
1107 default:
1108 // No-op
1109 break;
1110 }
1111 }
1112
1113
1114 }; // namespace camera3
1115
1116 }; // namespace android
1117