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

Commit f929f9b2 authored by Andy Hung's avatar Andy Hung Committed by Android (Google) Code Review
Browse files

Merge "AudioFlinger: Prevent offload underrun during active playback" into nyc-mr1-dev

parents f769ab76 f8044758
Loading
Loading
Loading
Loading
+27 −7
Original line number Diff line number Diff line
@@ -5359,7 +5359,8 @@ void AudioFlinger::AsyncCallbackThread::setAsyncError()
AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger,
        AudioStreamOut* output, audio_io_handle_t id, uint32_t device, bool systemReady)
    :   DirectOutputThread(audioFlinger, output, id, device, OFFLOAD, systemReady),
        mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true)
        mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true),
        mOffloadUnderrunPosition(~0LL)
{
    //FIXME: mStandby should be set to true by ThreadBase constructor
    mStandby = true;
@@ -5569,12 +5570,30 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr
                // No buffers for this track. Give it a few chances to
                // fill a buffer, then remove it from active list.
                if (--(track->mRetryCount) <= 0) {
                    bool running = false;
                    if (mOutput->stream->get_presentation_position != nullptr) {
                        uint64_t position = 0;
                        struct timespec unused;
                        // The running check restarts the retry counter at least once.
                        int ret = mOutput->stream->get_presentation_position(
                                mOutput->stream, &position, &unused);
                        if (ret == NO_ERROR && position != mOffloadUnderrunPosition) {
                            running = true;
                            mOffloadUnderrunPosition = position;
                        }
                        ALOGVV("underrun counter, running(%d): %lld vs %lld", running,
                                (long long)position, (long long)mOffloadUnderrunPosition);
                    }
                    if (running) { // still running, give us more time.
                        track->mRetryCount = kMaxTrackRetriesOffload;
                    } else {
                        ALOGV("OffloadThread: BUFFER TIMEOUT: remove(%d) from active list",
                                track->name());
                        tracksToRemove->add(track);
                        // indicate to client process that the track was disabled because of underrun;
                        // it will then automatically call start() when data is available
                        track->disable();
                    }
                } else if (last){
                    mixerStatus = MIXER_TRACKS_ENABLED;
                }
@@ -5631,6 +5650,7 @@ void AudioFlinger::OffloadThread::flushHw_l()
    mPausedBytesRemaining = 0;
    // reset bytes written count to reflect that DSP buffers are empty after flush.
    mBytesWritten = 0;
    mOffloadUnderrunPosition = ~0LL;

    if (mUseAsyncWrite) {
        // discard any pending drain or write ack by incrementing sequence
+4 −0
Original line number Diff line number Diff line
@@ -1027,6 +1027,10 @@ private:
    size_t      mPausedWriteLength;     // length in bytes of write interrupted by pause
    size_t      mPausedBytesRemaining;  // bytes still waiting in mixbuffer after resume
    bool        mKeepWakeLock;          // keep wake lock while waiting for write callback
    uint64_t    mOffloadUnderrunPosition; // Current frame position for offloaded playback
                                          // used and valid only during underrun.  ~0 if
                                          // no underrun has occurred during playback and
                                          // is not reset on standby.
};

class AsyncCallbackThread : public Thread {