Home | History | Annotate | Download | only in device3
      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 
     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 
     39 Camera3Stream* Camera3Stream::cast(camera3_stream *stream) {
     40     return static_cast<Camera3Stream*>(stream);
     41 }
     42 
     43 const Camera3Stream* Camera3Stream::cast(const camera3_stream *stream) {
     44     return static_cast<const Camera3Stream*>(stream);
     45 }
     46 
     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 
     94 int Camera3Stream::getId() const {
     95     return mId;
     96 }
     97 
     98 int Camera3Stream::getStreamSetId() const {
     99     return mSetId;
    100 }
    101 
    102 uint32_t Camera3Stream::getWidth() const {
    103     return camera3_stream::width;
    104 }
    105 
    106 uint32_t Camera3Stream::getHeight() const {
    107     return camera3_stream::height;
    108 }
    109 
    110 int Camera3Stream::getFormat() const {
    111     return camera3_stream::format;
    112 }
    113 
    114 android_dataspace Camera3Stream::getDataSpace() const {
    115     return camera3_stream::data_space;
    116 }
    117 
    118 uint64_t Camera3Stream::getUsage() const {
    119     return mUsage;
    120 }
    121 
    122 void Camera3Stream::setUsage(uint64_t usage) {
    123     mUsage = usage;
    124 }
    125 
    126 void Camera3Stream::setFormatOverride(bool formatOverridden) {
    127     mFormatOverridden = formatOverridden;
    128 }
    129 
    130 bool Camera3Stream::isFormatOverridden() const {
    131     return mFormatOverridden;
    132 }
    133 
    134 int Camera3Stream::getOriginalFormat() const {
    135     return mOriginalFormat;
    136 }
    137 
    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 
    145 bool Camera3Stream::isDataSpaceOverridden() const {
    146     return mDataSpaceOverridden;
    147 }
    148 
    149 android_dataspace Camera3Stream::getOriginalDataSpace() const {
    150     return mOriginalDataSpace;
    151 }
    152 
    153 const String8& Camera3Stream::physicalCameraId() const {
    154     return mPhysicalCameraId;
    155 }
    156 
    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 
    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 
    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 
    292 bool Camera3Stream::isConfiguring() const {
    293     Mutex::Autolock l(mLock);
    294     return (mState == STATE_IN_CONFIG) || (mState == STATE_IN_RECONFIG);
    295 }
    296 
    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 
    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 
    403 bool Camera3Stream::isUnpreparable() {
    404     ATRACE_CALL();
    405 
    406     Mutex::Autolock l(mLock);
    407     return mStreamUnpreparable;
    408 }
    409 
    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 
    463 bool Camera3Stream::isBlockedByPrepare() const {
    464     Mutex::Autolock l(mLock);
    465     return mState == STATE_PREPARING && mPrepareBlockRequest;
    466 }
    467 
    468 bool Camera3Stream::isAbandoned() const {
    469     Mutex::Autolock l(mLock);
    470     return mState == STATE_ABANDONED;
    471 }
    472 
    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 
    508 status_t Camera3Stream::cancelPrepare() {
    509     ATRACE_CALL();
    510 
    511     Mutex::Autolock l(mLock);
    512 
    513     return cancelPrepareLocked();
    514 }
    515 
    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 
    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 
    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 
    647 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 
    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 
    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 
    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 
    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 
    779 status_t Camera3Stream::getInputBufferProducer(sp<IGraphicBufferProducer> *producer) {
    780     ATRACE_CALL();
    781     Mutex::Autolock l(mLock);
    782 
    783     return getInputBufferProducerLocked(producer);
    784 }
    785 
    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 
    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 
    829 bool Camera3Stream::hasOutstandingBuffers() const {
    830     ATRACE_CALL();
    831     Mutex::Autolock l(mLock);
    832     return hasOutstandingBuffersLocked();
    833 }
    834 
    835 size_t Camera3Stream::getOutstandingBuffersCount() const {
    836     ATRACE_CALL();
    837     Mutex::Autolock l(mLock);
    838     return getHandoutOutputBufferCountLocked();
    839 }
    840 
    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 
    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 
    870 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 
    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 }
    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 }
    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 }
    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 }
    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 
    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 
    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 
    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