关闭

Audio笔记之MixerThread

101人阅读 评论(0) 收藏 举报
分类:

http://blog.csdn.net/u010681466/article/details/40263915

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id,  
  2.         audio_devices_t outDevice, audio_devices_t inDevice, type_t type)  
  3.     :   Thread(false /*canCallJava*/),  
  4.         mType(type),  
  5.         mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mNormalFrameCount(0),  
  6.         // mChannelMask  
  7.         mChannelCount(0),  
  8.         mFrameSize(1), mFormat(AUDIO_FORMAT_INVALID),  
  9.         mParamStatus(NO_ERROR),  
  10.         mStandby(false), mOutDevice(outDevice), mInDevice(inDevice),  
  11.         mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),  
  12.         // mName will be set by concrete (non-virtual) subclass  
  13.         mDeathRecipient(new PMDeathRecipient(this))  
  14. {  
  15. }  
  16.   
  17. AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,  
  18.                                              AudioStreamOut* output,  
  19.                                              audio_io_handle_t id,  
  20.                                              audio_devices_t device,  
  21.                                              type_t type)  
  22.     :   ThreadBase(audioFlinger, id, device, AUDIO_DEVICE_NONE, type),  
  23.         mMixBuffer(NULL), mSuspended(0), mBytesWritten(0),  
  24.         // mStreamTypes[] initialized in constructor body  
  25.         mOutput(output),  
  26.         mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false),  
  27.         mMixerStatus(MIXER_IDLE),  
  28.         mMixerStatusIgnoringFastTracks(MIXER_IDLE),  
  29.         standbyDelay(AudioFlinger::mStandbyTimeInNsecs),  
  30.         mScreenState(AudioFlinger::mScreenState),  
  31.         // index 0 is reserved for normal mixer's submix  
  32.         // 初始值为1111 1110  
  33.         mFastTrackAvailMask(((1 << FastMixerState::kMaxFastTracks) - 1) & ~1)  
  34. {  
  35.     snprintf(mName, kNameLength, "AudioOut_%X", id);  
  36.     mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mName);  
  37.   
  38.     // Assumes constructor is called by AudioFlinger with it's mLock held, but  
  39.     // it would be safer to explicitly pass initial masterVolume/masterMute as  
  40.     // parameter.  
  41.     //  
  42.     // If the HAL we are using has support for master volume or master mute,  
  43.     // then do not attenuate or mute during mixing (just leave the volume at 1.0  
  44.     // and the mute set to false).  
  45.     mMasterVolume = audioFlinger->masterVolume_l();  
  46.     mMasterMute = audioFlinger->masterMute_l();  
  47.     if (mOutput && mOutput->audioHwDev) {  
  48.         if (mOutput->audioHwDev->canSetMasterVolume()) {  
  49.             mMasterVolume = 1.0;  
  50.         }  
  51.   
  52.         if (mOutput->audioHwDev->canSetMasterMute()) {  
  53.             mMasterMute = false;  
  54.         }  
  55.     }  
  56.     // 负责读取硬件的各类参数  
  57.     readOutputParameters();  
  58.   
  59.     // mStreamTypes[AUDIO_STREAM_CNT] is initialized by stream_type_t default constructor  
  60.     // There is no AUDIO_STREAM_MIN, and ++ operator does not compile  
  61.     for (audio_stream_type_t stream = (audio_stream_type_t) 0; stream < AUDIO_STREAM_CNT;  
  62.             stream = (audio_stream_type_t) (stream + 1)) {  
  63.         mStreamTypes[stream].volume = mAudioFlinger->streamVolume_l(stream);  
  64.         mStreamTypes[stream].mute = mAudioFlinger->streamMute_l(stream);  
  65.     }  
  66.     // mStreamTypes[AUDIO_STREAM_CNT] exists but isn't explicitly initialized here,  
  67.     // because mAudioFlinger doesn't have one to copy from  
  68. }  
  69.   
  70. //通过输出接口获得Hal层支持的采样率、声道数、采样精度、每帧大小、缓冲区包含的帧数、mix缓冲区大小  
  71. void AudioFlinger::PlaybackThread::readOutputParameters()  
  72. {  
  73.     // unfortunately we have no way of recovering from errors here, hence the LOG_FATAL  
  74.     mSampleRate = mOutput->stream->common.get_sample_rate(&mOutput->stream->common);  
  75.     mChannelMask = mOutput->stream->common.get_channels(&mOutput->stream->common);  
  76.     if (!audio_is_output_channel(mChannelMask)) {  
  77.         LOG_FATAL("HAL channel mask %#x not valid for output", mChannelMask);  
  78.     }  
  79.     if ((mType == MIXER || mType == DUPLICATING) && mChannelMask != AUDIO_CHANNEL_OUT_STEREO) {  
  80.         LOG_FATAL("HAL channel mask %#x not supported for mixed output; "  
  81.                 "must be AUDIO_CHANNEL_OUT_STEREO", mChannelMask);  
  82.     }  
  83.     mChannelCount = popcount(mChannelMask);  
  84.     mFormat = mOutput->stream->common.get_format(&mOutput->stream->common);  
  85.     if (!audio_is_valid_format(mFormat)) {  
  86.         LOG_FATAL("HAL format %d not valid for output", mFormat);  
  87.     }  
  88.     if ((mType == MIXER || mType == DUPLICATING) && mFormat != AUDIO_FORMAT_PCM_16_BIT) {  
  89.         LOG_FATAL("HAL format %d not supported for mixed output; must be AUDIO_FORMAT_PCM_16_BIT",  
  90.                 mFormat);  
  91.     }  
  92.     mFrameSize = audio_stream_frame_size(&mOutput->stream->common);  
  93.     mFrameCount = mOutput->stream->common.get_buffer_size(&mOutput->stream->common) / mFrameSize;  
  94.     // 缓冲区包含的帧数必须是16的倍数  
  95.     if (mFrameCount & 15) {  
  96.         ALOGW("HAL output buffer size is %u frames but AudioMixer requires multiples of 16 frames",  
  97.                 mFrameCount);  
  98.     }  
  99.     // 如果该输出模块支持非阻塞模式,设置异步回调函数asyncCallback,并创建回调线程  
  100.     // AsyncCallbackThread,具体作用还需要分析  
  101.     if ((mOutput->flags & AUDIO_OUTPUT_FLAG_NON_BLOCKING) &&  
  102.             (mOutput->stream->set_callback != NULL)) {  
  103.         if (mOutput->stream->set_callback(mOutput->stream,  
  104.                                       AudioFlinger::PlaybackThread::asyncCallback, this) == 0) {  
  105.             mUseAsyncWrite = true;  
  106.             mCallbackThread = new AudioFlinger::AsyncCallbackThread(this);  
  107.         }  
  108.     }  
  109.   
  110.     // Calculate size of normal mix buffer relative to the HAL output buffer size  
  111.     // 根据物理缓冲区的大小计算normal mix buffer的大小>= 物理缓冲区  
  112.     double multiplier = 1.0;  
  113.     if (mType == MIXER && (kUseFastMixer == FastMixer_Static ||  
  114.             kUseFastMixer == FastMixer_Dynamic)) {  
  115.         size_t minNormalFrameCount = (kMinNormalMixBufferSizeMs * mSampleRate) / 1000;  
  116.         size_t maxNormalFrameCount = (kMaxNormalMixBufferSizeMs * mSampleRate) / 1000;  
  117.         // round up minimum and round down maximum to nearest 16 frames to satisfy AudioMixer  
  118.         minNormalFrameCount = (minNormalFrameCount + 15) & ~15;  
  119.         maxNormalFrameCount = maxNormalFrameCount & ~15;  
  120.         if (maxNormalFrameCount < minNormalFrameCount) {  
  121.             maxNormalFrameCount = minNormalFrameCount;  
  122.         }  
  123.         multiplier = (double) minNormalFrameCount / (double) mFrameCount;  
  124.         if (multiplier <= 1.0) {  
  125.             multiplier = 1.0;  
  126.         } else if (multiplier <= 2.0) {  
  127.             if (2 * mFrameCount <= maxNormalFrameCount) {  
  128.                 multiplier = 2.0;  
  129.             } else {  
  130.                 multiplier = (double) maxNormalFrameCount / (double) mFrameCount;  
  131.             }  
  132.         } else {  
  133.             // prefer an even multiplier, for compatibility with doubling of fast tracks due to HAL  
  134.             // SRC (it would be unusual for the normal mix buffer size to not be a multiple of fast  
  135.             // track, but we sometimes have to do this to satisfy the maximum frame count  
  136.             // constraint)  
  137.             // FIXME this rounding up should not be done if no HAL SRC  
  138.             uint32_t truncMult = (uint32_t) multiplier;  
  139.             if ((truncMult & 1)) {  
  140.                 if ((truncMult + 1) * mFrameCount <= maxNormalFrameCount) {  
  141.                     ++truncMult;  
  142.                 }  
  143.             }  
  144.             multiplier = (double) truncMult;  
  145.         }  
  146.     }  
  147.     mNormalFrameCount = multiplier * mFrameCount;  
  148.     // round up to nearest 16 frames to satisfy AudioMixer  
  149.     mNormalFrameCount = (mNormalFrameCount + 15) & ~15;  
  150.     ALOGI("HAL output buffer size %u frames, normal mix buffer size %u frames", mFrameCount,  
  151.             mNormalFrameCount);  
  152.   
  153.     delete[] mAllocMixBuffer;  
  154.     size_t align = (mFrameSize < sizeof(int16_t)) ? sizeof(int16_t) : mFrameSize;  
  155.     mAllocMixBuffer = new int8_t[mNormalFrameCount * mFrameSize + align - 1];  
  156.     mMixBuffer = (int16_t *) ((((size_t)mAllocMixBuffer + align - 1) / align) * align);  
  157.     memset(mMixBuffer, 0, mNormalFrameCount * mFrameSize);  
  158.   
  159.     // force reconfiguration of effect chains and engines to take new buffer size and audio  
  160.     // parameters into account  
  161.     // Note that mLock is not held when readOutputParameters() is called from the constructor  
  162.     // but in this case nothing is done below as no audio sessions have effect yet so it doesn't  
  163.     // matter.  
  164.     // create a copy of mEffectChains as calling moveEffectChain_l() can reorder some effect chains  
  165.     Vector< sp<EffectChain> > effectChains = mEffectChains;  
  166.     for (size_t i = 0; i < effectChains.size(); i ++) {  
  167.         mAudioFlinger->moveEffectChain_l(effectChains[i]->sessionId(), thisthisfalse);  
  168.     }  
  169. }  
  170.   
  171. // ----------------------------------------------------------------------------  
  172. //  
  173. AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output,  
  174.         audio_io_handle_t id, audio_devices_t device, type_t type)  
  175.     :   PlaybackThread(audioFlinger, output, id, device, type),  
  176.         // mAudioMixer below  
  177.         // mFastMixer below  
  178.         mFastMixerFutex(0)  
  179.         // mOutputSink below  
  180.         // mPipeSink below  
  181.         // mNormalSink below  
  182. {  
  183.     ALOGV("MixerThread() id=%d device=%#x type=%d", id, device, type);  
  184.     ALOGV("mSampleRate=%u, mChannelMask=%#x, mChannelCount=%d, mFormat=%d, mFrameSize=%u, "  
  185.             "mFrameCount=%d, mNormalFrameCount=%d",  
  186.             mSampleRate, mChannelMask, mChannelCount, mFormat, mFrameSize, mFrameCount,  
  187.             mNormalFrameCount);  
  188.     //构造AudioMixer对象,负责mix norm tracks  
  189.     mAudioMixer = new AudioMixer(mNormalFrameCount, mSampleRate);  
  190.   
  191.     // FIXME - Current mixer implementation only supports stereo output  
  192.     if (mChannelCount != FCC_2) {  
  193.         ALOGE("Invalid audio hardware channel count %d", mChannelCount);  
  194.     }  
  195.   
  196.     // create an NBAIO sink for the HAL output stream, and negotiate  
  197.     // 通过输出流构造一个StreamOutSink对象,负责将数据写入到Hal中。  
  198.     mOutputSink = new AudioStreamOutSink(output->stream);  
  199.     size_t numCounterOffers = 0;  
  200.     const NBAIO_Format offers[1] = {Format_from_SR_C(mSampleRate, mChannelCount)};  
  201.     ssize_t index = mOutputSink->negotiate(offers, 1, NULL, numCounterOffers);  
  202.     ALOG_ASSERT(index == 0);  
  203.   
  204.     // initialize fast mixer depending on configuration  
  205.     bool initFastMixer;  
  206.     switch (kUseFastMixer) {  
  207.     case FastMixer_Never:  
  208.         initFastMixer = false;  
  209.         break;  
  210.     case FastMixer_Always:  
  211.         initFastMixer = true;  
  212.         break;  
  213.     case FastMixer_Static:  
  214.     case FastMixer_Dynamic:  
  215.         initFastMixer = mFrameCount < mNormalFrameCount;  
  216.         break;  
  217.     }  
  218.     //如果支持FastMixer模式,需要做如下操作:  
  219.     //1、通过获取StreamOutSink的format来构造monoPipe对象,缓冲区大小是AudioMixer的4倍,  
  220.     //   负责获得AudioMixer对象的buffer数据,然后通过该monoPipe对象构造SourceAudioBufferProvider,  
  221.     //   作为FastTrack[0]的输入,由此我们可以知道这个对象名中有pipe(管道)的原因了,即像管道一样传输数据  
  222.     //2、构造FastMixer对象,初始化FastTrack[0]对象,并开启该线程,进行mix FastTrack处理  
  223.     //   特别注意,该FastTrack专门关联MixThread的MixBuff,后续作为一路track继续在FastMix中  
  224.     //   与其它FastTrack进行AudioMix混音处理  
  225.     //3、构造AudioWatchdog对象,负责监控该线程  
  226.     if (initFastMixer) {  
  227.   
  228.         // create a MonoPipe to connect our submix to FastMixer  
  229.         NBAIO_Format format = mOutputSink->format();  
  230.         // This pipe depth compensates for scheduling latency of the normal mixer thread.  
  231.         // When it wakes up after a maximum latency, it runs a few cycles quickly before  
  232.         // finally blocking.  Note the pipe implementation rounds up the request to a power of 2.  
  233.         //   
  234.         MonoPipe *monoPipe = new MonoPipe(mNormalFrameCount * 4, format, true /*writeCanBlock*/);  
  235.         const NBAIO_Format offers[1] = {format};  
  236.         size_t numCounterOffers = 0;  
  237.         ssize_t index = monoPipe->negotiate(offers, 1, NULL, numCounterOffers);  
  238.         ALOG_ASSERT(index == 0);  
  239.         monoPipe->setAvgFrames((mScreenState & 1) ?  
  240.                 (monoPipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);  
  241.         mPipeSink = monoPipe;  
  242.   
  243. #ifdef TEE_SINK  
  244.         if (mTeeSinkOutputEnabled) {  
  245.             // create a Pipe to archive a copy of FastMixer's output for dumpsys  
  246.             Pipe *teeSink = new Pipe(mTeeSinkOutputFrames, format);  
  247.             numCounterOffers = 0;  
  248.             index = teeSink->negotiate(offers, 1, NULL, numCounterOffers);  
  249.             ALOG_ASSERT(index == 0);  
  250.             mTeeSink = teeSink;  
  251.             PipeReader *teeSource = new PipeReader(*teeSink);  
  252.             numCounterOffers = 0;  
  253.             index = teeSource->negotiate(offers, 1, NULL, numCounterOffers);  
  254.             ALOG_ASSERT(index == 0);  
  255.             mTeeSource = teeSource;  
  256.         }  
  257. #endif  
  258.   
  259.         // create fast mixer and configure it initially with just one fast track for our submix          
  260.         // 构造FastMixer对象,初始化其中一个FastTrack对象,并开启该线程,进行mix FastTrack处理。  
  261.         mFastMixer = new FastMixer();  
  262.         FastMixerStateQueue *sq = mFastMixer->sq();  
  263. #ifdef STATE_QUEUE_DUMP  
  264.         sq->setObserverDump(&mStateQueueObserverDump);  
  265.         sq->setMutatorDump(&mStateQueueMutatorDump);  
  266. #endif  
  267.         FastMixerState *state = sq->begin();  
  268.         FastTrack *fastTrack = &state->mFastTracks[0];  
  269.         // wrap the source side of the MonoPipe to make it an AudioBufferProvider  
  270.         // 通过monoPipe来构造一个MonoPipeReader来读取monoPipe的数据,作为FastTrack[0]的输入端提供数据  
  271.         fastTrack->mBufferProvider = new SourceAudioBufferProvider(new MonoPipeReader(monoPipe));  
  272.         fastTrack->mVolumeProvider = NULL;  
  273.         fastTrack->mGeneration++;  
  274.         state->mFastTracksGen++;  
  275.         // 设置active track对应的bit位,初始值为0  
  276.         state->mTrackMask = 1;  
  277.         // fast mixer will use the HAL output sink  
  278.         // 使用AudioStreamOutSink来作为输出端,经过fast mixer处理过的数据将会提供给outputSink,最终写入到Hal中  
  279.         state->mOutputSink = mOutputSink.get();  
  280.         state->mOutputSinkGen++;  
  281.         state->mFrameCount = mFrameCount;  
  282.         state->mCommand = FastMixerState::COLD_IDLE;  
  283.         // already done in constructor initialization list  
  284.         //mFastMixerFutex = 0;  
  285.         state->mColdFutexAddr = &mFastMixerFutex;  
  286.         state->mColdGen++;  
  287.         state->mDumpState = &mFastMixerDumpState;  
  288. #ifdef TEE_SINK  
  289.         state->mTeeSink = mTeeSink.get();  
  290. #endif  
  291.         mFastMixerNBLogWriter = audioFlinger->newWriter_l(kFastMixerLogSize, "FastMixer");  
  292.         state->mNBLogWriter = mFastMixerNBLogWriter.get();  
  293.         sq->end();  
  294.         sq->push(FastMixerStateQueue::BLOCK_UNTIL_PUSHED);  
  295.   
  296.         // start the fast mixer  
  297.         mFastMixer->run("FastMixer", PRIORITY_URGENT_AUDIO);  
  298.         pid_t tid = mFastMixer->getTid();  
  299.         int err = requestPriority(getpid_cached, tid, kPriorityFastMixer);  
  300.         if (err != 0) {  
  301.             ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",  
  302.                     kPriorityFastMixer, getpid_cached, tid, err);  
  303.         }  
  304.   
  305. #ifdef AUDIO_WATCHDOG  
  306.         // create and start the watchdog  
  307.         mAudioWatchdog = new AudioWatchdog();  
  308.         mAudioWatchdog->setDump(&mAudioWatchdogDump);  
  309.         mAudioWatchdog->run("AudioWatchdog", PRIORITY_URGENT_AUDIO);  
  310.         tid = mAudioWatchdog->getTid();  
  311.         err = requestPriority(getpid_cached, tid, kPriorityFastMixer);  
  312.         if (err != 0) {  
  313.             ALOGW("Policy SCHED_FIFO priority %d is unavailable for pid %d tid %d; error %d",  
  314.                     kPriorityFastMixer, getpid_cached, tid, err);  
  315.         }  
  316. #endif  
  317.   
  318.     } else {  
  319.         mFastMixer = NULL;  
  320.     }  
  321.      
  322.     //根据FastMixer的模式,设置当前的MixerThread的输出端  
  323.     //1、never时,始终将mix之后的数据输出到Hal  
  324.     //2、dynamic时,将mix之后的数据输出到Hal,但是已经初始化FastMixer对象,后续可以使用  
  325.     //2、always时,将mix之后的数据通过pipe输出到FastMixer,作为FastMixer的输入  
  326.     //3、static时,判断是Mix buff是否大于Hal buff,如果大于则使用pip将数据输出到FastMixer,  
  327.     //   否则将mix后的数据输出到Hal  
  328.     switch (kUseFastMixer) {  
  329.     case FastMixer_Never:  
  330.     case FastMixer_Dynamic:  
  331.         mNormalSink = mOutputSink;  
  332.         break;  
  333.     case FastMixer_Always:  
  334.         mNormalSink = mPipeSink;  
  335.         break;  
  336.     case FastMixer_Static:  
  337.         mNormalSink = initFastMixer ? mPipeSink : mOutputSink;  
  338.         break;  
  339.     }  
  340. }  

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:30246次
    • 积分:506
    • 等级:
    • 排名:千里之外
    • 原创:5篇
    • 转载:84篇
    • 译文:0篇
    • 评论:9条
    最新评论