OSDN Git Service

HAL stream format for mixer output threads must be stereo 16-bit PCM
authorGlenn Kasten <gkasten@google.com>
Wed, 17 Jul 2013 00:18:58 +0000 (17:18 -0700)
committerGlenn Kasten <gkasten@google.com>
Thu, 25 Jul 2013 19:22:18 +0000 (12:22 -0700)
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
services/audioflinger/Threads.cpp

index 5350e2c..ad9f4f2 100644 (file)
@@ -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) {
index f27d908..0928923 100644 (file)
@@ -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) {