AudioFlinger(2)
查看Track的构造函数:
AudioFlinger::PlaybackThread::Track::Track( const wp<ThreadBase>& thread, const sp<Client>& client, int streamType, uint32_t sampleRate, int format, int channelCount, int frameCount, const sp<IMemory>& sharedBuffer, int sessionId) : TrackBase(thread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer, sessionId), mMute(false), mSharedBuffer(sharedBuffer), mName(-1), mMainBuffer(NULL), mAuxBuffer(NULL), mAuxEffectId(0), mHasVolumeController(false) { if (mCblk != NULL) {à在父类TrackBase中创建 sp<ThreadBase> baseThread = thread.promote(); if (baseThread != 0) { PlaybackThread *playbackThread = (PlaybackThread *)baseThread.get(); mName = playbackThread->getTrackName_l(); mMainBuffer = playbackThread->mixBuffer(); } mVolume[0] = 1.0f; mVolume[1] = 1.0f; mStreamType = streamType; // NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack mCblk->frameSize = AudioSystem::isLinearPCM(format) ? channelCount * sizeof(int16_t) : sizeof(int8_t); } } |
查看父类TrackBase的构造函数:
AudioFlinger::ThreadBase::TrackBase::TrackBase( const wp<ThreadBase>& thread, const sp<Client>& client, uint32_t sampleRate, int format, int channelCount, int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, int sessionId) : RefBase(), mThread(thread), mClient(client), mCblk(0), mFrameCount(0), mState(IDLE), mClientTid(-1), mFormat(format), mFlags(flags & ~SYSTEM_FLAGS_MASK), mSessionId(sessionId) { size_t size = sizeof(audio_track_cblk_t);à得到audio_track_cblk_t的大小 size_t bufferSize = frameCount*channelCount*sizeof(int16_t); if (sharedBuffer == 0) { size += bufferSize;à共享内存中前面为audio_track_cblk_t,后面为数据 }
if (client != NULL) { mCblkMemory = client->heap()->allocate(size);à根据size大小创建共享内存 if (mCblkMemory != 0) { mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());àpointer返回共享内存首地址,强制转换为audio_track_cblk_t类型 if (mCblk) { // construct the shared structure in-place. new(mCblk) audio_track_cblk_t(); // clear all buffers mCblk->frameCount = frameCount; mCblk->sampleRate = sampleRate; mCblk->channelCount = (uint8_t)channelCount; if (sharedBuffer == 0) { mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t); memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));à清空数据区 // Force underrun condition to avoid false underrun callback until first data is // written to buffer (other flags are cleared) mCblk->flags = CBLK_UNDERRUN_ON;à初始化flag } …
|
new(mCblk) audio_track_cblk_t();是一个placement new操作,目的是在已经分配的内存中创建一个对象(普通的new是无法完成的)。这里采用placement new将使audio_track_cblk_t创建在共享内存上,从而能使多个进程看见并使用。
上面分析可知:
Track创建了共享内存
audio_track_cblk_t对象通过placement new创建在共享内存中
查看AudioFlinger::createTrack:
sp<IAudioTrack> AudioFlinger::createTrack(..) { sp<TrackHandle> trackHandle; track = thread->createTrack_l(client, streamType, sampleRate, format, channelCount, frameCount, sharedBuffer, lSessionId, &lStatus); trackHandle = new TrackHandle(track); return trackHandle; } |
可见AudioFlinger::createTrack返回的是一个TrackHandle对象,它是Track的代理模式,完成Track本身不具备的Binder通信的功能。