AudioFlinger分析(3)

2020-02-20 14:13

//终于找到了,把这个线程加入线程管理组织中

mPlaybackThreads.add(mNextThreadId, thread); return mNextThreadId; } }

明白了,看来AT在调用AF的createTrack的之前,AF已经在某个时候把线程创建好了,而且是一个Mixer类型的线程,看来和混音有关系呀。这个似乎和我们开始设想的AF工作有点联系喔。Lock,读缓存,写Audio硬件,Unlock。可能都是在这个线程里边做的。 2 继续createTrack

AudioFlinger::createTrack( pid_t pid, int streamType, uint32_t sampleRate, int format, int channelCount, int frameCount, uint32_t flags,

const sp& sharedBuffer, int output, status_t *status) {

sp track; sp trackHandle; sp client; wp wclient; status_t lStatus; {

//假设我们找到了对应的线程 Mutex::Autolock _l(mLock);

PlaybackThread *thread = checkPlaybackThread_l(output); //晕,调用这个线程对象的createTrack_l

track = thread->createTrack_l(client, streamType, sampleRate, format, channelCount, frameCount, sharedBuffer, &lStatus);

}

trackHandle = new TrackHandle(track);

return trackHandle;----》注意,这个对象是最终返回到AT进程中的。

实在是....太绕了。再进去看看thread->createTrack_l吧。_l的意思是这个函数进入之前已经获得同步锁了。

跟着sourceinsight ctrl+鼠标左键就进入到下面这个函数。 下面这个函数的签名好长啊。这是为何?

原来Android的C++类中大量定义了内部类。说实话,我之前几年的C++的经验中基本没接触过这么频繁使用内部类的东东。--->当然,你可以说STL也大量使用了呀。 我们就把C++的内部类当做普通的类一样看待吧,其实我感觉也没什么特殊的含义,和外部类是一样的,包括函数调用,public/private之类的东西。这个和JAVA的内部类是大不一样的。

sp AudioFlinger::PlaybackThread::createTrack_l( const sp& client, int streamType, uint32_t sampleRate, int format, int channelCount, int frameCount,

const sp& sharedBuffer, status_t *status) {

sp track; status_t lStatus; { // scope for mLock

Mutex::Autolock _l(mLock); //new 一个track对象

//我有点愤怒了,Android真是层层封装啊,名字取得也非常相似。 //看看这个参数吧,注意sharedBuffer这个,此时的值应是0

track = new Track(this, client, streamType, sampleRate, format, channelCount, frameCount, sharedBuffer);

mTracks.add(track); //把这个track加入到数组中,是为了管理用的。 }

lStatus = NO_ERROR; return track; }

看到这个数组的存在,我们应该能想到什么吗?这时已经有:

? 一个MixerThread,内部有一个数组保存track的

看来,不管有多少个AudioTrack,最终在AF端都有一个track对象对应,而且这些所有的track对象都会由一个线程对象来处理。----难怪是Mixer啊

再去看看new Track,我们一直还没找到共享内存在哪里创建的!!!

AudioFlinger::PlaybackThread::Track::Track( const wp& thread, const sp& client, int streamType, uint32_t sampleRate, int format, int channelCount, int frameCount,

const sp& sharedBuffer)

: TrackBase(thread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer),

mMute(false), mSharedBuffer(sharedBuffer), mName(-1) {

// mCblk !=NULL?什么时候创建的??

//只能看基类TrackBase,还是很愤怒,太多继承了。 if (mCblk != NULL) { mVolume[0] = 1.0f; mVolume[1] = 1.0f; mStreamType = streamType;

mCblk->frameSize = AudioSystem::isLinearPCM(format) ? channelCount * sizeof(int16_t) : sizeof(int8_t); } }

看看基类TrackBase干嘛了

AudioFlinger::ThreadBase::TrackBase::TrackBase(

const wp& thread, const sp& client, uint32_t sampleRate, int format, int channelCount, int frameCount, uint32_t flags,

const sp& sharedBuffer) : RefBase(), mThread(thread), mClient(client), mCblk(0), mFrameCount(0), mState(IDLE), mClientTid(-1), mFormat(format),

mFlags(flags & ~SYSTEM_FLAGS_MASK) {

size_t size = sizeof(audio_track_cblk_t);

size_t bufferSize = frameCount*channelCount*sizeof(int16_t); if (sharedBuffer == 0) { size += bufferSize; }

//调用client的allocate函数。这个client是什么?就是我们在CreateTrack中创建的 那个Client,我不想再说了。反正这里会创建一块共享内存 mCblkMemory = client->heap()->allocate(size);

有了共享内存,但是还没有里边有同步锁的那个对象audio_track_cblk_t mCblk = static_cast(mCblkMemory->pointer()); 下面这个语法好怪啊。什么意思???

new(mCblk) audio_track_cblk_t();

//各位,这就是C++语法中的placement new。干啥用的啊?new后面的括号中是一块buffer,再

后面是一个类的构造函数。对了,这个placement new的意思就是在这块buffer中构造一个对象。

我们之前的普通new是没法让一个对象在某块指定的内存中创建的。而placement new却可以。

这样不就达到我们的目的了吗?搞一块共享内存,再在这块内存上创建一个对象。这样,这个对象不也就能在两个内存中共享了吗?太牛牛牛牛牛了。怎么想到的? // clear all buffers

mCblk->frameCount = frameCount; mCblk->sampleRate = sampleRate; mCblk->channels = (uint8_t)channelCount; }

好了,解决一个重大疑惑,跨进程数据共享的重要数据结构audio_track_cblk_t是通过placement new在一块共享内存上来创建的。 回到AF的CreateTrack,有这么一句话: trackHandle = new TrackHandle(track);

return trackHandle;----》注意,这个对象是最终返回到AT进程中的。 trackHandle的构造使用了thread->createTrack_l的返回值。

2.4 到底有少种对象

读到这里的人,一定会被异常多的class类型,内部类,继承关系搞疯掉。说实话,这里废点心血整个或者paste一个大的UML图未尝不可。但是我是不太习惯用图说话,因为图我实在是记不住。那好吧。我们就用最简单的话语争取把目前出现的对象说清楚。 1 AudioFlinger

class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient AudioFlinger类是代表整个AudioFlinger服务的类,其余所有的工作类都是通过内部类的方式在其中定义的。你把它当做一个壳子也行吧。 2 Client

Client是描述C/S结构的C端的代表,也就算是一个AT在AF端的对等物吧。不过可不是Binder机制中的BpXXX喔。因为AF是用不到AT的功能的。 class Client : public RefBase { public:

sp mAudioFlinger;//代表S端的AudioFlinger

sp mMemoryDealer;//每个C端使用的共享内存,通过它分配 pid_t mPid;//C端的进程id }; 3 TrackHandle

Trackhandle是AT端调用AF的CreateTrack得到的一个基于Binder机制的Track。


AudioFlinger分析(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:华理工 宏观经济学 - 201606 - 模拟卷2

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: