From 08dc42c46c942ff316a69be1cf74f3c60cf53e7f Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Wed, 1 Jul 2015 16:48:18 -0700 Subject: stagefright: flush pending video frames for MediaSync Bug: 22234976 Change-Id: Ib63c2286610181968658fb38f5526a489635cf3e --- media/libstagefright/MediaSync.cpp | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'media/libstagefright/MediaSync.cpp') 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) { -- cgit v1.1