summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/stagefright/MediaSync.h4
-rw-r--r--media/libstagefright/MediaSync.cpp32
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) {