目录
主要类
Audio 播放流程
Track构建
getoutput流程
Audio播放流程
主要类
AudioTrack(输出)和AudioRecorder,MediaPlayerService内部的实现就是通过它们来完成的,只不过MediaPlayer/MediaRecorder提供了更强大的控制功能,相比前者也更易于使用。
以前是基于ALSA,后来改为tinyalsa。
Audio Application Framework:音频应用框架
AudioTrack:负责回放数据的输出,属 Android 应用框架 API 类
AudioRecord:负责录音数据的采集,属 Android 应用框架 API 类
AudioSystem: 负责音频事务的综合管理,属 Android 应用框架 API 类
Audio Native Framework:音频本地框架
AudioTrack:负责回放数据的输出,属 Android 本地框架 API 类
AudioRecord:负责录音数据的采集,属 Android 本地框架 API 类
AudioSystem: 负责音频事务的综合管理,属 Android 本地框架 API 类
Audio Services:音频服务
AudioPolicyService:音频策略的制定者,负责音频设备切换的策略抉择、音量调节策略等,包含各种command线程。
AudioFlinger:音频策略的执行者,负责输入输出流设备的管理及音频流数据的处理传输。openOutput中会针对输出设备的类型创建了一个PlaybackThread。 PlaybackThread有几种,比较常见有MixerThread,蓝牙耳机设备需要外放(比如ring类型的流需要同时从耳机与喇叭出来)的时候使用DuplicatingThread。
Audio HAL:音频硬件抽象层,负责与音频硬件设备的交互,由 AudioFlinger 直接调用。
与 Audio 强相关的有 MultiMedia,MultiMedia 负责音视频的编解码,MultiMedia 将解码后的数据通过 AudioTrack 输出,而 AudioRecord 采集的录音数据交由 MultiMedia 进行编码。
Audio 播放流程
Track构建
AudioTrack---native_setup---android_media_AudioTrack_setup
具体可参考:createTrack_l流程
getoutput流程
audio_io_handle_t 是与 PlaybackThread 是一一对应的(一对键值对),由已知的 audio_io_handle_t 就能找到对应的 PlaybackThread。audio_io_handle_t 在创建 PlaybackThread 时由系统分配,这个值是全局唯一的。
AudioTrack的moutput初始化 ---(c语言中把output用传址的方式,在里面赋值)
AudioSystem::getOutputForAttr
AudioPolicyService::getOutputForAttr
AudioPolicyManager::getOutputForAttr
AudioPolicyManager::getOutputForDevice //根据device打开output,获取实例
AudioPolicyService::AudioPolicyClient::openOutput
AudioFlinger::openOutput
AudioFlinger::openOutput_l
服务端:
启动main_mediaserver.main|main_audioserver.main---AudioFlinger|AudioPolicyService---AudioPolicyService::AudioPolicyClient::openOutput---AudioFlinger::openOutput---PlaybackThread
Audio播放流程
客户端:AudioTrack(.java).play---native_start----android_media_AudioTrack.android_media_AudioTrack_start---AudioTrack(.cpp).start----TrackHandle(服务端的Track代理) 的start(这步跳转逻辑不清楚),最后会调用到服务端Track的start即Tracks文件中的AudioFlinger::PlaybackThread::Track::start---addTrack_l---onAddNewTrack_l---broadcast_l(mWaitWorkCV.broadcast,使用Condition原理)。接着会触发AudioTrack.java.write写数据--
android_media_AudioTrack.android_media_AudioTrack_write_byte
releaseBuffer--AudioTrackClientProxy.releaseBuffer
服务端写数据:
参考:
Android O(8.0)音频write数据流程变化(HIDL)
Audio PCM输出流程 "/dev/snd/pcmC%uD%u%c"
Threads.PlaybackThread::threadLoop---
threadLoop_mix (混音)
threadLoop_write(写到音频设备)---NormalSink->write---AudioStreamOutSink.write---StreamOutHalHidl::write---audio_hw(HIDL).out_write---
Android音频流的从PCM到输出的路线。首先,我们的PCM音频数据一般会在用户端,而混音会在AudioFlinger端,因此需要把PCM数据传送给AudioFlinger,因此需要开辟出一块内存用于数据传送;数据到了AudioFlinger之后,可以给PCM数据调节音量,增加音效等(即混音),因此还需要一块内存用于音效处理,这块buffer在getOutput内已经开辟;混音完成后即可把PCM数据输出给音频设备进行播放。