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

Commit af69ca18 authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "audioflinger: multiple tracks on direct output" into jb-mr2-dev

parents 2e9c6f37 d595b7c8
Loading
Loading
Loading
Loading
+52 −45
Original line number Diff line number Diff line
@@ -3122,16 +3122,15 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
    Vector< sp<Track> > *tracksToRemove
)
{
    sp<Track> trackToRemove;

    size_t count = mActiveTracks.size();
    mixer_state mixerStatus = MIXER_IDLE;

    // find out which tracks need to be processed
    if (mActiveTracks.size() != 0) {
        sp<Track> t = mActiveTracks[0].promote();
    for (size_t i = 0; i < count; i++) {
        sp<Track> t = mActiveTracks[i].promote();
        // The track died recently
        if (t == 0) {
            return MIXER_IDLE;
            continue;
        }

        Track* const track = t.get();
@@ -3180,7 +3179,11 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
                }
                right = v_clamped/MAX_GAIN;
            }

            // Only consider last track started for volume and mixer state control.
            // This is the last entry in mActiveTracks unless a track underruns.
            // As we only care about the transition phase between two tracks on a
            // direct output, it is not a problem to ignore the underrun case.
            if (i == (count - 1)) {
                if (left != mLeftVolFloat || right != mRightVolFloat) {
                    mLeftVolFloat = left;
                    mRightVolFloat = right;
@@ -3205,10 +3208,11 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
                track->mRetryCount = kMaxTrackRetriesDirect;
                mActiveTrack = t;
                mixerStatus = MIXER_TRACKS_READY;
            }
        } else {
            // clear effect chain input buffer if an active track underruns to avoid sending
            // previous audio buffer again to effects
            if (!mEffectChains.isEmpty()) {
            // clear effect chain input buffer if the last active track started underruns
            // to avoid sending previous audio buffer again to effects
            if (!mEffectChains.isEmpty() && (i == (count -1))) {
                mEffectChains[0]->clearInputBuffer();
            }

@@ -3224,33 +3228,36 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
                    if (track->isStopped()) {
                        track->reset();
                    }
                    trackToRemove = track;
                    tracksToRemove->add(track);
                }
            } else {
                // No buffers for this track. Give it a few chances to
                // fill a buffer, then remove it from active list.
                // Only consider last track started for mixer state control
                if (--(track->mRetryCount) <= 0) {
                    ALOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
                    trackToRemove = track;
                } else {
                    tracksToRemove->add(track);
                } else if (i == (count -1)){
                    mixerStatus = MIXER_TRACKS_ENABLED;
                }
            }
        }
    }

    // FIXME merge this with similar code for removing multiple tracks
    // remove all the tracks that need to be...
    if (CC_UNLIKELY(trackToRemove != 0)) {
        tracksToRemove->add(trackToRemove);
        mActiveTracks.remove(trackToRemove);
    count = tracksToRemove->size();
    if (CC_UNLIKELY(count)) {
        for (size_t i = 0 ; i < count ; i++) {
            const sp<Track>& track = tracksToRemove->itemAt(i);
            mActiveTracks.remove(track);
            if (!mEffectChains.isEmpty()) {
                ALOGV("stopping track on chain %p for session Id: %d", mEffectChains[0].get(),
                    trackToRemove->sessionId());
                      track->sessionId());
                mEffectChains[0]->decActiveTrackCnt();
            }
        if (trackToRemove->isTerminated()) {
            removeTrack_l(trackToRemove);
            if (track->isTerminated()) {
                removeTrack_l(track);
            }
        }
    }