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