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) { |