0
点赞
收藏
分享

微信扫一扫

视频流分析 二

DT_M 2022-04-16 阅读 67
java

目录

5 AudioFlinger和AudioPolicyServer

5 AudioFlinger和AudioPolicyServer

        AudioPolicyService是Android音频系统的两大服务之一,另一个服务是AudioFlinger,这两大服务都在系统启动时有 MediaSever加载,加载的代码位于:frameworks\base\media\mediaserver \main_mediaserver.cpp。AudioFlinger主要负责管理音频数据处理以及和硬件抽象层相关的工作。AudioPolicyService主要完成以下任务:JAVA应用层通过JNI,经由IAudioPolicyService接口,访问AudioPolicyService提供的服务;输入输出设备的连接状态;系统的音频策略(strategy)的切换;音量/音频参数的设置。

1. AudioPolicyService继承了IAudioPolicyService接口,这样AudioPolicyService就可以基于Android的Binder机制,向外部提供服务;

2. AudioPolicyService同时也继承了AudioPolicyClientInterface类,他有一个AudioPolicyInterface类的成员指针mpPolicyManager,实际上就是指向了AudioPolicyManager;

3. AudioPolicyManager类继承了AudioPolicyInterface类以便向AudioPolicyService提供服务,反过来 同时还有一个AudioPolicyClientInterface指针,该指针在构造函数中被初始化,指向了AudioPolicyService,实 际上,AudioPolicyService是通过成员指针mpPolicyManager访问AudioPolicyManager,而 AudioPolicyManager则通过AudioPolicyClientInterface(mpClientInterface)访问 AudioPolicyService;

4. AudioPolicyService有一个内部线程类AudioCommandThread,顾名思义,所有的命令(音量控制,输入、输出的切换等)最终都会在该线程中排队执行;

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

class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient

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

class Client : public RefBase {
public:
Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
virtual ~Client();
const sp<MemoryDealer>& heap() const;
pid_t pid() const { return mPid; }
sp<AudioFlinger> audioFlinger() { return mAudioFlinger; }

private:
Client(const Client
Client& operator = (const Client
sp<AudioFlinger> mAudioFlinger;
sp<MemoryDealer> mMemoryDealer;
pid_t mPid;
};

7. Trackhandle 是AT 端调用AF 的CreateTrack 得到的一个基于Binder 机制的Track。这个 TrackHandle 实际上是对真正干活的PlaybackThread::Track 的一个跨进程支持的封装。什么意思?本来PlaybackThread::Track 是真正在AF 中干活的东西,不过为了支持跨进程的话,我们用TrackHandle 对其进行了一下包转。这样在AudioTrack 调用TrackHandle 的功能,实际都由TrackHandle 调用PlaybackThread::Track 来完成了。可以认为是一种Proxy 模式吧。

class TrackHandle : public android::BnAudioTrack {
public:
TrackHandle(const sp<PlaybackThread::Track>
virtual ~TrackHandle();
virtual status_t start();
virtual void stop();
virtual void flush();
virtual void mute(bool);
virtual void pause();
virtual void setVolume(float left, float right);
virtual sp<IMemory> getCblk() const;
virtual status_t attachAuxEffect(int effectId);
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
private:
sp<PlaybackThread::Track> mTrack;
};

8.线程类

RecordThread : public ThreadBase, public AudioBufferProvider

class PlaybackThread : public ThreadBase

MixerThread : public PlaybackThread

DirectOutputThread : public PlaybackThread

DuplicatingThread : public MixerThread

class Track : public TrackBase                          --PlayingThread 的内部类Track

class TrackBase : public AudioBufferProvider, public RefBase

AudioFlinger功能:

  1. 播放:将应用写入的PCM数据给audio driver播放。
  2. 录音:将从audio driver读取的PCM传输给应用实现录音。
  3. SRC(Sample Rate Converter):根据需要支持采样率的转换功能。
  4. 混音:支持最多32路stream的混音播放
  5. 路径切换:支持多种输入路径,输出路径的选择,切换。
  6. 模式:支持三种不同的模式:normal/ringtone/in-call
  7. 音量控制:根据不同需要支持音量控制。

输出路径管理:

1. 应用层状态发生改变

  因素:1.手机模式发生改变  setMode()     AudioManager.java

        2.stream的状态发生改变

2. 设备状态发生改变

  因素:1.calling:用户默认选择“speaker”

        2.FMRadio:默认选择“headset”

3.应用程序的强制需求

因素:1.插入,拔出耳机

2.连接断开Bluetooth耳机

这个部分的流程与音量调节过程基本相似,重点需要学习的是audioflinger中Track与Record部分。

Record部分:

1.创建audioflinger
Main(Main_mediaServer.cpp)
=>AudioFlinger::instantiate()(Main_mediaServer.cpp)
=>AudioFlinger()(audioFlinger.cpp)
=>AudioHardwareInterface::create()(audioFlinger.cpp)
=>AudioPolicyService::instantiate()(Main_mediaServer.cpp)

2.分析createTrack函数
createTrack(audioFlinger.cpp)
=> checkPlaybackThread_l(audioFlinger.cpp)—根据output句柄获得线程
=>createTrack_l(audioFlinger.cpp)—从上面返回的线程对象中创建一个track
=>new Track(audioFlinger.cpp)
=>分析Track构造函数(audioFlinger.cpp)
=>再分析TrackBase构造函数(audioFlinger.cpp)
=>new(mCblk) audio_track_cblk_t();
3.分析output的来源
getOutput(AudioSystem.cpp)
=> getOutput(AudioPolicyService.cpp)
=> getOutput(AudioPolicyManagerBase.cpp)
=>output = mHardwareOutput(AudioPolicyManagerBase.cpp)
=>分析构造函数AudioPolicyService()并传递this指针AudioPolicyManagerBase
=>分析构造函数AudioPolicyManagerBase()
=> openOutput(AudioPolicyManagerBase.cpp)返回mHardwareOutput
=> openOutput(AudioPolicyService.cpp)
=> openOutput(audioFlinger.cpp)
=>openOutputStream(AudioHardwareALSA.cpp)
=>new AudioStreamOutALSA(AudioHardwareALSA.cpp)
=>new MixerThread()混音线程创建(audioFlinger.cpp)
=>new AudioMixer(audioFlinger.cpp)
=>AudioFlinger::MixerThread::threadLoop(audioFlinger.cpp)
=>prepareTracks_l(audioFlinger.cpp)
=>mAudioMixer->process()(audioFlinger.cpp)

(这是C++语法中的placement new。干啥用的啊?new 后面的括号中是一块buffer,再后面是一个类的构造函数。对了,这个placement new 的意思就是在这块buffer 中构造一个对象。我们之前的普通new 是没法让一个对象在某块指定的内存中创建的。而placement new 却可以。这样不就达到我们的目的了吗?搞一块共享内存,再在这块内存上创建一个对象。这样,这个对象不也就能在两个内存中共享了吗?)

=>new TrackHandle(track) (audioFlinger.cpp)

(Trackhandle 是AT 端调用AF 的CreateTrack 得到的一个基于Binder 机制的Track。这个 TrackHandle 实际上是对真正干活的PlaybackThread::Track 的一个跨进程支持的封装。什么意思?本来PlaybackThread::Track 是真正在AF 中干活的东西,不过为了支持跨进程的话,我们用TrackHandle 对其进行了一下包转。这样在AudioTrack 调用TrackHandle 的功能,实际都由TrackHandle 调用PlaybackThread::Track 来完成了。可以认为是一种Proxy 模式吧。)

在我们再次被绕晕之后,我们回眸看看足迹吧:

1.在 AudioTrack 中,调用set 函数

2.这个函数会通过AudioSystem::getOutput 来得到一个output 的句柄

3.AS 的getOutput 会调用AudioPolicyService 的getOutput

4.然后我们就没继续讲APS 的getOutPut 了,而是去看看APS 创建的东西

5.发现 APS 创建的时候会创建一个AudioManagerBase,这个AMB 的创建又会调用

6.APS 的openOutput。

7.APS 的openOutput 又会调用AudioFlinger 的openOutput

Start(AudioTrack.cpp)
=>mAudioTrack->start()(AudioTrack.cpp)
=>AudioFlinger::TrackHandle::start()(audioFlinger.cpp)
=> mTrack->start()(audioFlinger.cpp)
=>AudioFlinger::PlaybackThread::Track::start()(audioFlinger.cpp)
=>playbackThread->addTrack_l(this) (audioFlinger.cpp)
=>mActiveTracks.add(track) (audioFlinger.cpp) —加入到活跃数组
=> mWaitWorkCV.broadcast()

(看到这个broadcast,一定要想到:恩,在不远处有那么一个线程正等着这个CV 呢。start 是把某个track 加入到PlayingThread 的活跃Track 队列,然后触发一个信号事件。由于这个事件是PlayingThread 的内部成员变量,而PlayingThread 又创建了一个线程,那么难道是那个线程在等待这个事件吗?这时候有一个活跃track,那个线程应该可以干活了吧?这个线程是MixerThread。我们去看看它的线程函数threadLoop)

=> AudioFlinger::MixerThread::threadLoop()(audioFlinger.cpp)
=>prepareTracks_l(audioFlinger.cpp)
=>mAudioMixer->process()(audioFlinger.cpp)
=>AudioMixer(audioFlinger.cpp)
=>mState.hook(&mState, output) (audioFlinger.cpp)
=>AudioMixer(AudioMixer.cpp)
=>mState.hook = process__nop(AudioMixer.cpp)
=>mOutput->write(mMixBuffer, mixBufferSize) (audioFlinger.cpp)

(把缓存的数据写到outPut 中。这个mOutput 是AudioStreamOut,由Audio HAL 的那个对象创建得到)

AudioFlinger层的内容会编译成库libaudioflinger.so。AudioFlinger是Audio系统的中间层,在系统中起服务的作用,向上通过IAudioFlinger接口提供服务,向下访问AudioHardware,实现输出音频数据,控制音频参数。另外,AudioFlinger还为libmedia提供Audio部分接口的实现。AudioPolicyService主要完成以下功能:JAVA应用层通过JNI,经由IAudioPolicyService接口,访问AudioPolicyService提供的服务。输入输出设备的连接状态。系统的音频策略(strategy)的切换。音量/音频参数的设置。

举报

相关推荐

0 条评论