文章开始前面的说明:
- 这是我看源码时候认为是流程的地方,代码只是拿了关键代码
main_audioserver的初始化
前面初始化的流程和AudioPolicyService一样的,这里就直接调用构造函数和onFirstRef方法了
# frameworks/av/media/audioserver/main_audioserver.cpp
int main(int argc __unused, char **argv)
{
// 两个重要的Service初始化(不知道调换顺序会不会有关系?)
AudioFlinger::instantiate();
AudioPolicyService::instantiate();
}
构造函数和onFirstRef方法
构造函数和onFirstRef仿佛没做什么事情(也有可能是我没看出来) 流程就这样结束了,AudioFlinger创建出来就等着别人来使用
AudioFlinger::AudioFlinger(): BnAudioFlinger(),省略各种赋值
{
// 创建设备HAL层工厂
mDevicesFactoryHal = DevicesFactoryHalInterface::create();
// 创建效果HAL层工厂
mEffectsFactoryHal = EffectsFactoryHalInterface::create();
}
void AudioFlinger::onFirstRef()
{
// 音频模式
mMode = AUDIO_MODE_NORMAL;
gAudioFlinger = this;
// HDIL回调? 有什么作用?
mDevicesFactoryHalCallback = new DevicesFactoryHalCallbackImpl;
mDevicesFactoryHal->setCallbackOnce(mDevicesFactoryHalCallback);
}
AudioFlinger的loadHwModule
这里接着AudioPliocyService继续进入,总结起来就是(因为openDevice涉及HDIL和HAL层,就先不写了,后面再写)
- 先从mAudioHwDevs列表中找,不重复加载,也是做一份缓存
- openDevice通过HDIL和HAL交互,最后返回的dev = new DeviceHalHidl() = 设备
- 拿到设备之后,对设备进行一些赋值,用flag来记录,且会分配一个handle句柄
- 把所有信息封装到AudioHwDevice类,存到mAudioHwDevs列表
audio_module_handle_t AudioFlinger::loadHwModule(const char *name)
{
// 调用了自己的方法
return loadHwModule_l(name);
}
audio_module_handle_t AudioFlinger::loadHwModule_l(const char *name)
{
// 缓存,加载过的不再加载
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
if (strncmp(mAudioHwDevs.valueAt(i)->moduleName(), name, strlen(name)) == 0) {
return mAudioHwDevs.keyAt(i);
}
}
// 强智能指针 最后结果是 dev = new DeviceHalHidl()
sp<DeviceHalInterface> dev;
// 重要方法 加载硬件设备 --> mDevicesFactoryHal = DevicesFactoryHalHybrid --> DevicesFactoryHalHidl
// 和HIDL相关,先放着 ,方法执行openDevice完后会得到 dev = new DeviceHalHidl()
int rc = mDevicesFactoryHal->openDevice(name, &dev);
mHardwareStatus = AUDIO_HW_INIT;
// 检查设备是否正常初始化
rc = dev->initCheck();
mHardwareStatus = AUDIO_HW_IDLE;
AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0);
// 第一次加载获取的主设备值
if (0 == mAudioHwDevs.size()) {
mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
float mv;
if (OK == dev->getMasterVolume(&mv)) {
// 主音量
mMasterVolume = mv;
}
mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
bool mm;
if (OK == dev->getMasterMute(&mm)) {
// 是否静音
mMasterMute = mm;
}
}
// 用每一位对应一个属性值,最后全在flag中
mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
if (OK == dev->setMasterVolume(mMasterVolume)) {
flags = static_cast<AudioHwDevice::Flags>(flags |
AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
}
mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
if (OK == dev->setMasterMute(mMasterMute)) {
flags = static_cast<AudioHwDevice::Flags>(flags |
AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
}
// 分配一个句柄/id
audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
// 相当于包装 把所有相关的信息保存起来在AudioHwDevice类中管理
AudioHwDevice *audioDevice = new AudioHwDevice(handle, name, dev, flags);
// 做一个保存,handle为设备句柄,看作id,下标
mAudioHwDevs.add(handle, audioDevice);
// 返回句柄,有句柄就可以在mAudioHwDevs中找到你想要的device
return handle;
}
AudioFlinger的openOutput
总得来说就是两句话:
- 通过HIDL打开设备的输出流
- 根据流的类型创建相应的Thread,且保存在mPlaybackThreads
// 打开输出流
status_t AudioFlinger::openOutput(audio_module_handle_t module,
audio_io_handle_t *output,
audio_config_t *config,
const sp<DeviceDescriptorBase>& device,
uint32_t *latencyMs,
audio_output_flags_t flags)
{
// 调用内部方法,得到一个播放thraed
sp<ThreadBase> thread = openOutput_l(module, output, config, deviceType, address, flags);
if (thread != 0) {
if ((flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) == 0) {
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
// latency传输延迟
*latencyMs = playbackThread->latency();
// notify client processes of the new output creation
// 通知客户端进程创建了新的输出
playbackThread->ioConfigChanged(AUDIO_OUTPUT_OPENED);
}
}
return NO_INIT;
}
# 继续看openOutput_l
sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
audio_io_handle_t *output,
audio_config_t *config,
audio_devices_t deviceType,
const String8& address,
audio_output_flags_t flags)
{
// 找到合适输出设备
AudioHwDevice *outHwDev = findSuitableHwDev_l(module, deviceType);
// 修改状态
mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
AudioStreamOut *outputStream = NULL;
// 输出流,最终还是通过HIDL调用打开输出流
status_t status = outHwDev->openOutputStream(
&outputStream,
*output,
deviceType,
flags,
config,
address.string());
mHardwareStatus = AUDIO_HW_IDLE;
if (status == NO_ERROR) {
if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
....
} else {
// 创建播放线程名,根据类型去创建类型
sp<PlaybackThread> thread;
if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
// offloadThread 未经过软件解码的,要输出的硬件解码器解码
thread = new OffloadThread(this, outputStream, *output, mSystemReady);
} else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
|| !isValidPcmSinkFormat(config->format)
|| !isValidPcmSinkChannelMask(config->channel_mask)) {
// DirectOutputThread 不需要软件混音,自己输出到设备
thread = new DirectOutputThread(this, outputStream, *output, mSystemReady);
} else {
// MixerThread 混音后输出,通常都是创建这个
thread = new MixerThread(this, outputStream, *output, mSystemReady);
}
// 保存所有thread到mPlaybackThreads列表
mPlaybackThreads.add(*output, thread);
mPatchPanel.notifyStreamOpened(outHwDev, *output);
// 返回给调用者
return thread;
}
}
return 0;
}
网友评论