diff options
| -rw-r--r-- | include/media/stagefright/MediaSync.h | 4 | ||||
| -rw-r--r-- | media/libstagefright/MediaSync.cpp | 32 | 
2 files changed, 35 insertions, 1 deletions
diff --git a/include/media/stagefright/MediaSync.h b/include/media/stagefright/MediaSync.h index 1b7d7e8..4b5cd05 100644 --- a/include/media/stagefright/MediaSync.h +++ b/include/media/stagefright/MediaSync.h @@ -104,6 +104,9 @@ public:      // MediaClock::getMediaTime() and MediaClock::getRealTimeFor().      sp<const MediaClock> getMediaClock(); +    // Flush mediasync +    void flush(); +      // Set the video frame rate hint - this is used by the video FrameScheduler      status_t setVideoFrameRateHint(float rate); @@ -195,6 +198,7 @@ private:      sp<IGraphicBufferProducer> mOutput;      int mUsageFlagsFromOutput;      uint32_t mMaxAcquiredBufferCount; // max acquired buffer count +    bool mReturnPendingInputFrame;    // set while we are pending before acquiring an input frame      sp<AudioTrack> mAudioTrack;      uint32_t mNativeSampleRateInHz; diff --git a/media/libstagefright/MediaSync.cpp b/media/libstagefright/MediaSync.cpp index 455db42..0df3ec9 100644 --- a/media/libstagefright/MediaSync.cpp +++ b/media/libstagefright/MediaSync.cpp @@ -52,6 +52,7 @@ MediaSync::MediaSync()          mNumOutstandingBuffers(0),          mUsageFlagsFromOutput(0),          mMaxAcquiredBufferCount(1), +        mReturnPendingInputFrame(false),          mNativeSampleRateInHz(0),          mNumFramesWritten(0),          mHasAudio(false), @@ -245,6 +246,7 @@ void MediaSync::updatePlaybackRate_l(float rate) {          mNextBufferItemMediaUs = -1;      }      mPlaybackRate = rate; +    // TODO: update frame scheduler with this info      mMediaClock->setPlaybackRate(rate);      onDrainVideo_l();  } @@ -338,6 +340,23 @@ void MediaSync::setName(const AString &name) {      mInput->setConsumerName(String8(name.c_str()));  } +void MediaSync::flush() { +    Mutex::Autolock lock(mMutex); +    if (mFrameScheduler != NULL) { +        mFrameScheduler->restart(); +    } +    while (!mBufferItems.empty()) { +        BufferItem *bufferItem = &*mBufferItems.begin(); +        returnBufferToInput_l(bufferItem->mGraphicBuffer, bufferItem->mFence); +        mBufferItems.erase(mBufferItems.begin()); +    } +    mNextBufferItemMediaUs = -1; +    mNumFramesWritten = 0; +    mReturnPendingInputFrame = true; +    mReleaseCondition.signal(); +    mMediaClock->clearAnchor(); +} +  status_t MediaSync::setVideoFrameRateHint(float rate) {      Mutex::Autolock lock(mMutex);      if (rate < 0.f) { @@ -586,10 +605,13 @@ void MediaSync::onFrameAvailableFromInput() {      const static nsecs_t kAcquireWaitTimeout = 2000000000; // 2 seconds +    mReturnPendingInputFrame = false; +      // If there are too many outstanding buffers, wait until a buffer is      // released back to the input in onBufferReleased.      // NOTE: BufferQueue allows dequeuing maxAcquiredBufferCount + 1 buffers -    while (mNumOutstandingBuffers > mMaxAcquiredBufferCount && !mIsAbandoned) { +    while (mNumOutstandingBuffers > mMaxAcquiredBufferCount +            && !mIsAbandoned && !mReturnPendingInputFrame) {          if (mReleaseCondition.waitRelative(mMutex, kAcquireWaitTimeout) != OK) {              ALOGI("still waiting to release a buffer before acquire");          } @@ -633,6 +655,14 @@ void MediaSync::onFrameAvailableFromInput() {      }      mBuffersFromInput.add(bufferItem.mGraphicBuffer->getId(), bufferItem.mGraphicBuffer); +    // If flush happened while waiting for a buffer to be released, simply return it +    // TRICKY: do it here after it is detached so that we don't have to cache mGraphicBuffer. +    if (mReturnPendingInputFrame) { +        mReturnPendingInputFrame = false; +        returnBufferToInput_l(bufferItem.mGraphicBuffer, bufferItem.mFence); +        return; +    } +      mBufferItems.push_back(bufferItem);      if (mBufferItems.size() == 1) {  | 
