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

Commit 67295b54 authored by Marco Nelissen's avatar Marco Nelissen
Browse files

Fix gapless playback

On some devices the actual framecount per buffer of an AudioTrack
will be different than what was requested, which prevented the
track from being reused. Now we create a new AudioTrack with the
requested parameters, and then compare it to the track we already
have. If they match, we throw away the new track and reuse the
existing one.
b/6644559

Change-Id: Id3e8c4460436f52e59b98ecaeb01c94f02877c1d
parent c15d6657
Loading
Loading
Loading
Loading
+47 −38
Original line number Diff line number Diff line
@@ -1542,6 +1542,43 @@ status_t MediaPlayerService::AudioOutput::open(
        }
    }

    AudioTrack *t;
    CallbackData *newcbd = NULL;
    if (mCallback != NULL) {
        newcbd = new CallbackData(this);
        t = new AudioTrack(
                mStreamType,
                sampleRate,
                format,
                channelMask,
                frameCount,
                flags,
                CallbackWrapper,
                newcbd,
                0,  // notification frames
                mSessionId);
    } else {
        t = new AudioTrack(
                mStreamType,
                sampleRate,
                format,
                channelMask,
                frameCount,
                flags,
                NULL,
                NULL,
                0,
                mSessionId);
    }

    if ((t == 0) || (t->initCheck() != NO_ERROR)) {
        ALOGE("Unable to create audio track");
        delete t;
        delete newcbd;
        return NO_INIT;
    }


    if (mRecycledTrack) {
        // check if the existing track can be reused as-is, or if a new track needs to be created.

@@ -1553,11 +1590,14 @@ status_t MediaPlayerService::AudioOutput::open(
            reuse = false;
        } else if ((mRecycledTrack->getSampleRate() != sampleRate) ||
                (mRecycledTrack->channelCount() != channelCount) ||
                (mRecycledTrack->frameCount() != frameCount)) {
            ALOGV("samplerate, channelcount or framecount differ");
                (mRecycledTrack->frameCount() != t->frameCount())) {
            ALOGV("samplerate, channelcount or framecount differ: %d/%d Hz, %d/%d ch, %d/%d frames",
                  mRecycledTrack->getSampleRate(), sampleRate,
                  mRecycledTrack->channelCount(), channelCount,
                  mRecycledTrack->frameCount(), t->frameCount());
            reuse = false;
        } if (flags != mFlags) {
            ALOGV("output flags differ");
        } else if (flags != mFlags) {
            ALOGV("output flags differ %08x/%08x", flags, mFlags);
            reuse = false;
        }
        if (reuse) {
@@ -1568,6 +1608,8 @@ status_t MediaPlayerService::AudioOutput::open(
            if (mCallbackData != NULL) {
                mCallbackData->setOutput(this);
            }
            delete t;
            delete newcbd;
            return OK;
        }

@@ -1584,40 +1626,7 @@ status_t MediaPlayerService::AudioOutput::open(
        close();
    }

    AudioTrack *t;
    if (mCallback != NULL) {
        mCallbackData = new CallbackData(this);
        t = new AudioTrack(
                mStreamType,
                sampleRate,
                format,
                channelMask,
                frameCount,
                flags,
                CallbackWrapper,
                mCallbackData,
                0,  // notification frames
                mSessionId);
    } else {
        t = new AudioTrack(
                mStreamType,
                sampleRate,
                format,
                channelMask,
                frameCount,
                flags,
                NULL,
                NULL,
                0,
                mSessionId);
    }

    if ((t == 0) || (t->initCheck() != NO_ERROR)) {
        ALOGE("Unable to create audio track");
        delete t;
        return NO_INIT;
    }

    mCallbackData = newcbd;
    ALOGV("setVolume");
    t->setVolume(mLeftVolume, mRightVolume);