Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a546413 authored by Lajos Molnar's avatar Lajos Molnar Committed by Android Git Automerger
Browse files

am 08dc42c4: stagefright: flush pending video frames for MediaSync

* commit '08dc42c4':
  stagefright: flush pending video frames for MediaSync
parents 63f393db 08dc42c4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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;
+31 −1
Original line number Diff line number Diff line
@@ -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) {