From 7fc97ba08e2850f3f16db704b78ce78e3dbe1ff0 Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Tue, 16 Jul 2013 17:18:58 -0700 Subject: HAL stream format for mixer output threads must be stereo 16-bit PCM Direct and tunnel output threads can support various HAL stream formats, included encoded. But currently there are stereo 16-bit PCM assumptions in several places for mixer and duplicating output threads: - mMixBuffer and mixBuffer() - AudioMixer including resampler - FastMixer's mixBuffer - effects - NBAIO_Format - anywhere FCC_2 is used - possibly other places Until those assumptions are removed, this CL enforces stereo 16-bit PCM in mixer and duplicating threads at the place where the HAL format is read. It was already being checked in checkForNewParameters_l(), but not in readOutputParameters(). Change-Id: Ibe344cc922743da234299097aa1bb1f54795cc9b --- services/audioflinger/FastMixer.cpp | 8 +++++--- services/audioflinger/Threads.cpp | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'services/audioflinger') diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp index 5350e2c..ad9f4f2 100644 --- a/services/audioflinger/FastMixer.cpp +++ b/services/audioflinger/FastMixer.cpp @@ -45,6 +45,8 @@ #define MIN_WARMUP_CYCLES 2 // minimum number of loop cycles to wait for warmup #define MAX_WARMUP_CYCLES 10 // maximum number of loop cycles to wait for warmup +#define FCC_2 2 // fixed channel count assumption + namespace android { // Fast mixer thread @@ -225,7 +227,7 @@ bool FastMixer::threadLoop() } else { format = outputSink->format(); sampleRate = Format_sampleRate(format); - ALOG_ASSERT(Format_channelCount(format) == 2); + ALOG_ASSERT(Format_channelCount(format) == FCC_2); } dumpState->mSampleRate = sampleRate; } @@ -241,7 +243,7 @@ bool FastMixer::threadLoop() // implementation; it would be better to have normal mixer allocate for us // to avoid blocking here and to prevent possible priority inversion mixer = new AudioMixer(frameCount, sampleRate, FastMixerState::kMaxFastTracks); - mixBuffer = new short[frameCount * 2]; + mixBuffer = new short[frameCount * FCC_2]; periodNs = (frameCount * 1000000000LL) / sampleRate; // 1.00 underrunNs = (frameCount * 1750000000LL) / sampleRate; // 1.75 overrunNs = (frameCount * 500000000LL) / sampleRate; // 0.50 @@ -438,7 +440,7 @@ bool FastMixer::threadLoop() //bool didFullWrite = false; // dumpsys could display a count of partial writes if ((command & FastMixerState::WRITE) && (outputSink != NULL) && (mixBuffer != NULL)) { if (mixBufferState == UNDEFINED) { - memset(mixBuffer, 0, frameCount * 2 * sizeof(short)); + memset(mixBuffer, 0, frameCount * FCC_2 * sizeof(short)); mixBufferState = ZEROED; } if (teeSink != NULL) { diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index f27d908..0928923 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -1430,10 +1430,25 @@ void AudioFlinger::PlaybackThread::audioConfigChanged_l(int event, int param) { void AudioFlinger::PlaybackThread::readOutputParameters() { + // unfortunately we have no way of recovering from errors here, hence the LOG_FATAL mSampleRate = mOutput->stream->common.get_sample_rate(&mOutput->stream->common); mChannelMask = mOutput->stream->common.get_channels(&mOutput->stream->common); + if (!audio_is_output_channel(mChannelMask)) { + LOG_FATAL("HAL channel mask %#x not valid for output", mChannelMask); + } + if ((mType == MIXER || mType == DUPLICATING) && mChannelMask != AUDIO_CHANNEL_OUT_STEREO) { + LOG_FATAL("HAL channel mask %#x not supported for mixed output; " + "must be AUDIO_CHANNEL_OUT_STEREO", mChannelMask); + } mChannelCount = (uint16_t)popcount(mChannelMask); mFormat = mOutput->stream->common.get_format(&mOutput->stream->common); + if (!audio_is_valid_format(mFormat)) { + LOG_FATAL("HAL format %d not valid for output", mFormat); + } + if ((mType == MIXER || mType == DUPLICATING) && mFormat != AUDIO_FORMAT_PCM_16_BIT) { + LOG_FATAL("HAL format %d not supported for mixed output; must be AUDIO_FORMAT_PCM_16_BIT", + mFormat); + } mFrameSize = audio_stream_frame_size(&mOutput->stream->common); mFrameCount = mOutput->stream->common.get_buffer_size(&mOutput->stream->common) / mFrameSize; if (mFrameCount & 15) { -- cgit v1.1