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

Commit 3c09c78a authored by Andy Hung's avatar Andy Hung
Browse files

Event driven wake for AudioTrackThread notification changes

Used for setMarkerPosition and setPositionUpdatePeriod.

Change-Id: I0d94b929438a5cd94b295d7c1884f876fae8b5e7
parent 53c3b5fc
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -614,6 +614,7 @@ protected:

                void        pause();    // suspend thread from execution at next loop boundary
                void        resume();   // allow thread to execute, if not requested to exit
                void        wake();     // wake to handle changed notification conditions.

    private:
                void        pauseInternal(nsecs_t ns = 0LL);
@@ -628,7 +629,9 @@ protected:
        bool                mPaused;    // whether thread is requested to pause at next loop entry
        bool                mPausedInt; // whether thread internally requests pause
        nsecs_t             mPausedNs;  // if mPausedInt then associated timeout, otherwise ignored
        bool                mIgnoreNextPausedInt;   // whether to ignore next mPausedInt request
        bool                mIgnoreNextPausedInt;   // skip any internal pause and go immediately
                                        // to processAudioBuffer() as state may have changed
                                        // since pause time calculated.
    };

            // body of AudioTrackThread::threadLoop()
+25 −2
Original line number Diff line number Diff line
@@ -753,6 +753,8 @@ void AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCount)
    mLoopStart = loopStart;
    mLoopCountNotified = loopCount;
    mStaticProxy->setLoop(loopStart, loopEnd, loopCount);

    // Waking the AudioTrackThread is not needed as this cannot be called when active.
}

status_t AudioTrack::setMarkerPosition(uint32_t marker)
@@ -766,6 +768,10 @@ status_t AudioTrack::setMarkerPosition(uint32_t marker)
    mMarkerPosition = marker;
    mMarkerReached = false;

    sp<AudioTrackThread> t = mAudioTrackThread;
    if (t != 0) {
        t->wake();
    }
    return NO_ERROR;
}

@@ -795,6 +801,10 @@ status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod)
    mNewPosition = updateAndGetPosition_l() + updatePeriod;
    mUpdatePeriod = updatePeriod;

    sp<AudioTrackThread> t = mAudioTrackThread;
    if (t != 0) {
        t->wake();
    }
    return NO_ERROR;
}

@@ -835,6 +845,8 @@ status_t AudioTrack::setPosition(uint32_t position)
    // After setting the position, use full update period before notification.
    mNewPosition = updateAndGetPosition_l() + mUpdatePeriod;
    mStaticProxy->setBufferPosition(position);

    // Waking the AudioTrackThread is not needed as this cannot be called when active.
    return NO_ERROR;
}

@@ -2181,8 +2193,8 @@ bool AudioTrack::AudioTrackThread::threadLoop()
    case NS_NEVER:
        return false;
    case NS_WHENEVER:
        // FIXME increase poll interval, or make event-driven
        ns = 1000000000LL;
        // Event driven: call wake() when callback notifications conditions change.
        ns = INT64_MAX;
        // fall through
    default:
        LOG_ALWAYS_FATAL_IF(ns < 0, "processAudioBuffer() returned %" PRId64, ns);
@@ -2215,6 +2227,17 @@ void AudioTrack::AudioTrackThread::resume()
    }
}

void AudioTrack::AudioTrackThread::wake()
{
    AutoMutex _l(mMyLock);
    if (!mPaused && mPausedInt && mPausedNs > 0) {
        // audio track is active and internally paused with timeout.
        mIgnoreNextPausedInt = true;
        mPausedInt = false;
        mMyCond.signal();
    }
}

void AudioTrack::AudioTrackThread::pauseInternal(nsecs_t ns)
{
    AutoMutex _l(mMyLock);
+13 −1
Original line number Diff line number Diff line
@@ -21,6 +21,12 @@ destructor [label="~AudioTrack()"];
destructor -> requestExit;
requestExit [label="AudioTrackThread::requestExit()"];
requestExit -> resume;
Application -> ATsetMarkerPosition
ATsetMarkerPosition [label="AudioTrack::setMarkerPosition()\n[sets marker variables]"];
ATsetMarkerPosition -> ATTwake
Application -> ATsetPositionUpdatePeriod
ATsetPositionUpdatePeriod [label="AudioTrack::setPositionUpdatePeriod()\n[sets update period variables]"];
ATsetPositionUpdatePeriod -> ATTwake
Application -> ATstart;

resume [label="AudioTrackThread::resume()"];
@@ -29,6 +35,12 @@ resume -> resume_body;
resume_body -> resume_paused [label="true"];
resume_body -> resume_merged [label="false"];

ATTwake [label="AudioTrackThread::wake()\nif (!mPaused && mPausedInt && mPausedNs > 0)"];
ATTwake-> ATTWake_wakeable [label="true"];
ATTWake_wakeable [label="mIgnoreNextPausedInt = true\nmPausedInt = false\nsignal()"];
ATTwake-> ATTWake_cannotwake [label="false"]
ATTWake_cannotwake [label="ignore"];

pause [label="mPaused = true"];
pause -> return;

@@ -63,7 +75,7 @@ threadLoop_6_default [label="if (ns < 0)"];
threadLoop_6_default -> threadLoop_6_default_true [label="true"];
threadLoop_6_default -> threadLoop_6_default_false [label="false"];
threadLoop_6_default_true [label="FATAL"];
threadLoop_6_default_false [label="pauseInternal(ns)\nmPausedInternal = true\nmPausedNs = ns\nreturn true"];
threadLoop_6_default_false [label="pauseInternal(ns) [wake()-able]\nmPausedInternal = true\nmPausedNs = ns\nreturn true"];
threadLoop_6_0 [label="return true"];
threadLoop_6_NS_INACTIVE [label="pauseInternal()\nmPausedInternal = true\nmPausedNs = 0\nreturn true"];
threadLoop_6_NS_NEVER [label="return false"];