Merge "AudioFlinger: mix track only when really ready (2)" into ics-mr1

This commit is contained in:
Eric Laurent
2012-01-18 16:05:31 -08:00
committed by Android (Google) Code Review
2 changed files with 21 additions and 6 deletions

View File

@@ -1832,7 +1832,7 @@ uint32_t AudioFlinger::PlaybackThread::activeSleepTimeUs()
AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device) AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
: PlaybackThread(audioFlinger, output, id, device), : PlaybackThread(audioFlinger, output, id, device),
mAudioMixer(0) mAudioMixer(0), mPrevMixerStatus(MIXER_IDLE)
{ {
mType = ThreadBase::MIXER; mType = ThreadBase::MIXER;
mAudioMixer = new AudioMixer(mFrameCount, mSampleRate); mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
@@ -1945,6 +1945,7 @@ bool AudioFlinger::MixerThread::threadLoop()
LOGV("MixerThread %p TID %d waking up\n", this, gettid()); LOGV("MixerThread %p TID %d waking up\n", this, gettid());
acquireWakeLock_l(); acquireWakeLock_l();
mPrevMixerStatus = MIXER_IDLE;
if (mMasterMute == false) { if (mMasterMute == false) {
char value[PROPERTY_VALUE_MAX]; char value[PROPERTY_VALUE_MAX];
property_get("ro.audio.silent", value, "0"); property_get("ro.audio.silent", value, "0");
@@ -2103,11 +2104,11 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
// make sure that we have enough frames to mix one full buffer. // make sure that we have enough frames to mix one full buffer.
// enforce this condition only once to enable draining the buffer in case the client // enforce this condition only once to enable draining the buffer in case the client
// app does not call stop() and relies on underrun to stop: // app does not call stop() and relies on underrun to stop:
// hence the test on (track->mRetryCount >= kMaxTrackRetries) meaning the track was mixed // hence the test on (mPrevMixerStatus == MIXER_TRACKS_READY) meaning the track was mixed
// during last round // during last round
uint32_t minFrames = 1; uint32_t minFrames = 1;
if (!track->isStopped() && !track->isPausing() && if (!track->isStopped() && !track->isPausing() &&
(track->mRetryCount >= kMaxTrackRetries)) { (mPrevMixerStatus == MIXER_TRACKS_READY)) {
if (t->sampleRate() == (int)mSampleRate) { if (t->sampleRate() == (int)mSampleRate) {
minFrames = mFrameCount; minFrames = mFrameCount;
} else { } else {
@@ -2229,7 +2230,13 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
// reset retry count // reset retry count
track->mRetryCount = kMaxTrackRetries; track->mRetryCount = kMaxTrackRetries;
mixerStatus = MIXER_TRACKS_READY; // If one track is ready, set the mixer ready if:
// - the mixer was not ready during previous round OR
// - no other track is not ready
if (mPrevMixerStatus != MIXER_TRACKS_READY ||
mixerStatus != MIXER_TRACKS_ENABLED) {
mixerStatus = MIXER_TRACKS_READY;
}
} else { } else {
//LOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", track->name(), cblk->user, cblk->server, this); //LOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", track->name(), cblk->user, cblk->server, this);
if (track->isStopped()) { if (track->isStopped()) {
@@ -2247,7 +2254,11 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
tracksToRemove->add(track); tracksToRemove->add(track);
// indicate to client process that the track was disabled because of underrun // indicate to client process that the track was disabled because of underrun
android_atomic_or(CBLK_DISABLED_ON, &cblk->flags); android_atomic_or(CBLK_DISABLED_ON, &cblk->flags);
} else if (mixerStatus != MIXER_TRACKS_READY) { // If one track is not ready, mark the mixer also not ready if:
// - the mixer was ready during previous round OR
// - no other track is ready
} else if (mPrevMixerStatus == MIXER_TRACKS_READY ||
mixerStatus != MIXER_TRACKS_READY) {
mixerStatus = MIXER_TRACKS_ENABLED; mixerStatus = MIXER_TRACKS_ENABLED;
} }
} }
@@ -2281,6 +2292,7 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
memset(mMixBuffer, 0, mFrameCount * mChannelCount * sizeof(int16_t)); memset(mMixBuffer, 0, mFrameCount * mChannelCount * sizeof(int16_t));
} }
mPrevMixerStatus = mixerStatus;
return mixerStatus; return mixerStatus;
} }
@@ -3016,6 +3028,7 @@ bool AudioFlinger::DuplicatingThread::threadLoop()
LOGV("DuplicatingThread %p TID %d waking up\n", this, gettid()); LOGV("DuplicatingThread %p TID %d waking up\n", this, gettid());
acquireWakeLock_l(); acquireWakeLock_l();
mPrevMixerStatus = MIXER_IDLE;
if (mMasterMute == false) { if (mMasterMute == false) {
char value[PROPERTY_VALUE_MAX]; char value[PROPERTY_VALUE_MAX];
property_get("ro.audio.silent", value, "0"); property_get("ro.audio.silent", value, "0");

View File

@@ -836,7 +836,9 @@ private:
virtual uint32_t idleSleepTimeUs(); virtual uint32_t idleSleepTimeUs();
virtual uint32_t suspendSleepTimeUs(); virtual uint32_t suspendSleepTimeUs();
AudioMixer* mAudioMixer; AudioMixer* mAudioMixer;
uint32_t mPrevMixerStatus; // previous status (mixer_state) returned by
// prepareTracks_l()
}; };
class DirectOutputThread : public PlaybackThread { class DirectOutputThread : public PlaybackThread {