android音频概念解析

音频硬件接口(我们可以理解为ASOC的声卡)

官方代码里叫audio hardware interface

也称为module,定义在services/audiopolicy/config/audio_policy_configuration.xml:

分别有primary,a2dp,usb,r_submix(用于 音频数据回环);

配置文件中的每一个module都被描述为HwModule,保存在mHwModules中;

output(devcie+thread) 我们可以理解为ASOC的substream概念

可以理解成是软件的输出通道,类比文件IO系统里面的stream概念。常用的输出通道类型有:

prmary_out,low_latency,deep_buffer,compress_offload,mutil_channel等;

定义在services/audiopolicy/config/audio_policy_configuration.xml;

每个输出通道类型都可以路由(route)到speaker,蓝牙设备,HDMI接口等;

配置文件中的每一个output都被描述为OutputProfile,保存在module->mOutputProfiles中;
这是一种常见的代码设计 思想,将能力级和实体解耦!

SwAudioOutputDescriptor

Output的描述符,真正的output实体,以output为句柄,保存在AudioPolicyManager的mOutputs中;

可以通过flag,device,streamtype去获取;

注意和outputprofile之间的区别。

PlaybackThread(对output中的数据进行搬运工作)

回放线程。

output在创建同时,会创建一个与之一一对应的PlaybackThread,句柄为output,保存在AudioFlinger的mPlaybackThreads中;

PlaybackThread的类型与配置文件中output的flag有关。

PlaybackThread与output一一对应,一旦确定了output,也就确定了PlaybackThread;

stream与Strategy

流类型很多,需要为将他们分类,将具有相同行为的stream分成一组,它们用一个Strategy:

具有相同行为的Stream:播放的设备一样,device相同,播放优先级相同。

stream,strategy,device,output,flag以及playbackthread之间如何关联起来?

①解析配置文件时,音频系统会将所有支持的output打开并初始化(如果没有活跃的track对应的thread会standby,减少CPU loading):

markup 复制代码
-->打开output
-->根据flag创建playbackthread

-->以output为句柄保存playbackthread;

播放声音时:

markup 复制代码
-->每个audiotrack都由自己的流类型stream type

-->根据streamtype匹配对应的strategy

-->根据strategy确定播放的设备device

-->根据device,flag确定所有符合条件的outputs
-->根据format,flags从ouputs中选择最中意的output

-->根据output确定playbackthread

-->通过Iaudiotrack把声音数据传给这个thread(这里就可以用到audiotrack那片文章的知识了)

8.AudioPolicyService启动过程

①读取解析配置文件

②根据配置文件调用AudioFlinger的服务,打开output,创建线程;

AudioPolicyService启动

读取解析配置文件

根据配置文件调用AudioFlinger,打开output,创建线程

markup 复制代码
void AudioPolicyService::onFirstRef()
     //所有的服务代码都需要线程/进程实体作为自己的承载,不然无法和调用方异步
    // start tone playback thread
    mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
    // start audio commands thread
    mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
    // start output activity command thread
    mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
    /*mAudioPolicyClient 就是AudioFlinger的客户端
     */
	mAudioPolicyClient = new AudioPolicyClient(this);
	mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);

createAudioPolicyManager(mAudioPolicyClient)主要就是构建AudioPolicyManager,在AudioPolicyManager里面解析配置文件。

AudioPolicyService启动过程(策略加载以及音频服务体系构建)

a. 对于配置文件里的每一个module项, new HwModule(name), 放入mHwModules数组;

对于module里的每一个output, new IOProfile, 放入module的mOutputProfiles;

对于module里的每一个input, new IOProfile, 放入module的mInputProfiles;

b. 根据module的name加载厂家提供的so文件 (通过AudioFlinger来加载)

c. 打开对应的output (通过AudioFlinger来open output)

output选择的优先级

output的选择由AudioTrack创建引起,最终会走到AudioPolicyManager::getOutputForDevice()中;

选择output的逻辑优先级是:

flags > Format > primary > outputs0

相关推荐
urhero44 分钟前
Python+ffmpeg 实现给视频添加字幕
ffmpeg·音视频·python编程·视频编辑·实用视频工具·添加字幕
每次的天空1 小时前
Android学习总结之Binder篇
android·学习·binder
峥嵘life1 小时前
Android 有线网开发调试总结
android
hvinsion2 小时前
【Python开源】深度解析:一款高效音频封面批量删除工具的设计与实现
python·开源·音视频
是店小二呀2 小时前
【算法-链表】链表操作技巧:常见算法
android·c++·算法·链表
zhifanxu4 小时前
Kotlin 遍历
android·开发语言·kotlin
18538162800余--4 小时前
短视频矩阵系统批量剪辑模式开发详解,支持OEM
线性代数·ui·矩阵·音视频·概率论
追随远方4 小时前
Android NDK版本迭代与FFmpeg交叉编译完全指南
android·ffmpeg
带鱼工作室5 小时前
ffmpeg多媒体(音视频)处理常用命令
ffmpeg·音视频
学术裁缝李师傅13 小时前
三款实用工具推荐:配音软件+Windows暂停更新+音视频下载!
音视频·开源软件·实用工具·软件分享