AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device)
: PlaybackThread(audioFlinger, output, id, device),
- mAudioMixer(0)
+ mAudioMixer(0), mPrevMixerStatus(MIXER_IDLE)
{
mType = ThreadBase::MIXER;
mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
LOGV("MixerThread %p TID %d waking up\n", this, gettid());
acquireWakeLock_l();
+ mPrevMixerStatus = MIXER_IDLE;
if (mMasterMute == false) {
char value[PROPERTY_VALUE_MAX];
property_get("ro.audio.silent", value, "0");
// 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
// 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
uint32_t minFrames = 1;
if (!track->isStopped() && !track->isPausing() &&
- (track->mRetryCount >= kMaxTrackRetries)) {
+ (mPrevMixerStatus == MIXER_TRACKS_READY)) {
if (t->sampleRate() == (int)mSampleRate) {
minFrames = mFrameCount;
} else {
// reset retry count
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 {
//LOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", track->name(), cblk->user, cblk->server, this);
if (track->isStopped()) {
tracksToRemove->add(track);
// indicate to client process that the track was disabled because of underrun
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;
}
}
memset(mMixBuffer, 0, mFrameCount * mChannelCount * sizeof(int16_t));
}
+ mPrevMixerStatus = mixerStatus;
return mixerStatus;
}
LOGV("DuplicatingThread %p TID %d waking up\n", this, gettid());
acquireWakeLock_l();
+ mPrevMixerStatus = MIXER_IDLE;
if (mMasterMute == false) {
char value[PROPERTY_VALUE_MAX];
property_get("ro.audio.silent", value, "0");