• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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