AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, audio_devices_t outDevice, audio_devices_t inDevice, type_t type) : Thread(false /*canCallJava*/), mType(type), mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mNormalFrameCount(0), // mChannelMask mChannelCount(0), mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID), mParamStatus(NO_ERROR), mStandby(false), mOutDevice(outDevice), mInDevice(inDevice), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id), // mName will be set by concrete (non-virtual) subclass mDeathRecipient(new PMDeathRecipient(this)) { } AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device, type_t type) : ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type), mMixBuffer(NULL), mSuspended(0), mBytesWritten(0), // mStreamTypes[] initialized in constructor body mOutput(output), mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false), mMixerStatus(MIXER_IDLE), mMixerStatusIgnoringFastTracks(MIXER_IDLE), standbyDelay(AudioFlinger::mStandbyTimeInNsecs), mScreenState(AudioFlinger::mScreenState), // index 0 is reserved for normal mixer's submix // 初始值为1111 1110 mFastTrackAvailMask(((1 << FastMixerState::kMaxFastTracks) - 1) & ~1) { snprintf(mName, kNameLength, "AudioOut_%X", id); mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mName); // Assumes constructor is called by AudioFlinger with it's mLock held, but // it would be safer to explicitly pass initial masterVolume/masterMute as // parameter. // // If the HAL we are using has support for master volume or master mute, // then do not attenuate or mute during mixing (just leave the volume at 1.0 // and the mute set to false). mMasterVolume = audioFlinger->masterVolume_l(); mMasterMute = audioFlinger->masterMute_l(); if (mOutput && mOutput->audioHwDev) { if (mOutput->audioHwDev->canSetMasterVolume()) { mMasterVolume = 1.0; } if (mOutput->audioHwDev->canSetMasterMute()) { mMasterMute = false; } } // 负责读取硬件的各类参数 readOutputParameters(); // mStreamTypes[AUDIO_STREAM_CNT] is initialized by stream_type_t default constructor // There is no AUDIO_STREAM_MIN, and ++ operator does not compile for (audio_stream_type_t stream = (audio_stream_type_t) 0; stream < AUDIO_STREAM_CNT; stream = (audio_stream_type_t) (stream + 1)) { mStreamTypes[stream].volume = mAudioFlinger->streamVolume_l(stream); mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream); } // mStreamTypes[AUDIO_STREAM_CNT] exists but isn't explicitly initialized here, // because mAudioFlinger doesn't have one to copy from } //通过输出接口获得Hal层支持的采样率、声道数、采样精度、每帧大小、缓冲区包含的帧数、mix缓冲区大小 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 = 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; // 缓冲区包含的帧数必须是16的倍数 if (mFrameCount & 15) { ALOGW("HAL output buffer size is %u frames but AudioMixer requires multiples of 16 frames", mFrameCount); } // 如果该输出模块支持非阻塞模式,设置异步回调函数asyncCallback,并创建回调线程 // AsyncCallbackThread,具体作用还需要分析 if ((mOutput->flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING) && (mOutput->stream->set_callback != NULL)) { if (mOutput->stream->set_callback(mOutput->stream, AudioFlinger::PlaybackThread::asyncCallback, this) == 0) { mUseAsyncWrite = true; mCallbackThread = new AudioFlinger::AsyncCallbackThread(this); } } // Calculate size of normal mix buffer relative to the HAL output buffer size // 根据物理缓冲区的大小计算normal mix buffer的大小>= 物理缓冲区 double multiplier = 1.0; if (mType == MIXER && (kUseFastMixer == FastMixer_Static || kUseFastMixer == FastMixer_Dynamic)) { size_t minNormalFrameCount = (kMinNormalMixBufferSizeMs * mSampleRate) / 1000; size_t maxNormalFrameCount = (kMaxNormalMixBufferSizeMs * mSampleRate) / 1000; // round up minimum and round down maximum to nearest 16 frames to satisfy AudioMixer minNormalFrameCount = (minNormalFrameCount + 15) & ~15; maxNormalFrameCount = maxNormalFrameCount & ~15; if (maxNormalFrameCount < minNormalFrameCount) { maxNormalFrameCount = minNormalFrameCount; } multiplier = (double) minNormalFrameCount / (double) mFrameCount; if (multiplier <= 1.0) { multiplier = 1.0; } else if (multiplier <= 2.0) { if (2 * mFrameCount <= maxNormalFrameCount) { multiplier = 2.0; } else { multiplier = (double) maxNormalFrameCount / (double) mFrameCount; } } else { // prefer an even multiplier, for compatibility with doubling of fast tracks due to HAL // SRC (it would be unusual for the normal mix buffer size to not be a multiple of fast // track, but we sometimes have to do this to satisfy the maximum frame count // constraint) // FIXME this rounding up should not be done if no HAL SRC uint32_t truncMult = (uint32_t) multiplier; if ((truncMult & 1)) { if ((truncMult + 1) * mFrameCount <= maxNormalFrameCount) { ++truncMult; } } multiplier = (double) truncMult; } } mNormalFrameCount = multiplier * mFrameCount; // round up to nearest 16 frames to satisfy AudioMixer mNormalFrameCount = (mNormalFrameCount + 15) & ~15; ALOGI("HAL output buffer size %u frames, normal mix buffer size %u frames", mFrameCount, mNormalFrameCount); delete[] mAllocMixBuffer; size_t align = (mFrameSize < sizeof(int16_t)) ? sizeof(int16_t) : mFrameSize; mAllocMixBuffer = new int8_t[mNormalFrameCount * mFrameSize + align - 1]; mMixBuffer = (int16_t *) ((((size_t)mAllocMixBuffer + align - 1) / align) * align); memset(mMixBuffer, 0, mNormalFrameCount * mFrameSize); // force reconfiguration of effect chains and engines to take new buffer size and audio // parameters into account // Note that mLock is not held when readOutputParameters() is called from the constructor // but in this case nothing is done below as no audio sessions have effect yet so it doesn't // matter. // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains Vector< sp<EffectChain> > effectChains = mEffectChains; for (size_t i = 0; i < effectChains.size(); i ++) { mAudioFlinger->moveEffectChain_l(effectChains[i]->sessionId(), this, this, false); } } // ---------------------------------------------------------------------------- // AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, audio_devices_t device, type_t type) : PlaybackThread(audioFlinger, output, id, device, type), // mAudioMixer below // mFastMixer below mFastMixerFutex(0) // mOutputSink below // mPipeSink below // mNormalSink below { ALOGV("MixerThread() id=%d device=%#x type=%d", id, device, type); ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%d, mFormat=%d, mFrameSize=%u, " "mFrameCount=%d, mNormalFrameCount=%d", mSampleRate, mChannelMask, mChannelCount, mFormat, mFrameSize, mFrameCount, mNormalFrameCount); //构造AudioMixer对象,负责mix norm tracks mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate); // FIXME - Current mixer implementation only supports stereo output if (mChannelCount != FCC_2) { ALOGE("Invalid audio hardware channel count %d", mChannelCount); } // create an NBAIO sink for the HAL output stream, and negotiate // 通过输出流构造一个StreamOutSink对象,负责将数据写入到Hal中。 mOutputSink = new AudioStreamOutSink(output->stream); size_t numCounterOffers = 0; const NBAIO_Format offers[1] = {Format_from_SR_C(mSampleRate, mChannelCount)}; ssize_t index = mOutputSink->negotiate(offers, 1, NULL, numCounterOffers); ALOG_ASSERT(index == 0); // initialize fast mixer depending on configuration bool initFastMixer; switch (kUseFastMixer) { case FastMixer_Never: initFastMixer = false; break; case FastMixer_Always: initFastMixer = true; break; case FastMixer_Static: case FastMixer_Dynamic: initFastMixer = mFrameCount < mNormalFrameCount; break; } //如果支持FastMixer模式,需要做如下操作: //1、通过获取StreamOutSink的format来构造monoPipe对象,缓冲区大小是AudioMixer的4倍, // 负责获得AudioMixer对象的buffer数据,然后通过该monoPipe对象构造SourceAudioBufferProvider, // 作为FastTrack[0]的输入,由此我们可以知道这个对象名中有pipe(管道)的原因了,即像管道一样传输数据 //2、构造FastMixer对象,初始化FastTrack[0]对象,并开启该线程,进行mix FastTrack处理 // 特别注意,该FastTrack专门关联MixThread的MixBuff,后续作为一路track继续在FastMix中 // 与其它FastTrack进行AudioMix混音处理 //3、构造AudioWatchdog对象,负责监控该线程 if (initFastMixer) { // create a MonoPipe to connect our submix to FastMixer NBAIO_Format format = mOutputSink->format(); // This pipe depth compensates for scheduling latency of the normal mixer thread. // When it wakes up after a maximum latency, it runs a few cycles quickly before // finally blocking. Note the pipe implementation rounds up the request to a power of 2. // MonoPipe *monoPipe = new MonoPipe(mNormalFrameCount * 4, format, true /*writeCanBlock*/); const NBAIO_Format offers[1] = {format}; size_t numCounterOffers = 0; ssize_t index = monoPipe->negotiate(offers, 1, NULL, numCounterOffers); ALOG_ASSERT(index == 0); monoPipe->setAvgFrames((mScreenState & 1) ? (monoPipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2); mPipeSink = monoPipe; #ifdef TEE_SINK if (mTeeSinkOutputEnabled) { // create a Pipe to archive a copy of FastMixer's output for dumpsys Pipe *teeSink = new Pipe(mTeeSinkOutputFrames, format); numCounterOffers = 0; index = teeSink->negotiate(offers, 1, NULL, numCounterOffers); ALOG_ASSERT(index == 0); mTeeSink = teeSink; PipeReader *teeSource = new PipeReader(*teeSink); numCounterOffers = 0; index = teeSource->negotiate(offers, 1, NULL, numCounterOffers); ALOG_ASSERT(index == 0); mTeeSource = teeSource; } #endif // create fast mixer and configure it initially with just one fast track for our submix // 构造FastMixer对象,初始化其中一个FastTrack对象,并开启该线程,进行mix FastTrack处理。 mFastMixer = new FastMixer(); FastMixerStateQueue *sq = mFastMixer->sq(); #ifdef STATE_QUEUE_DUMP sq->setObserverDump(&mStateQueueObserverDump); sq->setMutatorDump(&mStateQueueMutatorDump); #endif FastMixerState *state = sq->begin(); FastTrack *fastTrack = &state->mFastTracks[0]; // wrap the source side of the MonoPipe to make it an AudioBufferProvider // 通过monoPipe来构造一个MonoPipeReader来读取monoPipe的数据,作为FastTrack[0]的输入端提供数据 fastTrack->mBufferProvider = new SourceAudioBufferProvider(new MonoPipeReader(monoPipe)); fastTrack->mVolumeProvider = NULL; fastTrack->mGeneration++; state->mFastTracksGen++; // 设置active track对应的bit位,初始值为0 state->mTrackMask = 1; // fast mixer will use the HAL output sink // 使用AudioStreamOutSink来作为输出端,经过fast mixer处理过的数据将会提供给outputSink,最终写入到Hal中 state->mOutputSink = mOutputSink.get(); state->mOutputSinkGen++; state->mFrameCount = mFrameCount; state->mCommand = FastMixerState::COLD_IDLE; // already done in constructor initialization list //mFastMixerFutex = 0; state->mColdFutexAddr = &mFastMixerFutex; state->mColdGen++; state->mDumpState = &mFastMixerDumpState; #ifdef TEE_SINK state->mTeeSink = mTeeSink.get(); #endif mFastMixerNBLogWriter = audioFlinger->newWriter_l(kFastMixerLogSize, "FastMixer"); state->mNBLogWriter = mFastMixerNBLogWriter.get(); sq->end(); sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED); // start the fast mixer mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO); pid_t tid = mFastMixer->getTid(); int err = requestPriority(getpid_cached, tid, kPriorityFastMixer); if (err != 0) { ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d", kPriorityFastMixer, getpid_cached, tid, err); } #ifdef AUDIO_WATCHDOG // create and start the watchdog mAudioWatchdog = new AudioWatchdog(); mAudioWatchdog->setDump(&mAudioWatchdogDump); mAudioWatchdog->run("AudioWatchdog", PRIORITY_URGENT_AUDIO); tid = mAudioWatchdog->getTid(); err = requestPriority(getpid_cached, tid, kPriorityFastMixer); if (err != 0) { ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d", kPriorityFastMixer, getpid_cached, tid, err); } #endif } else { mFastMixer = NULL; } //根据FastMixer的模式,设置当前的MixerThread的输出端 //1、never时,始终将mix之后的数据输出到Hal //2、dynamic时,将mix之后的数据输出到Hal,但是已经初始化FastMixer对象,后续可以使用 //2、always时,将mix之后的数据通过pipe输出到FastMixer,作为FastMixer的输入 //3、static时,判断是Mix buff是否大于Hal buff,如果大于则使用pip将数据输出到FastMixer, // 否则将mix后的数据输出到Hal switch (kUseFastMixer) { case FastMixer_Never: case FastMixer_Dynamic: mNormalSink = mOutputSink; break; case FastMixer_Always: mNormalSink = mPipeSink; break; case FastMixer_Static: mNormalSink = initFastMixer ? mPipeSink : mOutputSink; break; } }