Merge "AudioFlinger: mix track only when really ready (2)" into ics-mr1
This commit is contained in:
@@ -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");
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user