Home | History | Annotate | Download | only in omx
      1 /*
      2  * Copyright (C) 2013 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 #include <inttypes.h>
     18 
     19 #define LOG_TAG "GraphicBufferSource"
     20 //#define LOG_NDEBUG 0
     21 #include <utils/Log.h>
     22 
     23 #define STRINGIFY_ENUMS // for asString in HardwareAPI.h/VideoAPI.h
     24 
     25 #include "GraphicBufferSource.h"
     26 #include <media/stagefright/foundation/ADebug.h>
     27 #include <media/stagefright/foundation/AMessage.h>
     28 #include <media/stagefright/foundation/ColorUtils.h>
     29 #include <media/stagefright/foundation/FileDescriptor.h>
     30 
     31 #include <media/hardware/MetadataBufferType.h>
     32 #include <ui/GraphicBuffer.h>
     33 #include <gui/BufferItem.h>
     34 #include <HardwareAPI.h>
     35 #include "omx/OMXUtils.h"
     36 #include <OMX_Component.h>
     37 #include <OMX_IndexExt.h>
     38 #include "OMXBuffer.h"
     39 
     40 #include <inttypes.h>
     41 #include "FrameDropper.h"
     42 
     43 #include <functional>
     44 #include <memory>
     45 #include <cmath>
     46 
     47 namespace android {
     48 
     49 /**
     50  * A copiable object managing a buffer in the buffer cache managed by the producer. This object
     51  * holds a reference to the buffer, and maintains which buffer slot it belongs to (if any), and
     52  * whether it is still in a buffer slot. It also maintains whether there are any outstanging acquire
     53  * references to it (by buffers acquired from the slot) mainly so that we can keep a debug
     54  * count of how many buffers we need to still release back to the producer.
     55  */
     56 struct GraphicBufferSource::CachedBuffer {
     57     /**
     58      * Token that is used to track acquire counts (as opposed to all references to this object).
     59      */
     60     struct Acquirable { };
     61 
     62     /**
     63      * Create using a buffer cached in a slot.
     64      */
     65     CachedBuffer(slot_id slot, const sp<GraphicBuffer> &graphicBuffer)
     66         : mIsCached(true),
     67           mSlot(slot),
     68           mGraphicBuffer(graphicBuffer),
     69           mAcquirable(std::make_shared<Acquirable>()) {
     70     }
     71 
     72     /**
     73      * Returns the cache slot that this buffer is cached in, or -1 if it is no longer cached.
     74      *
     75      * This assumes that -1 slot id is invalid; though, it is just a benign collision used for
     76      * debugging. This object explicitly manages whether it is still cached.
     77      */
     78     slot_id getSlot() const {
     79         return mIsCached ? mSlot : -1;
     80     }
     81 
     82     /**
     83      * Returns the cached buffer.
     84      */
     85     sp<GraphicBuffer> getGraphicBuffer() const {
     86         return mGraphicBuffer;
     87     }
     88 
     89     /**
     90      * Checks whether this buffer is still in the buffer cache.
     91      */
     92     bool isCached() const {
     93         return mIsCached;
     94     }
     95 
     96     /**
     97      * Checks whether this buffer has an acquired reference.
     98      */
     99     bool isAcquired() const {
    100         return mAcquirable.use_count() > 1;
    101     }
    102 
    103     /**
    104      * Gets and returns a shared acquired reference.
    105      */
    106     std::shared_ptr<Acquirable> getAcquirable() {
    107         return mAcquirable;
    108     }
    109 
    110 private:
    111     friend void GraphicBufferSource::discardBufferAtSlotIndex_l(ssize_t);
    112 
    113     /**
    114      * This method to be called when the buffer is no longer in the buffer cache.
    115      * Called from discardBufferAtSlotIndex_l.
    116      */
    117     void onDroppedFromCache() {
    118         CHECK_DBG(mIsCached);
    119         mIsCached = false;
    120     }
    121 
    122     bool mIsCached;
    123     slot_id mSlot;
    124     sp<GraphicBuffer> mGraphicBuffer;
    125     std::shared_ptr<Acquirable> mAcquirable;
    126 };
    127 
    128 /**
    129  * A copiable object managing a buffer acquired from the producer. This must always be a cached
    130  * buffer. This objects also manages its acquire fence and any release fences that may be returned
    131  * by the encoder for this buffer (this buffer may be queued to the encoder multiple times).
    132  * If no release fences are added by the encoder, the acquire fence is returned as the release
    133  * fence for this - as it is assumed that noone waited for the acquire fence. Otherwise, it is
    134  * assumed that the encoder has waited for the acquire fence (or returned it as the release
    135  * fence).
    136  */
    137 struct GraphicBufferSource::AcquiredBuffer {
    138     AcquiredBuffer(
    139             const std::shared_ptr<CachedBuffer> &buffer,
    140             std::function<void(AcquiredBuffer *)> onReleased,
    141             const sp<Fence> &acquireFence)
    142         : mBuffer(buffer),
    143           mAcquirable(buffer->getAcquirable()),
    144           mAcquireFence(acquireFence),
    145           mGotReleaseFences(false),
    146           mOnReleased(onReleased) {
    147     }
    148 
    149     /**
    150      * Adds a release fence returned by the encoder to this object. If this is called with an
    151      * valid file descriptor, it is added to the list of release fences. These are returned to the
    152      * producer on release() as a merged fence. Regardless of the validity of the file descriptor,
    153      * we take note that a release fence was attempted to be added and the acquire fence can now be
    154      * assumed as acquired.
    155      */
    156     void addReleaseFenceFd(int fenceFd) {
    157         // save all release fences - these will be propagated to the producer if this buffer is
    158         // ever released to it
    159         if (fenceFd >= 0) {
    160             mReleaseFenceFds.push_back(fenceFd);
    161         }
    162         mGotReleaseFences = true;
    163     }
    164 
    165     /**
    166      * Returns the acquire fence file descriptor associated with this object.
    167      */
    168     int getAcquireFenceFd() {
    169         if (mAcquireFence == nullptr || !mAcquireFence->isValid()) {
    170             return -1;
    171         }
    172         return mAcquireFence->dup();
    173     }
    174 
    175     /**
    176      * Returns whether the buffer is still in the buffer cache.
    177      */
    178     bool isCached() const {
    179         return mBuffer->isCached();
    180     }
    181 
    182     /**
    183      * Returns the acquired buffer.
    184      */
    185     sp<GraphicBuffer> getGraphicBuffer() const {
    186         return mBuffer->getGraphicBuffer();
    187     }
    188 
    189     /**
    190      * Returns the slot that this buffer is cached at, or -1 otherwise.
    191      *
    192      * This assumes that -1 slot id is invalid; though, it is just a benign collision used for
    193      * debugging. This object explicitly manages whether it is still cached.
    194      */
    195     slot_id getSlot() const {
    196         return mBuffer->getSlot();
    197     }
    198 
    199     /**
    200      * Creates and returns a release fence object from the acquire fence and/or any release fences
    201      * added. If no release fences were added (even if invalid), returns the acquire fence.
    202      * Otherwise, it returns a merged fence from all the valid release fences added.
    203      */
    204     sp<Fence> getReleaseFence() {
    205         // If did not receive release fences, we assume this buffer was not consumed (it was
    206         // discarded or dropped). In this case release the acquire fence as the release fence.
    207         // We do this here to avoid a dup, close and recreation of the Fence object.
    208         if (!mGotReleaseFences) {
    209             return mAcquireFence;
    210         }
    211         sp<Fence> ret = getReleaseFence(0, mReleaseFenceFds.size());
    212         // clear fds as fence took ownership of them
    213         mReleaseFenceFds.clear();
    214         return ret;
    215     }
    216 
    217     // this video buffer is no longer referenced by the codec (or kept for later encoding)
    218     // it is now safe to release to the producer
    219     ~AcquiredBuffer() {
    220         //mAcquirable.clear();
    221         mOnReleased(this);
    222         // mOnRelease method should call getReleaseFence() that releases all fds but just in case
    223         ALOGW_IF(!mReleaseFenceFds.empty(), "release fences were not obtained, closing fds");
    224         for (int fildes : mReleaseFenceFds) {
    225             ::close(fildes);
    226             TRESPASS_DBG();
    227         }
    228     }
    229 
    230 private:
    231     std::shared_ptr<GraphicBufferSource::CachedBuffer> mBuffer;
    232     std::shared_ptr<GraphicBufferSource::CachedBuffer::Acquirable> mAcquirable;
    233     sp<Fence> mAcquireFence;
    234     Vector<int> mReleaseFenceFds;
    235     bool mGotReleaseFences;
    236     std::function<void(AcquiredBuffer *)> mOnReleased;
    237 
    238     /**
    239      * Creates and returns a release fence from 0 or more release fence file descriptors in from
    240      * the specified range in the array.
    241      *
    242      * @param start start index
    243      * @param num   number of release fds to merge
    244      */
    245     sp<Fence> getReleaseFence(size_t start, size_t num) const {
    246         if (num == 0) {
    247             return Fence::NO_FENCE;
    248         } else if (num == 1) {
    249             return new Fence(mReleaseFenceFds[start]);
    250         } else {
    251             return Fence::merge("GBS::AB",
    252                                 getReleaseFence(start, num >> 1),
    253                                 getReleaseFence(start + (num >> 1), num - (num >> 1)));
    254         }
    255     }
    256 };
    257 
    258 GraphicBufferSource::GraphicBufferSource() :
    259     mInitCheck(UNKNOWN_ERROR),
    260     mNumAvailableUnacquiredBuffers(0),
    261     mNumOutstandingAcquires(0),
    262     mEndOfStream(false),
    263     mEndOfStreamSent(false),
    264     mLastDataspace(HAL_DATASPACE_UNKNOWN),
    265     mExecuting(false),
    266     mSuspended(false),
    267     mStopTimeUs(-1),
    268     mLastActionTimeUs(-1ll),
    269     mSkipFramesBeforeNs(-1ll),
    270     mFrameRepeatIntervalUs(-1ll),
    271     mRepeatLastFrameGeneration(0),
    272     mOutstandingFrameRepeatCount(0),
    273     mFrameRepeatBlockedOnCodecBuffer(false),
    274     mFps(-1.0),
    275     mCaptureFps(-1.0),
    276     mBaseCaptureUs(-1ll),
    277     mBaseFrameUs(-1ll),
    278     mFrameCount(0),
    279     mPrevCaptureUs(-1ll),
    280     mPrevFrameUs(-1ll),
    281     mInputBufferTimeOffsetUs(0ll) {
    282     ALOGV("GraphicBufferSource");
    283 
    284     String8 name("GraphicBufferSource");
    285 
    286     BufferQueue::createBufferQueue(&mProducer, &mConsumer);
    287     mConsumer->setConsumerName(name);
    288 
    289     // Note that we can't create an sp<...>(this) in a ctor that will not keep a
    290     // reference once the ctor ends, as that would cause the refcount of 'this'
    291     // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
    292     // that's what we create.
    293     wp<BufferQueue::ConsumerListener> listener =
    294             static_cast<BufferQueue::ConsumerListener*>(this);
    295     sp<IConsumerListener> proxy =
    296             new BufferQueue::ProxyConsumerListener(listener);
    297 
    298     mInitCheck = mConsumer->consumerConnect(proxy, false);
    299     if (mInitCheck != NO_ERROR) {
    300         ALOGE("Error connecting to BufferQueue: %s (%d)",
    301                 strerror(-mInitCheck), mInitCheck);
    302         return;
    303     }
    304 
    305     memset(&mDefaultColorAspectsPacked, 0, sizeof(mDefaultColorAspectsPacked));
    306 
    307     CHECK(mInitCheck == NO_ERROR);
    308 }
    309 
    310 GraphicBufferSource::~GraphicBufferSource() {
    311     ALOGV("~GraphicBufferSource");
    312     {
    313         // all acquired buffers must be freed with the mutex locked otherwise our debug assertion
    314         // may trigger
    315         Mutex::Autolock autoLock(mMutex);
    316         mAvailableBuffers.clear();
    317         mSubmittedCodecBuffers.clear();
    318         mLatestBuffer.mBuffer.reset();
    319     }
    320 
    321     if (mNumOutstandingAcquires != 0) {
    322         ALOGW("potential buffer leak: acquired=%d", mNumOutstandingAcquires);
    323         TRESPASS_DBG();
    324     }
    325     if (mConsumer != NULL) {
    326         status_t err = mConsumer->consumerDisconnect();
    327         if (err != NO_ERROR) {
    328             ALOGW("consumerDisconnect failed: %d", err);
    329         }
    330     }
    331 }
    332 
    333 Status GraphicBufferSource::onOmxExecuting() {
    334     Mutex::Autolock autoLock(mMutex);
    335     ALOGV("--> executing; available=%zu, submittable=%zd",
    336             mAvailableBuffers.size(), mFreeCodecBuffers.size());
    337     CHECK(!mExecuting);
    338     mExecuting = true;
    339     mLastDataspace = HAL_DATASPACE_UNKNOWN;
    340     ALOGV("clearing last dataSpace");
    341 
    342     // Start by loading up as many buffers as possible.  We want to do this,
    343     // rather than just submit the first buffer, to avoid a degenerate case:
    344     // if all BQ buffers arrive before we start executing, and we only submit
    345     // one here, the other BQ buffers will just sit until we get notified
    346     // that the codec buffer has been released.  We'd then acquire and
    347     // submit a single additional buffer, repeatedly, never using more than
    348     // one codec buffer simultaneously.  (We could instead try to submit
    349     // all BQ buffers whenever any codec buffer is freed, but if we get the
    350     // initial conditions right that will never be useful.)
    351     while (haveAvailableBuffers_l()) {
    352         if (!fillCodecBuffer_l()) {
    353             ALOGV("stop load with available=%zu+%d",
    354                     mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
    355             break;
    356         }
    357     }
    358 
    359     ALOGV("done loading initial frames, available=%zu+%d",
    360             mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
    361 
    362     // If EOS has already been signaled, and there are no more frames to
    363     // submit, try to send EOS now as well.
    364     if (mStopTimeUs == -1 && mEndOfStream && !haveAvailableBuffers_l()) {
    365         submitEndOfInputStream_l();
    366     }
    367 
    368     if (mFrameRepeatIntervalUs > 0ll && mLooper == NULL) {
    369         mReflector = new AHandlerReflector<GraphicBufferSource>(this);
    370 
    371         mLooper = new ALooper;
    372         mLooper->registerHandler(mReflector);
    373         mLooper->start();
    374 
    375         if (mLatestBuffer.mBuffer != nullptr) {
    376             queueFrameRepeat_l();
    377         }
    378     }
    379 
    380     return Status::ok();
    381 }
    382 
    383 Status GraphicBufferSource::onOmxIdle() {
    384     ALOGV("omxIdle");
    385 
    386     Mutex::Autolock autoLock(mMutex);
    387 
    388     if (mExecuting) {
    389         // We are only interested in the transition from executing->idle,
    390         // not loaded->idle.
    391         mExecuting = false;
    392     }
    393     return Status::ok();
    394 }
    395 
    396 Status GraphicBufferSource::onOmxLoaded(){
    397     Mutex::Autolock autoLock(mMutex);
    398     if (mLooper != NULL) {
    399         mLooper->unregisterHandler(mReflector->id());
    400         mReflector.clear();
    401 
    402         mLooper->stop();
    403         mLooper.clear();
    404     }
    405 
    406     ALOGV("--> loaded; available=%zu+%d eos=%d eosSent=%d acquired=%d",
    407             mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers,
    408             mEndOfStream, mEndOfStreamSent, mNumOutstandingAcquires);
    409 
    410     // Codec is no longer executing.  Releasing all buffers to bq.
    411     mFreeCodecBuffers.clear();
    412     mSubmittedCodecBuffers.clear();
    413     mLatestBuffer.mBuffer.reset();
    414     mOMXNode.clear();
    415     mExecuting = false;
    416 
    417     return Status::ok();
    418 }
    419 
    420 Status GraphicBufferSource::onInputBufferAdded(codec_buffer_id bufferId) {
    421     Mutex::Autolock autoLock(mMutex);
    422 
    423     if (mExecuting) {
    424         // This should never happen -- buffers can only be allocated when
    425         // transitioning from "loaded" to "idle".
    426         ALOGE("addCodecBuffer: buffer added while executing");
    427         return Status::fromServiceSpecificError(INVALID_OPERATION);
    428     }
    429 
    430     ALOGV("addCodecBuffer: bufferId=%u", bufferId);
    431 
    432     mFreeCodecBuffers.push_back(bufferId);
    433     return Status::ok();
    434 }
    435 
    436 Status GraphicBufferSource::onInputBufferEmptied(codec_buffer_id bufferId, int fenceFd) {
    437     Mutex::Autolock autoLock(mMutex);
    438     FileDescriptor::Autoclose fence(fenceFd);
    439 
    440     ssize_t cbi = mSubmittedCodecBuffers.indexOfKey(bufferId);
    441     if (cbi < 0) {
    442         // This should never happen.
    443         ALOGE("onInputBufferEmptied: buffer not recognized (bufferId=%u)", bufferId);
    444         return Status::fromServiceSpecificError(BAD_VALUE);
    445     }
    446 
    447     std::shared_ptr<AcquiredBuffer> buffer = mSubmittedCodecBuffers.valueAt(cbi);
    448 
    449     // Move buffer to available buffers
    450     mSubmittedCodecBuffers.removeItemsAt(cbi);
    451     mFreeCodecBuffers.push_back(bufferId);
    452 
    453     // header->nFilledLen may not be the original value, so we can't compare
    454     // that to zero to see of this was the EOS buffer.  Instead we just
    455     // see if there is a null AcquiredBuffer, which should only ever happen for EOS.
    456     if (buffer == nullptr) {
    457         if (!(mEndOfStream && mEndOfStreamSent)) {
    458             // This can happen when broken code sends us the same buffer twice in a row.
    459             ALOGE("onInputBufferEmptied: non-EOS null buffer (bufferId=%u)", bufferId);
    460         } else {
    461             ALOGV("onInputBufferEmptied: EOS null buffer (bufferId=%u@%zd)", bufferId, cbi);
    462         }
    463         // No GraphicBuffer to deal with, no additional input or output is expected, so just return.
    464         return Status::fromServiceSpecificError(BAD_VALUE);
    465     }
    466 
    467     if (!mExecuting) {
    468         // this is fine since this could happen when going from Idle to Loaded
    469         ALOGV("onInputBufferEmptied: no longer executing (bufferId=%u@%zd)", bufferId, cbi);
    470         return Status::fromServiceSpecificError(OK);
    471     }
    472 
    473     ALOGV("onInputBufferEmptied: bufferId=%d@%zd [slot=%d, useCount=%ld, handle=%p] acquired=%d",
    474             bufferId, cbi, buffer->getSlot(), buffer.use_count(), buffer->getGraphicBuffer()->handle,
    475             mNumOutstandingAcquires);
    476 
    477     buffer->addReleaseFenceFd(fence.release());
    478     // release codec reference for video buffer just in case remove does not it
    479     buffer.reset();
    480 
    481     if (haveAvailableBuffers_l()) {
    482         // Fill this codec buffer.
    483         CHECK(!mEndOfStreamSent);
    484         ALOGV("onInputBufferEmptied: buffer freed, feeding codec (available=%zu+%d, eos=%d)",
    485                 mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers, mEndOfStream);
    486         fillCodecBuffer_l();
    487     } else if (mEndOfStream && mStopTimeUs == -1) {
    488         // No frames available, but EOS is pending and no stop time, so use this buffer to
    489         // send that.
    490         ALOGV("onInputBufferEmptied: buffer freed, submitting EOS");
    491         submitEndOfInputStream_l();
    492     } else if (mFrameRepeatBlockedOnCodecBuffer) {
    493         bool success = repeatLatestBuffer_l();
    494         ALOGV("onInputBufferEmptied: completing deferred repeatLatestBuffer_l %s",
    495                 success ? "SUCCESS" : "FAILURE");
    496         mFrameRepeatBlockedOnCodecBuffer = false;
    497     }
    498 
    499     // releaseReleasableBuffers_l();
    500     return Status::ok();
    501 }
    502 
    503 void GraphicBufferSource::onDataspaceChanged_l(
    504         android_dataspace dataspace, android_pixel_format pixelFormat) {
    505     ALOGD("got buffer with new dataSpace #%x", dataspace);
    506     mLastDataspace = dataspace;
    507 
    508     if (ColorUtils::convertDataSpaceToV0(dataspace)) {
    509         mOMXNode->dispatchDataSpaceChanged(mLastDataspace, mDefaultColorAspectsPacked, pixelFormat);
    510     }
    511 }
    512 
    513 bool GraphicBufferSource::fillCodecBuffer_l() {
    514     CHECK(mExecuting && haveAvailableBuffers_l());
    515 
    516     if (mFreeCodecBuffers.empty()) {
    517         // No buffers available, bail.
    518         ALOGV("fillCodecBuffer_l: no codec buffers, available=%zu+%d",
    519                 mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
    520         return false;
    521     }
    522 
    523     VideoBuffer item;
    524     if (mAvailableBuffers.empty()) {
    525         ALOGV("fillCodecBuffer_l: acquiring available buffer, available=%zu+%d",
    526                 mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
    527         if (acquireBuffer_l(&item) != OK) {
    528             ALOGE("fillCodecBuffer_l: failed to acquire available buffer");
    529             return false;
    530         }
    531     } else {
    532         ALOGV("fillCodecBuffer_l: getting available buffer, available=%zu+%d",
    533                 mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
    534         item = *mAvailableBuffers.begin();
    535         mAvailableBuffers.erase(mAvailableBuffers.begin());
    536     }
    537 
    538     int64_t itemTimeUs = item.mTimestampNs / 1000;
    539 
    540     // Process ActionItem in the Queue if there is any. If a buffer's timestamp
    541     // is smaller than the first action's timestamp, no action need to be performed.
    542     // If buffer's timestamp is larger or equal than the last action's timestamp,
    543     // only the last action needs to be performed as all the acitions before the
    544     // the action are overridden by the last action. For the other cases, traverse
    545     // the Queue to find the newest action that with timestamp smaller or equal to
    546     // the buffer's timestamp. For example, an action queue like
    547     // [pause 1us], [resume 2us], [pause 3us], [resume 4us], [pause 5us].... Upon
    548     // receiving a buffer with timestamp 3.5us, only the action [pause, 3us] needs
    549     // to be handled and [pause, 1us], [resume 2us] will be discarded.
    550     bool done = false;
    551     bool seeStopAction = false;
    552     if (!mActionQueue.empty()) {
    553         // First scan to check if bufferTimestamp is smaller than first action's timestamp.
    554         ActionItem nextAction = *(mActionQueue.begin());
    555         if (itemTimeUs < nextAction.mActionTimeUs) {
    556             ALOGV("No action. buffer timestamp %lld us < action timestamp: %lld us",
    557                 (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
    558             // All the actions are ahead. No action need to perform now.
    559             // Release the buffer if is in suspended state, or process the buffer
    560             // if not in suspended state.
    561             done = true;
    562         }
    563 
    564         if (!done) {
    565             // Find the newest action that with timestamp smaller than itemTimeUs. Then
    566             // remove all the actions before and include the newest action.
    567             List<ActionItem>::iterator it = mActionQueue.begin();
    568             while (it != mActionQueue.end() && it->mActionTimeUs <= itemTimeUs
    569                     && nextAction.mAction != ActionItem::STOP) {
    570                 nextAction = *it;
    571                 ++it;
    572             }
    573             mActionQueue.erase(mActionQueue.begin(), it);
    574 
    575             CHECK(itemTimeUs >= nextAction.mActionTimeUs);
    576             switch (nextAction.mAction) {
    577                 case ActionItem::PAUSE:
    578                 {
    579                     mSuspended = true;
    580                     ALOGV("RUNNING/PAUSE -> PAUSE at buffer %lld us  PAUSE Time: %lld us",
    581                             (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
    582                     break;
    583                 }
    584                 case ActionItem::RESUME:
    585                 {
    586                     mSuspended = false;
    587                     ALOGV("PAUSE/RUNNING -> RUNNING at buffer %lld us  RESUME Time: %lld us",
    588                             (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
    589                     break;
    590                 }
    591                 case ActionItem::STOP:
    592                 {
    593                     ALOGV("RUNNING/PAUSE -> STOP at buffer %lld us  STOP Time: %lld us",
    594                             (long long)itemTimeUs, (long long)nextAction.mActionTimeUs);
    595                     // Clear the whole ActionQueue as recording is done
    596                     mActionQueue.clear();
    597                     seeStopAction = true;
    598                     break;
    599                 }
    600                 default:
    601                     TRESPASS_DBG("Unknown action type");
    602                     // return true here because we did consume an available buffer, so the
    603                     // loop in onOmxExecuting will eventually terminate even if we hit this.
    604                     return false;
    605             }
    606         }
    607     }
    608 
    609     if (seeStopAction) {
    610         // Clear all the buffers before setting mEndOfStream and signal EndOfInputStream.
    611         releaseAllAvailableBuffers_l();
    612         mEndOfStream = true;
    613         submitEndOfInputStream_l();
    614         return true;
    615     }
    616 
    617     if (mSuspended) {
    618         return true;
    619     }
    620 
    621     int err = UNKNOWN_ERROR;
    622 
    623     // only submit sample if start time is unspecified, or sample
    624     // is queued after the specified start time
    625     if (mSkipFramesBeforeNs < 0ll || item.mTimestampNs >= mSkipFramesBeforeNs) {
    626         // if start time is set, offset time stamp by start time
    627         if (mSkipFramesBeforeNs > 0) {
    628             item.mTimestampNs -= mSkipFramesBeforeNs;
    629         }
    630 
    631         int64_t timeUs = item.mTimestampNs / 1000;
    632         if (mFrameDropper != NULL && mFrameDropper->shouldDrop(timeUs)) {
    633             ALOGV("skipping frame (%lld) to meet max framerate", static_cast<long long>(timeUs));
    634             // set err to OK so that the skipped frame can still be saved as the lastest frame
    635             err = OK;
    636         } else {
    637             err = submitBuffer_l(item); // this takes shared ownership of the acquired buffer on succeess
    638         }
    639     }
    640 
    641     if (err != OK) {
    642         ALOGV("submitBuffer_l failed, will release bq slot %d", item.mBuffer->getSlot());
    643         return true;
    644     } else {
    645         // Don't set the last buffer id if we're not repeating,
    646         // we'll be holding on to the last buffer for nothing.
    647         if (mFrameRepeatIntervalUs > 0ll) {
    648             setLatestBuffer_l(item);
    649         }
    650         ALOGV("buffer submitted [slot=%d, useCount=%ld] acquired=%d",
    651                 item.mBuffer->getSlot(), item.mBuffer.use_count(), mNumOutstandingAcquires);
    652     }
    653 
    654     return true;
    655 }
    656 
    657 bool GraphicBufferSource::repeatLatestBuffer_l() {
    658     CHECK(mExecuting && !haveAvailableBuffers_l());
    659 
    660     if (mLatestBuffer.mBuffer == nullptr || mSuspended) {
    661         return false;
    662     }
    663 
    664     if (mFreeCodecBuffers.empty()) {
    665         // No buffers available, bail.
    666         ALOGV("repeatLatestBuffer_l: no codec buffers.");
    667         return false;
    668     }
    669 
    670     if (!mLatestBuffer.mBuffer->isCached()) {
    671         ALOGV("repeatLatestBuffer_l: slot was discarded, but repeating our own reference");
    672     }
    673 
    674     // it is ok to update the timestamp of latest buffer as it is only used for submission
    675     status_t err = submitBuffer_l(mLatestBuffer);
    676     if (err != OK) {
    677         return false;
    678     }
    679 
    680     /* repeat last frame up to kRepeatLastFrameCount times.
    681      * in case of static scene, a single repeat might not get rid of encoder
    682      * ghosting completely, refresh a couple more times to get better quality
    683      */
    684     if (--mOutstandingFrameRepeatCount > 0) {
    685         // set up timestamp for repeat frame
    686         mLatestBuffer.mTimestampNs += mFrameRepeatIntervalUs * 1000;
    687         queueFrameRepeat_l();
    688     }
    689 
    690     return true;
    691 }
    692 
    693 void GraphicBufferSource::setLatestBuffer_l(const VideoBuffer &item) {
    694     mLatestBuffer = item;
    695 
    696     ALOGV("setLatestBuffer_l: [slot=%d, useCount=%ld]",
    697             mLatestBuffer.mBuffer->getSlot(), mLatestBuffer.mBuffer.use_count());
    698 
    699     mOutstandingFrameRepeatCount = kRepeatLastFrameCount;
    700     // set up timestamp for repeat frame
    701     mLatestBuffer.mTimestampNs += mFrameRepeatIntervalUs * 1000;
    702     queueFrameRepeat_l();
    703 }
    704 
    705 void GraphicBufferSource::queueFrameRepeat_l() {
    706     mFrameRepeatBlockedOnCodecBuffer = false;
    707 
    708     if (mReflector != NULL) {
    709         sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector);
    710         msg->setInt32("generation", ++mRepeatLastFrameGeneration);
    711         msg->post(mFrameRepeatIntervalUs);
    712     }
    713 }
    714 
    715 bool GraphicBufferSource::calculateCodecTimestamp_l(
    716         nsecs_t bufferTimeNs, int64_t *codecTimeUs) {
    717     int64_t timeUs = bufferTimeNs / 1000;
    718     timeUs += mInputBufferTimeOffsetUs;
    719 
    720     if (mCaptureFps > 0.
    721             && (mFps > 2 * mCaptureFps
    722             || mCaptureFps > 2 * mFps)) {
    723         // Time lapse or slow motion mode
    724         if (mPrevCaptureUs < 0ll) {
    725             // first capture
    726             mPrevCaptureUs = mBaseCaptureUs = timeUs;
    727             // adjust the first sample timestamp.
    728             mPrevFrameUs = mBaseFrameUs =
    729                     std::llround((timeUs * mCaptureFps) / mFps);
    730             mFrameCount = 0;
    731         } else {
    732             // snap to nearest capture point
    733             int64_t nFrames = std::llround(
    734                     (timeUs - mPrevCaptureUs) * mCaptureFps);
    735             if (nFrames <= 0) {
    736                 // skip this frame as it's too close to previous capture
    737                 ALOGV("skipping frame, timeUs %lld", static_cast<long long>(timeUs));
    738                 return false;
    739             }
    740             mFrameCount += nFrames;
    741             mPrevCaptureUs = mBaseCaptureUs + std::llround(
    742                     mFrameCount / mCaptureFps);
    743             mPrevFrameUs = mBaseFrameUs + std::llround(
    744                     mFrameCount / mFps);
    745         }
    746 
    747         ALOGV("timeUs %lld, captureUs %lld, frameUs %lld",
    748                 static_cast<long long>(timeUs),
    749                 static_cast<long long>(mPrevCaptureUs),
    750                 static_cast<long long>(mPrevFrameUs));
    751     } else {
    752         if (timeUs <= mPrevFrameUs) {
    753             // Drop the frame if it's going backward in time. Bad timestamp
    754             // could disrupt encoder's rate control completely.
    755             ALOGW("Dropping frame that's going backward in time");
    756             return false;
    757         }
    758 
    759         mPrevFrameUs = timeUs;
    760     }
    761 
    762     *codecTimeUs = mPrevFrameUs;
    763     return true;
    764 }
    765 
    766 status_t GraphicBufferSource::submitBuffer_l(const VideoBuffer &item) {
    767     CHECK(!mFreeCodecBuffers.empty());
    768     IOMX::buffer_id codecBufferId = *mFreeCodecBuffers.begin();
    769 
    770     ALOGV("submitBuffer_l [slot=%d, bufferId=%d]", item.mBuffer->getSlot(), codecBufferId);
    771 
    772     int64_t codecTimeUs;
    773     if (!calculateCodecTimestamp_l(item.mTimestampNs, &codecTimeUs)) {
    774         return UNKNOWN_ERROR;
    775     }
    776 
    777     if ((android_dataspace)item.mDataspace != mLastDataspace) {
    778         onDataspaceChanged_l(
    779                 item.mDataspace,
    780                 (android_pixel_format)item.mBuffer->getGraphicBuffer()->format);
    781     }
    782 
    783     std::shared_ptr<AcquiredBuffer> buffer = item.mBuffer;
    784     // use a GraphicBuffer for now as OMXNodeInstance is using GraphicBuffers to hold references
    785     // and it requires this graphic buffer to be able to hold its reference
    786     // and thus we would need to create a new GraphicBuffer from an ANWBuffer separate from the
    787     // acquired GraphicBuffer.
    788     // TODO: this can be reworked globally to use ANWBuffer references
    789     sp<GraphicBuffer> graphicBuffer = buffer->getGraphicBuffer();
    790     status_t err = mOMXNode->emptyBuffer(
    791             codecBufferId, OMX_BUFFERFLAG_ENDOFFRAME, graphicBuffer, codecTimeUs,
    792             buffer->getAcquireFenceFd());
    793 
    794     if (err != OK) {
    795         ALOGW("WARNING: emptyGraphicBuffer failed: 0x%x", err);
    796         return err;
    797     }
    798 
    799     mFreeCodecBuffers.erase(mFreeCodecBuffers.begin());
    800 
    801     ssize_t cbix = mSubmittedCodecBuffers.add(codecBufferId, buffer);
    802     ALOGV("emptyGraphicBuffer succeeded, bufferId=%u@%zd bufhandle=%p",
    803             codecBufferId, cbix, graphicBuffer->handle);
    804     return OK;
    805 }
    806 
    807 void GraphicBufferSource::submitEndOfInputStream_l() {
    808     CHECK(mEndOfStream);
    809     if (mEndOfStreamSent) {
    810         ALOGV("EOS already sent");
    811         return;
    812     }
    813 
    814     if (mFreeCodecBuffers.empty()) {
    815         ALOGV("submitEndOfInputStream_l: no codec buffers available");
    816         return;
    817     }
    818     IOMX::buffer_id codecBufferId = *mFreeCodecBuffers.begin();
    819 
    820     // We reject any additional incoming graphic buffers. There is no acquired buffer used for EOS
    821     status_t err = mOMXNode->emptyBuffer(
    822             codecBufferId, OMX_BUFFERFLAG_ENDOFFRAME | OMX_BUFFERFLAG_EOS);
    823     if (err != OK) {
    824         ALOGW("emptyDirectBuffer EOS failed: 0x%x", err);
    825     } else {
    826         mFreeCodecBuffers.erase(mFreeCodecBuffers.begin());
    827         ssize_t cbix = mSubmittedCodecBuffers.add(codecBufferId, nullptr);
    828         ALOGV("submitEndOfInputStream_l: buffer submitted, bufferId=%u@%zd", codecBufferId, cbix);
    829         mEndOfStreamSent = true;
    830 
    831         // no need to hold onto any buffers for frame repeating
    832         ++mRepeatLastFrameGeneration;
    833         mLatestBuffer.mBuffer.reset();
    834     }
    835 }
    836 
    837 status_t GraphicBufferSource::acquireBuffer_l(VideoBuffer *ab) {
    838     BufferItem bi;
    839     status_t err = mConsumer->acquireBuffer(&bi, 0);
    840     if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
    841         // shouldn't happen
    842         ALOGW("acquireBuffer_l: frame was not available");
    843         return err;
    844     } else if (err != OK) {
    845         ALOGW("acquireBuffer_l: failed with err=%d", err);
    846         return err;
    847     }
    848     --mNumAvailableUnacquiredBuffers;
    849 
    850     // Manage our buffer cache.
    851     std::shared_ptr<CachedBuffer> buffer;
    852     ssize_t bsi = mBufferSlots.indexOfKey(bi.mSlot);
    853     if (bi.mGraphicBuffer != NULL) {
    854         // replace/initialize slot with new buffer
    855         ALOGV("acquireBuffer_l: %s buffer slot %d", bsi < 0 ? "setting" : "UPDATING", bi.mSlot);
    856         if (bsi >= 0) {
    857             discardBufferAtSlotIndex_l(bsi);
    858         } else {
    859             bsi = mBufferSlots.add(bi.mSlot, nullptr);
    860         }
    861         buffer = std::make_shared<CachedBuffer>(bi.mSlot, bi.mGraphicBuffer);
    862         mBufferSlots.replaceValueAt(bsi, buffer);
    863     } else {
    864         buffer = mBufferSlots.valueAt(bsi);
    865     }
    866     int64_t frameNum = bi.mFrameNumber;
    867 
    868     std::shared_ptr<AcquiredBuffer> acquiredBuffer =
    869         std::make_shared<AcquiredBuffer>(
    870                 buffer,
    871                 [frameNum, this](AcquiredBuffer *buffer){
    872                     // AcquiredBuffer's destructor should always be called when mMutex is locked.
    873                     // If we had a reentrant mutex, we could just lock it again to ensure this.
    874                     if (mMutex.tryLock() == 0) {
    875                         TRESPASS_DBG();
    876                         mMutex.unlock();
    877                     }
    878 
    879                     // we can release buffers immediately if not using adapters
    880                     // alternately, we could add them to mSlotsToRelease, but we would
    881                     // somehow need to propagate frame number to that queue
    882                     if (buffer->isCached()) {
    883                         --mNumOutstandingAcquires;
    884                         mConsumer->releaseBuffer(
    885                                 buffer->getSlot(), frameNum, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
    886                                 buffer->getReleaseFence());
    887                     }
    888                 },
    889                 bi.mFence);
    890     VideoBuffer videoBuffer{acquiredBuffer, bi.mTimestamp, bi.mDataSpace};
    891     *ab = videoBuffer;
    892     ++mNumOutstandingAcquires;
    893     return OK;
    894 }
    895 
    896 // BufferQueue::ConsumerListener callback
    897 void GraphicBufferSource::onFrameAvailable(const BufferItem& item __unused) {
    898     Mutex::Autolock autoLock(mMutex);
    899 
    900     ALOGV("onFrameAvailable: executing=%d available=%zu+%d",
    901             mExecuting, mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers);
    902     ++mNumAvailableUnacquiredBuffers;
    903 
    904     // For BufferQueue we cannot acquire a buffer if we cannot immediately feed it to the codec
    905     // UNLESS we are discarding this buffer (acquiring and immediately releasing it), which makes
    906     // this an ugly logic.
    907     // NOTE: We could also rely on our debug counter but that is meant only as a debug counter.
    908     if (!areWeDiscardingAvailableBuffers_l() && mFreeCodecBuffers.empty()) {
    909         // we may not be allowed to acquire a possibly encodable buffer, so just note that
    910         // it is available
    911         ALOGV("onFrameAvailable: cannot acquire buffer right now, do it later");
    912 
    913         ++mRepeatLastFrameGeneration; // cancel any pending frame repeat
    914         return;
    915     }
    916 
    917     VideoBuffer buffer;
    918     status_t err = acquireBuffer_l(&buffer);
    919     if (err != OK) {
    920         ALOGE("onFrameAvailable: acquireBuffer returned err=%d", err);
    921     } else {
    922         onBufferAcquired_l(buffer);
    923     }
    924 }
    925 
    926 bool GraphicBufferSource::areWeDiscardingAvailableBuffers_l() {
    927     return mEndOfStreamSent // already sent EOS to codec
    928             || mOMXNode == nullptr // there is no codec connected
    929             || (mSuspended && mActionQueue.empty()) // we are suspended and not waiting for
    930                                                     // any further action
    931             || !mExecuting;
    932 }
    933 
    934 void GraphicBufferSource::onBufferAcquired_l(const VideoBuffer &buffer) {
    935     if (mEndOfStreamSent) {
    936         // This should only be possible if a new buffer was queued after
    937         // EOS was signaled, i.e. the app is misbehaving.
    938         ALOGW("onFrameAvailable: EOS is sent, ignoring frame");
    939     } else if (mOMXNode == NULL || (mSuspended && mActionQueue.empty())) {
    940         // FIXME: if we are suspended but have a resume queued we will stop repeating the last
    941         // frame. Is that the desired behavior?
    942         ALOGV("onFrameAvailable: suspended, ignoring frame");
    943     } else {
    944         ++mRepeatLastFrameGeneration; // cancel any pending frame repeat
    945         mAvailableBuffers.push_back(buffer);
    946         if (mExecuting) {
    947             fillCodecBuffer_l();
    948         }
    949     }
    950 }
    951 
    952 // BufferQueue::ConsumerListener callback
    953 void GraphicBufferSource::onBuffersReleased() {
    954     Mutex::Autolock lock(mMutex);
    955 
    956     uint64_t slotMask;
    957     if (mConsumer->getReleasedBuffers(&slotMask) != NO_ERROR) {
    958         ALOGW("onBuffersReleased: unable to get released buffer set");
    959         slotMask = 0xffffffffffffffffULL;
    960     }
    961 
    962     ALOGV("onBuffersReleased: 0x%016" PRIx64, slotMask);
    963 
    964     for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
    965         if ((slotMask & 0x01) != 0) {
    966             discardBufferInSlot_l(i);
    967         }
    968         slotMask >>= 1;
    969     }
    970 }
    971 
    972 void GraphicBufferSource::discardBufferInSlot_l(GraphicBufferSource::slot_id i) {
    973     ssize_t bsi = mBufferSlots.indexOfKey(i);
    974     if (bsi < 0) {
    975         ALOGW("releasing an unpopulated slot: %d", i);
    976     } else {
    977         discardBufferAtSlotIndex_l(bsi);
    978         mBufferSlots.removeItemsAt(bsi);
    979     }
    980 }
    981 
    982 void GraphicBufferSource::discardBufferAtSlotIndex_l(ssize_t bsi) {
    983     const std::shared_ptr<CachedBuffer>& buffer = mBufferSlots.valueAt(bsi);
    984     // use -2 if there is no latest buffer, and -1 if it is no longer cached
    985     slot_id latestBufferSlot =
    986         mLatestBuffer.mBuffer == nullptr ? -2 : mLatestBuffer.mBuffer->getSlot();
    987     ALOGV("releasing acquired buffer: [slot=%d, useCount=%ld], latest: [slot=%d]",
    988             mBufferSlots.keyAt(bsi), buffer.use_count(), latestBufferSlot);
    989     mBufferSlots.valueAt(bsi)->onDroppedFromCache();
    990 
    991     // If the slot of an acquired buffer is discarded, that buffer will not have to be
    992     // released to the producer, so account it here. However, it is possible that the
    993     // acquired buffer has already been discarded so check if it still is.
    994     if (buffer->isAcquired()) {
    995         --mNumOutstandingAcquires;
    996     }
    997 
    998     // clear the buffer reference (not technically needed as caller either replaces or deletes
    999     // it; done here for safety).
   1000     mBufferSlots.editValueAt(bsi).reset();
   1001     CHECK_DBG(buffer == nullptr);
   1002 }
   1003 
   1004 void GraphicBufferSource::releaseAllAvailableBuffers_l() {
   1005     mAvailableBuffers.clear();
   1006     while (mNumAvailableUnacquiredBuffers > 0) {
   1007         VideoBuffer item;
   1008         if (acquireBuffer_l(&item) != OK) {
   1009             ALOGW("releaseAllAvailableBuffers: failed to acquire available unacquired buffer");
   1010             break;
   1011         }
   1012     }
   1013 }
   1014 
   1015 // BufferQueue::ConsumerListener callback
   1016 void GraphicBufferSource::onSidebandStreamChanged() {
   1017     ALOG_ASSERT(false, "GraphicBufferSource can't consume sideband streams");
   1018 }
   1019 
   1020 status_t GraphicBufferSource::configure(
   1021         const sp<IOmxNodeWrapper>& omxNode,
   1022         int32_t dataSpace,
   1023         int32_t bufferCount,
   1024         uint32_t frameWidth,
   1025         uint32_t frameHeight,
   1026         uint32_t consumerUsage) {
   1027     if (omxNode == NULL) {
   1028         return BAD_VALUE;
   1029     }
   1030 
   1031 
   1032     // Call setMaxAcquiredBufferCount without lock.
   1033     // setMaxAcquiredBufferCount could call back to onBuffersReleased
   1034     // if the buffer count change results in releasing of existing buffers,
   1035     // which would lead to deadlock.
   1036     status_t err = mConsumer->setMaxAcquiredBufferCount(bufferCount);
   1037     if (err != NO_ERROR) {
   1038         ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
   1039                 bufferCount, err);
   1040         return err;
   1041     }
   1042 
   1043     {
   1044         Mutex::Autolock autoLock(mMutex);
   1045         mOMXNode = omxNode;
   1046 
   1047         err = mConsumer->setDefaultBufferSize(frameWidth, frameHeight);
   1048         if (err != NO_ERROR) {
   1049             ALOGE("Unable to set BQ default buffer size to %ux%u: %d",
   1050                     frameWidth, frameHeight, err);
   1051             return err;
   1052         }
   1053 
   1054         consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER;
   1055         mConsumer->setConsumerUsageBits(consumerUsage);
   1056 
   1057         // Sets the default buffer data space
   1058         ALOGD("setting dataspace: %#x, acquired=%d", dataSpace, mNumOutstandingAcquires);
   1059         mConsumer->setDefaultBufferDataSpace((android_dataspace)dataSpace);
   1060         mLastDataspace = (android_dataspace)dataSpace;
   1061 
   1062         mExecuting = false;
   1063         mSuspended = false;
   1064         mEndOfStream = false;
   1065         mEndOfStreamSent = false;
   1066         mSkipFramesBeforeNs = -1ll;
   1067         mFrameRepeatIntervalUs = -1ll;
   1068         mRepeatLastFrameGeneration = 0;
   1069         mOutstandingFrameRepeatCount = 0;
   1070         mLatestBuffer.mBuffer.reset();
   1071         mFrameRepeatBlockedOnCodecBuffer = false;
   1072         mFps = -1.0;
   1073         mCaptureFps = -1.0;
   1074         mBaseCaptureUs = -1ll;
   1075         mBaseFrameUs = -1ll;
   1076         mPrevCaptureUs = -1ll;
   1077         mPrevFrameUs = -1ll;
   1078         mFrameCount = 0;
   1079         mInputBufferTimeOffsetUs = 0;
   1080         mStopTimeUs = -1;
   1081         mActionQueue.clear();
   1082     }
   1083 
   1084     return OK;
   1085 }
   1086 
   1087 status_t GraphicBufferSource::setSuspend(bool suspend, int64_t suspendStartTimeUs) {
   1088     ALOGV("setSuspend=%d at time %lld us", suspend, (long long)suspendStartTimeUs);
   1089 
   1090     Mutex::Autolock autoLock(mMutex);
   1091 
   1092     if (mStopTimeUs != -1) {
   1093         ALOGE("setSuspend failed as STOP action is pending");
   1094         return INVALID_OPERATION;
   1095     }
   1096 
   1097     // Push the action to the queue.
   1098     if (suspendStartTimeUs != -1) {
   1099         // suspendStartTimeUs must be smaller or equal to current systemTime.
   1100         int64_t currentSystemTimeUs = systemTime() / 1000;
   1101         if (suspendStartTimeUs > currentSystemTimeUs) {
   1102             ALOGE("setSuspend failed. %lld is larger than current system time %lld us",
   1103                     (long long)suspendStartTimeUs, (long long)currentSystemTimeUs);
   1104             return INVALID_OPERATION;
   1105         }
   1106         if (mLastActionTimeUs != -1 && suspendStartTimeUs < mLastActionTimeUs) {
   1107             ALOGE("setSuspend failed. %lld is smaller than last action time %lld us",
   1108                     (long long)suspendStartTimeUs, (long long)mLastActionTimeUs);
   1109             return INVALID_OPERATION;
   1110         }
   1111         mLastActionTimeUs = suspendStartTimeUs;
   1112         ActionItem action;
   1113         action.mAction = suspend ? ActionItem::PAUSE : ActionItem::RESUME;
   1114         action.mActionTimeUs = suspendStartTimeUs;
   1115         ALOGV("Push %s action into actionQueue", suspend ? "PAUSE" : "RESUME");
   1116         mActionQueue.push_back(action);
   1117     } else {
   1118         if (suspend) {
   1119             mSuspended = true;
   1120             releaseAllAvailableBuffers_l();
   1121             return OK;
   1122         } else {
   1123             mSuspended = false;
   1124             if (mExecuting && !haveAvailableBuffers_l()
   1125                     && mFrameRepeatBlockedOnCodecBuffer) {
   1126                 if (repeatLatestBuffer_l()) {
   1127                     ALOGV("suspend/deferred repeatLatestBuffer_l SUCCESS");
   1128                     mFrameRepeatBlockedOnCodecBuffer = false;
   1129                 } else {
   1130                     ALOGV("suspend/deferred repeatLatestBuffer_l FAILURE");
   1131                 }
   1132             }
   1133         }
   1134     }
   1135     return OK;
   1136 }
   1137 
   1138 status_t GraphicBufferSource::setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs) {
   1139     ALOGV("setRepeatPreviousFrameDelayUs: delayUs=%lld", (long long)repeatAfterUs);
   1140 
   1141     Mutex::Autolock autoLock(mMutex);
   1142 
   1143     if (mExecuting || repeatAfterUs <= 0ll) {
   1144         return INVALID_OPERATION;
   1145     }
   1146 
   1147     mFrameRepeatIntervalUs = repeatAfterUs;
   1148     return OK;
   1149 }
   1150 
   1151 status_t GraphicBufferSource::setTimeOffsetUs(int64_t timeOffsetUs) {
   1152     Mutex::Autolock autoLock(mMutex);
   1153 
   1154     // timeOffsetUs must be negative for adjustment.
   1155     if (timeOffsetUs >= 0ll) {
   1156         return INVALID_OPERATION;
   1157     }
   1158 
   1159     mInputBufferTimeOffsetUs = timeOffsetUs;
   1160     return OK;
   1161 }
   1162 
   1163 status_t GraphicBufferSource::setMaxFps(float maxFps) {
   1164     ALOGV("setMaxFps: maxFps=%lld", (long long)maxFps);
   1165 
   1166     Mutex::Autolock autoLock(mMutex);
   1167 
   1168     if (mExecuting) {
   1169         return INVALID_OPERATION;
   1170     }
   1171 
   1172     mFrameDropper = new FrameDropper();
   1173     status_t err = mFrameDropper->setMaxFrameRate(maxFps);
   1174     if (err != OK) {
   1175         mFrameDropper.clear();
   1176         return err;
   1177     }
   1178 
   1179     return OK;
   1180 }
   1181 
   1182 status_t GraphicBufferSource::setStartTimeUs(int64_t skipFramesBeforeUs) {
   1183     ALOGV("setStartTimeUs: skipFramesBeforeUs=%lld", (long long)skipFramesBeforeUs);
   1184 
   1185     Mutex::Autolock autoLock(mMutex);
   1186 
   1187     mSkipFramesBeforeNs =
   1188             (skipFramesBeforeUs > 0) ? (skipFramesBeforeUs * 1000) : -1ll;
   1189 
   1190     return OK;
   1191 }
   1192 
   1193 status_t GraphicBufferSource::setStopTimeUs(int64_t stopTimeUs) {
   1194     ALOGV("setStopTimeUs: %lld us", (long long)stopTimeUs);
   1195     Mutex::Autolock autoLock(mMutex);
   1196 
   1197     if (mStopTimeUs != -1) {
   1198         // Ignore if stop time has already been set
   1199         return OK;
   1200     }
   1201 
   1202     // stopTimeUs must be smaller or equal to current systemTime.
   1203     int64_t currentSystemTimeUs = systemTime() / 1000;
   1204     if (stopTimeUs > currentSystemTimeUs) {
   1205         ALOGE("setStopTimeUs failed. %lld is larger than current system time %lld us",
   1206             (long long)stopTimeUs, (long long)currentSystemTimeUs);
   1207         return INVALID_OPERATION;
   1208     }
   1209     if (mLastActionTimeUs != -1 && stopTimeUs < mLastActionTimeUs) {
   1210         ALOGE("setSuspend failed. %lld is smaller than last action time %lld us",
   1211             (long long)stopTimeUs, (long long)mLastActionTimeUs);
   1212         return INVALID_OPERATION;
   1213     }
   1214     mLastActionTimeUs = stopTimeUs;
   1215     ActionItem action;
   1216     action.mAction = ActionItem::STOP;
   1217     action.mActionTimeUs = stopTimeUs;
   1218     mActionQueue.push_back(action);
   1219     mStopTimeUs = stopTimeUs;
   1220     return OK;
   1221 }
   1222 
   1223 status_t GraphicBufferSource::setTimeLapseConfig(double fps, double captureFps) {
   1224     ALOGV("setTimeLapseConfig: fps=%lg, captureFps=%lg",
   1225             fps, captureFps);
   1226 
   1227     Mutex::Autolock autoLock(mMutex);
   1228 
   1229     if (mExecuting || !(fps > 0) || !(captureFps > 0)) {
   1230         return INVALID_OPERATION;
   1231     }
   1232 
   1233     mFps = fps;
   1234     mCaptureFps = captureFps;
   1235 
   1236     return OK;
   1237 }
   1238 
   1239 status_t GraphicBufferSource::setColorAspects(int32_t aspectsPacked) {
   1240     Mutex::Autolock autoLock(mMutex);
   1241     mDefaultColorAspectsPacked = aspectsPacked;
   1242     ColorAspects colorAspects = ColorUtils::unpackToColorAspects(aspectsPacked);
   1243     ALOGD("requesting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s))",
   1244             colorAspects.mRange, asString(colorAspects.mRange),
   1245             colorAspects.mPrimaries, asString(colorAspects.mPrimaries),
   1246             colorAspects.mMatrixCoeffs, asString(colorAspects.mMatrixCoeffs),
   1247             colorAspects.mTransfer, asString(colorAspects.mTransfer));
   1248 
   1249     return OK;
   1250 }
   1251 
   1252 status_t GraphicBufferSource::signalEndOfInputStream() {
   1253     Mutex::Autolock autoLock(mMutex);
   1254     ALOGV("signalEndOfInputStream: executing=%d available=%zu+%d eos=%d",
   1255             mExecuting, mAvailableBuffers.size(), mNumAvailableUnacquiredBuffers, mEndOfStream);
   1256 
   1257     if (mEndOfStream) {
   1258         ALOGE("EOS was already signaled");
   1259         return INVALID_OPERATION;
   1260     }
   1261 
   1262     // Set the end-of-stream flag.  If no frames are pending from the
   1263     // BufferQueue, and a codec buffer is available, and we're executing,
   1264     // and there is no stop timestamp, we initiate the EOS from here.
   1265     // Otherwise, we'll let codecBufferEmptied() (or omxExecuting) do it.
   1266     //
   1267     // Note: if there are no pending frames and all codec buffers are
   1268     // available, we *must* submit the EOS from here or we'll just
   1269     // stall since no future events are expected.
   1270     mEndOfStream = true;
   1271 
   1272     if (mStopTimeUs == -1 && mExecuting && !haveAvailableBuffers_l()) {
   1273         submitEndOfInputStream_l();
   1274     }
   1275 
   1276     return OK;
   1277 }
   1278 
   1279 void GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) {
   1280     switch (msg->what()) {
   1281         case kWhatRepeatLastFrame:
   1282         {
   1283             Mutex::Autolock autoLock(mMutex);
   1284 
   1285             int32_t generation;
   1286             CHECK(msg->findInt32("generation", &generation));
   1287 
   1288             if (generation != mRepeatLastFrameGeneration) {
   1289                 // stale
   1290                 break;
   1291             }
   1292 
   1293             if (!mExecuting || haveAvailableBuffers_l()) {
   1294                 break;
   1295             }
   1296 
   1297             bool success = repeatLatestBuffer_l();
   1298             if (success) {
   1299                 ALOGV("repeatLatestBuffer_l SUCCESS");
   1300             } else {
   1301                 ALOGV("repeatLatestBuffer_l FAILURE");
   1302                 mFrameRepeatBlockedOnCodecBuffer = true;
   1303             }
   1304             break;
   1305         }
   1306 
   1307         default:
   1308             TRESPASS();
   1309     }
   1310 }
   1311 
   1312 }  // namespace android
   1313