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

Commit 0fe52c8b authored by Glenn Kasten's avatar Glenn Kasten
Browse files

Merge dup code at thread entry and param change

This CL is mostly just cleanup, but there are a couple of fixes marked
"FIX" below.

Merge the duplicate code that was at the beginning of threadLoop() and
after a parameter change.  cacheParameters_l() is now called at entry to
threadLoop() and after any parameter change.  It re-calculates all values
that are derived from parameters, and caches them in instance variables.

updateWaitTime_l():
 - FIX activeSleepTime depends on mWaitTimeMs, which was initially set
   to infinity.  updateWaitTime_l() was not called at entry to
   threadLoop(), so activeSleepTime was not set correctly before the
   first parameter change.

 - FIX reversed the order of calls after parameter change
   for the same reason so that updateWaitTime_l() is called before
   calculating values that are derived from wait time.

 - marked it private since now it's only called from DuplicatingThread

Change-Id: If2607d2ed66c6893d910433e48208a93c41fb7e9
parent c4ffe77a
Loading
Loading
Loading
Loading
+62 −48
Original line number Diff line number Diff line
@@ -1464,7 +1464,8 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
        mMasterVolume(audioFlinger->masterVolumeSW_l()),
        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),
        // mMixerStatus
        mPrevMixerStatus(MIXER_IDLE)
        mPrevMixerStatus(MIXER_IDLE),
        standbyDelay(AudioFlinger::mStandbyTimeInNsecs)
{
    snprintf(mName, kNameLength, "AudioOut_%X", id);

@@ -1997,14 +1998,8 @@ bool AudioFlinger::PlaybackThread::threadLoop()
    Vector< sp<Track> > tracksToRemove;

    standbyTime = systemTime();
    mixBufferSize = mFrameCount * mFrameSize;

    // MIXER
    // FIXME: Relaxed timing because of a certain device that can't meet latency
    // Should be reduced to 2x after the vendor fixes the driver issue
    // increase threshold again due to low power audio mode. The way this warning threshold is
    // calculated and its usefulness should be reconsidered anyway.
    nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
    nsecs_t lastWarning = 0;
if (mType == MIXER) {
    longStandbyExit = false;
@@ -2014,8 +2009,7 @@ if (mType == MIXER) {
    // FIXME could this be made local to while loop?
    writeFrames = 0;

    activeSleepTime = activeSleepTimeUs();
    idleSleepTime = idleSleepTimeUs();
    cacheParameters_l();
    sleepTime = idleSleepTime;

if (mType == MIXER) {
@@ -2025,13 +2019,6 @@ if (mType == MIXER) {
    // MIXER
    CpuStats cpuStats;

    // DIRECT
if (mType == DIRECT) {
    // use shorter standby delay as on normal output to release
    // hardware resources as soon as possible
    standbyDelay = microseconds(activeSleepTime*2);
}

    acquireWakeLock();

    while (!exitPending())
@@ -2050,25 +2037,7 @@ if (mType == MIXER) {
            Mutex::Autolock _l(mLock);

            if (checkForNewParameters_l()) {
                mixBufferSize = mFrameCount * mFrameSize;

if (mType == MIXER) {
                // FIXME: Relaxed timing because of a certain device that can't meet latency
                // Should be reduced to 2x after the vendor fixes the driver issue
                // increase threshold again due to low power audio mode. The way this warning
                // threshold is calculated and its usefulness should be reconsidered anyway.
                maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
}

                updateWaitTime_l();

                activeSleepTime = activeSleepTimeUs();
                idleSleepTime = idleSleepTimeUs();

if (mType == DIRECT) {
                standbyDelay = microseconds(activeSleepTime*2);
}

                cacheParameters_l();
            }

            saveOutputTracks();
@@ -2103,16 +2072,8 @@ if (mType == DIRECT) {

                    checkSilentMode_l();

if (mType == MIXER || mType == DUPLICATING) {
                    standbyTime = systemTime() + mStandbyTimeInNsecs;
}

if (mType == DIRECT) {
                    standbyTime = systemTime() + standbyDelay;
}

                    sleepTime = idleSleepTime;

                    if (mType == MIXER) {
                        sleepTimeShift = 0;
                    }
@@ -2261,7 +2222,7 @@ void AudioFlinger::MixerThread::threadLoop_mix()
        sleepTimeShift--;
    }
    sleepTime = 0;
    standbyTime = systemTime() + mStandbyTimeInNsecs;
    standbyTime = systemTime() + standbyDelay;
    //TODO: delay standby when effects have a tail
}

@@ -2548,6 +2509,32 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
    return mixerStatus;
}

/*
The derived values that are cached:
 - mixBufferSize from frame count * frame size
 - activeSleepTime from activeSleepTimeUs()
 - idleSleepTime from idleSleepTimeUs()
 - standbyDelay from mActiveSleepTimeUs (DIRECT only)
 - maxPeriod from frame count and sample rate (MIXER only)

The parameters that affect these derived values are:
 - frame count
 - frame size
 - sample rate
 - device type: A2DP or not
 - device latency
 - format: PCM or not
 - active sleep time
 - idle sleep time
*/

void AudioFlinger::PlaybackThread::cacheParameters_l()
{
    mixBufferSize = mFrameCount * mFrameSize;
    activeSleepTime = activeSleepTimeUs();
    idleSleepTime = idleSleepTimeUs();
}

void AudioFlinger::MixerThread::invalidateTracks(audio_stream_type_t streamType)
{
    ALOGV ("MixerThread::invalidateTracks() mixer %p, streamType %d, mTracks.size %d",
@@ -2718,6 +2705,17 @@ uint32_t AudioFlinger::MixerThread::suspendSleepTimeUs()
    return (uint32_t)(((mFrameCount * 1000) / mSampleRate) * 1000);
}

void AudioFlinger::MixerThread::cacheParameters_l()
{
    PlaybackThread::cacheParameters_l();

    // FIXME: Relaxed timing because of a certain device that can't meet latency
    // Should be reduced to 2x after the vendor fixes the driver issue
    // increase threshold again due to low power audio mode. The way this warning
    // threshold is calculated and its usefulness should be reconsidered anyway.
    maxPeriod = seconds(mFrameCount) / mSampleRate * 15;
}

// ----------------------------------------------------------------------------
AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger,
        AudioStreamOut* output, audio_io_handle_t id, uint32_t device)
@@ -3074,6 +3072,14 @@ uint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs()
    return time;
}

void AudioFlinger::DirectOutputThread::cacheParameters_l()
{
    PlaybackThread::cacheParameters_l();

    // use shorter standby delay as on normal output to release
    // hardware resources as soon as possible
    standbyDelay = microseconds(activeSleepTime*2);
}

// ----------------------------------------------------------------------------

@@ -3127,7 +3133,7 @@ void AudioFlinger::DuplicatingThread::threadLoop_sleepTime()

void AudioFlinger::DuplicatingThread::threadLoop_write()
{
    standbyTime = systemTime() + mStandbyTimeInNsecs;
    standbyTime = systemTime() + standbyDelay;
    for (size_t i = 0; i < outputTracks.size(); i++) {
        outputTracks[i]->write(mMixBuffer, writeFrames);
    }
@@ -3223,6 +3229,14 @@ uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs()
    return (mWaitTimeMs * 1000) / 2;
}

void AudioFlinger::DuplicatingThread::cacheParameters_l()
{
    // updateWaitTime_l() sets mWaitTimeMs, which affects activeSleepTimeUs(), so call it first
    updateWaitTime_l();

    MixerThread::cacheParameters_l();
}

// ----------------------------------------------------------------------------

// TrackBase constructor must be called with AudioFlinger::mLock held
+19 −4
Original line number Diff line number Diff line
@@ -222,6 +222,8 @@ private:
    audio_hw_device_t*      findSuitableHwDev_l(uint32_t devices);
    void                    purgeStaleEffects_l();

    // standby delay for MIXER and DUPLICATING playback threads is read from property
    // ro.audio.flinger_standbytime_ms or defaults to kDefaultStandbyTimeInNsecs
    static nsecs_t          mStandbyTimeInNsecs;

    // Internal dump utilites.
@@ -840,9 +842,6 @@ protected:
        virtual     void        threadLoop_write();
        virtual     void        threadLoop_standby();

        // Non-trivial for DUPLICATING only
        virtual     void        updateWaitTime_l() { }

        // Non-trivial for DIRECT only
        virtual     void        applyVolume() { }

@@ -929,6 +928,9 @@ public:
        virtual     void        saveOutputTracks() { }
        virtual     void        clearOutputTracks() { }

        // Cache various calculated values, at threadLoop() entry and after a parameter change
        virtual     void        cacheParameters_l();

    private:

        friend class AudioFlinger;
@@ -964,8 +966,11 @@ public:
        // FIXME rename these former local variables of threadLoop to standard "m" names
        nsecs_t                         standbyTime;
        size_t                          mixBufferSize;

        // cached copies of activeSleepTimeUs() and idleSleepTimeUs() made by cacheParameters_l()
        uint32_t                        activeSleepTime;
        uint32_t                        idleSleepTime;

        uint32_t                        sleepTime;

        // mixer status returned by prepareTracks_l()
@@ -976,8 +981,13 @@ public:
        // MIXER only
        bool                            longStandbyExit;
        uint32_t                        sleepTimeShift;
        // DIRECT only

        // same as AudioFlinger::mStandbyTimeInNsecs except for DIRECT which uses a shorter value
        nsecs_t                         standbyDelay;

        // MIXER only
        nsecs_t                         maxPeriod;

        // DUPLICATING only
        uint32_t                        writeFrames;
    };
@@ -1003,6 +1013,7 @@ public:
        virtual     void        deleteTrackName_l(int name);
        virtual     uint32_t    idleSleepTimeUs();
        virtual     uint32_t    suspendSleepTimeUs();
        virtual     void        cacheParameters_l();

        // threadLoop snippets
        virtual     void        threadLoop_mix();
@@ -1028,6 +1039,7 @@ public:
        virtual     uint32_t    activeSleepTimeUs();
        virtual     uint32_t    idleSleepTimeUs();
        virtual     uint32_t    suspendSleepTimeUs();
        virtual     void        cacheParameters_l();

        // threadLoop snippets
        virtual     mixer_state prepareTracks_l(Vector< sp<Track> > *tracksToRemove);
@@ -1075,9 +1087,12 @@ private:
        virtual     void        threadLoop_sleepTime();
        virtual     void        threadLoop_write();
        virtual     void        threadLoop_standby();
        virtual     void        cacheParameters_l();

    private:
        // called from threadLoop, addOutputTrack, removeOutputTrack
        virtual     void        updateWaitTime_l();
    protected:
        virtual     void        saveOutputTracks();
        virtual     void        clearOutputTracks();
    private: