专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > 移动开发

起动MixerThread

发布时间:2010-05-30 05:31:11 文章来源:www.iduyao.cn 采编人员:星星草
启动MixerThread
今天想改变一下MixerThread的优先级。
看了下,原来在Thread的run函数中可以指定线程的优先级。
接下来就需要找到哪个地方调用了MixerThread的run函数,也就是启动了MixerThread。


想到,调用AudioTrack的start函数,可以开始播放。MixerThread的启动是不是由这儿驱动的呢?


看了下函数AudioTrack::start,有两个地方可疑:
           t->run("AudioTrackThread", THREAD_PRIORITY_AUDIO_CLIENT);
            status = mAudioTrack->start();


不过第一处指明了thread名称为AudioTrackThread,并非Mixer Thread。
既然看了,也就看看t是个嘛东东吧:
    sp<AudioTrackThread> t = mAudioTrackThread;
mAudioTrackThread在AudioTrack::set函数中被赋值:
        mAudioTrackThread = new AudioTrackThread(*this, threadCanCallJava);
AudioTrackThread::threadLoop函数的实现:
    return mReceiver.processAudioBuffer(this);
也就是调用了函数AudioTrack::processAudioBuffer。
看了看AudioTrack::processAudioBuffer函数的处理,感觉也就前面对callback的处理有用点。
比如,原来如果调用过SetMarkerPosition,而此时如果满足了条件,就会调用相应的回调函数。
后面的处理,没看明白什么意思,唯一的数据copy发生在16bit与8bit的转换。


那就看看mAudioTrack->start()吧。
函数AudioTrack::createTrack对mAudioTrack进行了赋值:
    mAudioTrack = track;

track的来历:
    sp<IAudioTrack> track = audioFlinger->createTrack(getpid(),
                                                      streamType,
                                                      sampleRate,
                                                      format,
                                                      channelCount,
                                                      frameCount,
                                                      ((uint16_t)flags) << 16,
                                                      sharedBuffer,
                                                      output,
                                                      &mSessionId,
                                                      &status);
 
函数AudioFlinger::createTrack返回的是一个TrackHandle对象:
        trackHandle = new TrackHandle(track);


函数AudioFlinger::TrackHandle::start的实现也不复杂:
    return mTrack->start();


mTrack就是刚才传入的track。
        track = thread->createTrack_l(client, streamType, sampleRate, format,
                channelCount, frameCount, sharedBuffer, lSessionId, &lStatus);


函数 AudioFlinger::PlaybackThread::createTrack_l返回的是一个Track对象:
        track = new Track(this, client, streamType, sampleRate, format,
                channelCount, frameCount, sharedBuffer, sessionId);


函数AudioFlinger::PlaybackThread::Track::start调用了函数AudioSystem::startOutput。
层层调用,最终调到了函数AudioPolicyManagerBase::startOutput。
不过,并没有看到有启动MixerThread的地方。


先小结一下。


创建AudioTrack对象的时候,会先根据stream type获取一个output。
获取的方法是调用函数AudioSystem::getOutput。
函数AudioSystem::getOutput中,会调用函数AudioSystem::get_audio_policy_service来获取AudioPolicyService。
AudioPolicyService对象若尚未被创建,函数AudioSystem::get_audio_policy_service会创建一个。
在AudioPolicyService的构造函数中调用了AudioPolicyManagerBase的构造函数。
AudioPolicyManagerBase的构造函数中打开了输出用的output。
打开方法是通过调用函数AudioPolicyService::openOutput最终调用到了函数AudioFlinger::openOutput。
函数AudioFlinger::openOutput中调用到了HAL层中的函数openOutputStream。
HAL层中通过调用ALSA Lib的接口,根据device name最终打开了output stream。


回到AudioPolicyManagerBase的构造函数中。
其中打开了output之后,为每个output创建了一个playback thread。
也就是说,底层的每个device对应了一个playback thread。


AudioTrack的构造函数获取到output之后,接下来调用函数AudioFlinger::createTrack来创建track。
track最终对应到了playback thread中的track。


调用函数AudioTrack::write往AudioTrack中写数据的时候,其实是写到了AudioTrack中的audio_track_cblk_t对象中。
调用函数AudioTrack::start最终调用到了函数AudioFlinger::PlaybackThread::Track::start,其中将track自己设置为有效,并将自己追加到对应的playback thread的track列表中。
MixerThread的threadloop函数中,会处理所有的active 的track,进行mix,并将数据写入到硬件。


还是回去看看Mixer Thread是怎么启动的吧。
搜了下,发现函数AudioFlinger::PlaybackThread::onFirstRef中有调用run。
PlaybackThread是MixerThread的父类。
估计MixerThread也就是在这儿启动的了。
查了下资料,onFirstRef是在创建第一个强连接是被创建,在创建对象的时候会被调用。


由前面所知,AudioPolicyManagerBase的构造函数中创建了playback thread,这里的playback thread其实是MixerThread。
打log验证了一下,果然,在AudioPolicyManagerBase的构造函数中引起了AudioFlinger::PlaybackThread::onFirstRef函数的调用,并最终启动了MixerThread。
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: