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

Commit e984d682 authored by Haynes Mathew George's avatar Haynes Mathew George Committed by Steve Kondik
Browse files

AudioTrack: Handle track invalidate on wait for stream done

If a track invalidate is called while waiting for a stream done,
AudioCallback handler is notified with event EVENT_STREAM_END.
This might cause substantial data loss for offload playback. Try to
recreate the track if needed.

Change-Id: Ie663c85e92588ddfd8d633f4bf5024f9fa4f5c2e
parent 32768aff
Loading
Loading
Loading
Loading
+1 −31
Original line number Diff line number Diff line
@@ -1797,36 +1797,6 @@ nsecs_t AudioTrack::processAudioBuffer()

    mLock.unlock();

    if (waitStreamEnd) {
        struct timespec timeout;
        timeout.tv_sec = WAIT_STREAM_END_TIMEOUT_SEC;
        timeout.tv_nsec = 0;

        status_t status = proxy->waitStreamEndDone(&timeout);
        switch (status) {
        case NO_ERROR:
        case DEAD_OBJECT:
        case TIMED_OUT:
            mCbf(EVENT_STREAM_END, mUserData, NULL);
            {
                AutoMutex lock(mLock);
                // The previously assigned value of waitStreamEnd is no longer valid,
                // since the mutex has been unlocked and either the callback handler
                // or another thread could have re-started the AudioTrack during that time.
                waitStreamEnd = mState == STATE_STOPPING;
                if (waitStreamEnd) {
                    mState = STATE_STOPPED;
                    mReleased = 0;
                }
            }
            if (waitStreamEnd && status != DEAD_OBJECT) {
               return NS_INACTIVE;
            }
            break;
        }
        return 0;
    }

    // perform callbacks while unlocked
    if (newUnderrun) {
        mCbf(EVENT_UNDERRUN, mUserData, NULL);
@@ -1876,7 +1846,7 @@ nsecs_t AudioTrack::processAudioBuffer()
        case NO_ERROR:
        case DEAD_OBJECT:
        case TIMED_OUT:
            if (isOffloaded()) {
            if (isOffloaded_l()) {
                if (mCblk->mFlags & (CBLK_INVALID | CBLK_STREAM_FATAL_ERROR)) {
                    // will trigger EVENT_NEW_IAUDIOTRACK/STREAM_END in next iteration
                    return 0;