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