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