summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/FastMixer.cpp
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2013-02-13 14:46:45 -0800
committerGlenn Kasten <gkasten@google.com>2013-02-14 14:35:29 -0800
commit639482c24c911b125398b31883ba6d55faebe28b (patch)
tree698e25baf47d4e6a10663d21ca86c3a0702fe606 /services/audioflinger/FastMixer.cpp
parent085205bd23c3604c1b792c3046fdae0a489c04be (diff)
downloadframeworks_av-639482c24c911b125398b31883ba6d55faebe28b.zip
frameworks_av-639482c24c911b125398b31883ba6d55faebe28b.tar.gz
frameworks_av-639482c24c911b125398b31883ba6d55faebe28b.tar.bz2
Temporary additional logging to investigate bug
The bug appears related to continuing to use an invalid buffer provider in fast mixer after track destruction, so focus the added logs in that area. Also includes a bug fix: was calling log in an unsafe place near Threads.cpp AudioFlinger::PlaybackThread::createTrack_l line 1250. Details: - include caller pid or client pid where appropriate - increase log buffer size - log mFastIndex when AudioMixer sees an invalid bufferProvider. - log both potentially modified and actually modified tracks in FastMixer. - fix benign bug where sq->end() was called more than once. - log StateQueue push() call and return. - increase StateQueue size from 4 to 8 entries - log mixer->enable(), bufferProvider, and currentTrackMask - log buffer provider addresses - increase fast mixer log buffer again - check logf format vs. argument list compatibility - add logging to AudioMixer - add checking of magic field in AudioMixer to detect overwrites - add bool AudioMixer::enabled() Bug: 6490974 Change-Id: I1f3f18aa62d9fbd35bc32285b669f5ba40efe28e
Diffstat (limited to 'services/audioflinger/FastMixer.cpp')
-rw-r--r--services/audioflinger/FastMixer.cpp45
1 files changed, 43 insertions, 2 deletions
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 80e37ca..5811771 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -120,12 +120,16 @@ bool FastMixer::threadLoop()
FastMixerState::Command command = next->mCommand;
if (next != current) {
+ logWriter->logTimestamp();
logWriter->log("next != current");
// As soon as possible of learning of a new dump area, start using it
dumpState = next->mDumpState != NULL ? next->mDumpState : &dummyDumpState;
teeSink = next->mTeeSink;
logWriter = next->mNBLogWriter != NULL ? next->mNBLogWriter : &dummyLogWriter;
+ if (mixer != NULL) {
+ mixer->setLog(logWriter);
+ }
// We want to always have a valid reference to the previous (non-idle) state.
// However, the state queue only guarantees access to current and previous states.
@@ -300,13 +304,21 @@ bool FastMixer::threadLoop()
addedTracks &= ~(1 << i);
const FastTrack* fastTrack = &current->mFastTracks[i];
AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
+ logWriter->logf("bp %d i=%d %p", __LINE__, i, bufferProvider);
ALOG_ASSERT(bufferProvider != NULL && fastTrackNames[i] == -1);
+ if (bufferProvider == NULL ||
+ bufferProvider->getValid() != AudioBufferProvider::kValid) {
+ logWriter->logTimestamp();
+ logWriter->logf("added invalid %#x", i);
+ }
if (mixer != NULL) {
// calling getTrackName with default channel mask and a random invalid
// sessionId (no effects here)
name = mixer->getTrackName(AUDIO_CHANNEL_OUT_STEREO, -555);
ALOG_ASSERT(name >= 0);
fastTrackNames[i] = name;
+ mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FAST_INDEX,
+ (void *) i);
mixer->setBufferProvider(name, bufferProvider);
mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
(void *) mixBuffer);
@@ -317,27 +329,40 @@ bool FastMixer::threadLoop()
}
mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
(void *) fastTrack->mChannelMask);
+ if (!mixer->enabled(name)) {
+ logWriter->logf("enable %d i=%d name=%d", __LINE__, i, name);
+ }
mixer->enable(name);
}
generations[i] = fastTrack->mGeneration;
}
- // finally process modified tracks; these use the same slot
+ // finally process (potentially) modified tracks; these use the same slot
// but may have a different buffer provider or volume provider
unsigned modifiedTracks = currentTrackMask & previousTrackMask;
if (modifiedTracks) {
- logWriter->logf("modified %#x", modifiedTracks);
+ logWriter->logf("pot. mod. %#x", modifiedTracks);
}
+ unsigned actuallyModifiedTracks = 0;
while (modifiedTracks != 0) {
i = __builtin_ctz(modifiedTracks);
modifiedTracks &= ~(1 << i);
const FastTrack* fastTrack = &current->mFastTracks[i];
if (fastTrack->mGeneration != generations[i]) {
+ actuallyModifiedTracks |= 1 << i;
AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
+ logWriter->logf("bp %d i=%d %p", __LINE__, i, bufferProvider);
ALOG_ASSERT(bufferProvider != NULL);
+ if (bufferProvider == NULL ||
+ bufferProvider->getValid() != AudioBufferProvider::kValid) {
+ logWriter->logTimestamp();
+ logWriter->logf("modified invalid %#x", i);
+ }
if (mixer != NULL) {
name = fastTrackNames[i];
ALOG_ASSERT(name >= 0);
+ mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FAST_INDEX,
+ (void *) i);
mixer->setBufferProvider(name, bufferProvider);
if (fastTrack->mVolumeProvider == NULL) {
mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0,
@@ -360,6 +385,9 @@ bool FastMixer::threadLoop()
generations[i] = fastTrack->mGeneration;
}
}
+ if (actuallyModifiedTracks) {
+ logWriter->logf("act. mod. %#x", actuallyModifiedTracks);
+ }
fastTracksGen = current->mFastTracksGen;
@@ -377,6 +405,7 @@ bool FastMixer::threadLoop()
ALOG_ASSERT(mixBuffer != NULL);
// for each track, update volume and check for underrun
unsigned currentTrackMask = current->mTrackMask;
+ logWriter->logf("ctm %#x", currentTrackMask);
while (currentTrackMask != 0) {
i = __builtin_ctz(currentTrackMask);
currentTrackMask &= ~(1 << i);
@@ -414,15 +443,27 @@ bool FastMixer::threadLoop()
// allow mixing partial buffer
underruns.mBitFields.mPartial++;
underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL;
+ if (!mixer->enabled(name)) {
+ logWriter->logf("enable %d i=%d name=%d", __LINE__, i, name);
+ }
mixer->enable(name);
}
} else {
underruns.mBitFields.mFull++;
underruns.mBitFields.mMostRecent = UNDERRUN_FULL;
+ if (!mixer->enabled(name)) {
+ logWriter->logf("enable %d i=%d name=%d", __LINE__, i, name);
+ }
mixer->enable(name);
}
ftDump->mUnderruns = underruns;
ftDump->mFramesReady = framesReady;
+ AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider;
+ if (bufferProvider == NULL ||
+ bufferProvider->getValid() != AudioBufferProvider::kValid) {
+ logWriter->logTimestamp();
+ logWriter->logf("mixing invalid %#x", i);
+ }
}
int64_t pts;