summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/AudioTrack.h5
-rw-r--r--media/libmedia/AudioTrack.cpp27
-rw-r--r--media/libmedia/docs/paused.dot14
3 files changed, 42 insertions, 4 deletions
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index c995bd2..d602ee4 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -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()
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index ea7b2df..ca36143 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -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);
diff --git a/media/libmedia/docs/paused.dot b/media/libmedia/docs/paused.dot
index 8856647..11e1777 100644
--- a/media/libmedia/docs/paused.dot
+++ b/media/libmedia/docs/paused.dot
@@ -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"];