http://blog.csdn.net/u010681466/article/details/40263915
- 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;
- }
- }