AudioFlinger源码解析
⾸先介绍⼀些AudioFlienger ⽤到的内部类
⼀ client 内部类
可能存在很多个AudioTrack 或者AudioRecord (客户端)与AudioFlienger 对接。每个客户端由PId 分辨。
每注册⼀个客户端, 则⽣成⼀个client 对象,保存到DefaultKeyedVector< pid_t, wp<Client> > mClients 中
class Client : public RefBase {
public:
Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
virtual ~Client();
sp<MemoryDealer> heap() const;
pid_t pid() const { return mPid; }
sp<AudioFlinger> audioFlinger() const { return mAudioFlinger; }
private:
Client(const Client&);
Client& operator = (const Client&);
const sp<AudioFlinger> mAudioFlinger;
sp<MemoryDealer> mMemoryDealer;
const pid_t mPid;
};
⼆ AudioFlinger 的初始化
AudioFlinger的初始化是从main_audioserver.cpp 初始化。
这是系统启动服务的典型⽅法。
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
AudioPolicyService::instantiate();
RadioService::instantiate();
SoundTriggerHwService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
我们只关⼼AudioFlinger::instantial()函数, 但是此函数并不是在AudioFlinger.cpp 中定义。
AudioFlinger 继承了BinderService,
class AudioFlinger :
public BinderService<AudioFlinger>,
public BnAudioFlinger
template<typename SERVICE>
class BinderService
{
public:
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
pendingreturn sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}
......
static void instantiate() { publish(); }
其实就是执⾏,
sp<IServiceManager> sm(defaultServiceManager());
sm->addService( String16(AudioFlinger::getServiceName()), new AudioFlinger, allowIsolated);
向ServiceManager 中注册AudioFlinger。
三 建⽴Track, 反馈给AudioTracker
sp<IAudioTrack> AudioFlinger::createTrack(
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
size_t *frameCount,
IAudioFlinger::track_flags_t *flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
pid_t pid,
pid_t tid,
audio_session_t *sessionId,
int clientUid,
status_t *status)
{
sp<PlaybackThread::Track> track;
sp<TrackHandle> trackHandle;
sp<Client> client;
status_t lStatus;
audio_session_t lSessionId;
const uid_t callingUid = IPCThreadState::self()->getCallingUid(); ......
{
Mutex::Autolock _l(mLock);
/
/ 1.根据索引号到⼀个⼯作线程 playbackThread
PlaybackThread *thread = checkPlaybackThread_l(output);
client = registerPid(pid);
ALOGV("createTrack() lSessionId: %d", lSessionId);
//2.建⽴PlaybackThread::Track指针, 这个对象是AT调⽤AF 的中间接⼝
track = thread->createTrack_l(client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, clientUid, &lStatus); LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (track == 0));
// we don't abort yet if lStatus != NO_ERROR; there is still work to be done regardless
// move effect chain to this output thread if an effect on same session was waiting
// for a track to be created
if (lStatus == NO_ERROR && effectThread != NULL) {
// no risk of deadlock because AudioFlinger::mLock is held
Mutex::Autolock _dl(thread->mLock);
Mutex::Autolock _sl(effectThread->mLock);
moveEffectChain_l(lSessionId, effectThread, thread, true);
}
// Look for sync events awaiting for a session to be used.
for (size_t i = 0; i < mPendingSyncEvents.size(); i++) {
if (mPendingSyncEvents[i]->triggerSession() == lSessionId) {
if (thread->isValidSyncEvent(mPendingSyncEvents[i])) {
if (lStatus == NO_ERROR) {
(void) track->setSyncEvent(mPendingSyncEvents[i]);
} else {
mPendingSyncEvents[i]->cancel();
}
i--;
}
}
}
//3.向PlaybackThread 中设置硬件ID
setAudioHwSyncForSession_l(thread, lSessionId);
}
if (lStatus != NO_ERROR) {
// remove local strong reference to Client before deleting the Track so that the
// Client destructor is called by the TrackBase destructor with mClientLock held
// Don't hold mClientLock when releasing the reference on the track as the
// destructor will acquire it.
{
Mutex::Autolock _cl(mClientLock);
client.clear();
}
track.clear();
goto Exit;
}
// return handle to client
//4.包装sp<TrackHandle>并返回
trackHandle = new TrackHandle(track);
Exit:
*status = lStatus;
return trackHandle;
}
重点关注过程2.
// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l( const sp<AudioFlinger::Client>& client,
audio_stream_type_t streamType,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
size_t *pFrameCount,
const sp<IMemory>& sharedBuffer,
audio_session_t sessionId,
IAudioFlinger::track_flags_t *flags,
pid_t tid,
int uid,
status_t *status)
{
......
//1. 创建Track,此对象提供给AudioTrack, ⽤于与AudioFlinger 通信
track = new Track(this, client, streamType, sampleRate, format,
channelMask, frameCount, NULL, sharedBuffer,
sessionId, uid, *flags, TrackBase::TYPE_DEFAULT);
lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
if (lStatus != NO_ERROR) {
ALOGE("createTrack_l() initCheck failed %d; no control block?", lStatus);
// track must be cleared from the caller as the caller has the AF lock
goto Exit;
}
// PlaybackThread 会包含很多Track, 保存在mTracks
mTracks.add(track);
sp<EffectChain> chain = getEffectChain_l(sessionId);
if (chain != 0) {
ALOGV("createTrack_l() setting main buffer %p", chain->inBuffer());
track->setMainBuffer(chain->inBuffer());
chain->setStrategy(AudioSystem::getStrategyForStream(track->streamType())); chain->incTrackCnt();
}
if ((*flags & IAudioFlinger::TRACK_FAST) && (tid != -1)) {
pid_t callingPid = IPCThreadState::self()->getCallingPid();
// we don't have CAP_SYS_NICE, nor do we want to have it as it's too powerful, // so ask activity manager to do this on our behalf
sendPrioConfigEvent_l(callingPid, tid, kPriorityAudioApp);
}
}
lStatus = NO_ERROR;
Exit:
*status = lStatus;
return track;
}
下⾯看⼀下Track 的构造函数,在Track.cpp中实现。
它最重要的部分是建⽴共享内存的服务器端mAudioTrackServerProxy。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论