皮皮网

【sscom3.2 源码】【PMOn编译源码失败】【脚本破解带源码】audiopolicymanager源码

2024-11-19 22:33:35 来源:三合一外卖红包小程序源码

1.Android audio_policy_configuration.xml
2.Android Audio简述
3.Android音频模块启动流程分析
4.Android音频(1)_AudioTrack::createTrack

audiopolicymanager源码

Android audio_policy_configuration.xml

        前言

        Android的audioserver 进程启动时,会创建AudioPolicyManager,在构造函数中,首先会去解析audio_policy_configuration.xml文件。

        audio音频数据从一个源走到一个目的都是需要根据配置文件audio_policy_configuration.xml来决定,所以理解configuration配置文件中各个标签项转化为c++实体类的及各成员至关重要。

        audio_policy_configuration.xml为音频audio的设备、流以及路由等配置文件,里面写明了audio音频部分有哪些设备、哪些流以及它们支持的编码、格式以及通道存储布局等等

        audio_policy_configuration.xml中 的<modules>对应每一个audio hal 的so,module中列出的mixPorts,devicePorts和routes解析之后完整的描述了音频的路由规则

module name

        支持“primary” (用于车载使用场景),源码 "A2DP", "remote_submix"和"USB"。模块名称和相应音频驱动程序应编译到 audio.primary.$(variant).so 中

devicePorts

        包含可从此模块访问的所有输入和输出设备(包括永久连接的设备和可移除设备)的设备描述符列表。设备的output和input,不是像mixport那样以role来分,而是以type中有关键字“IN”和“OUT”来区分

mixPorts

        包含由音频 HAL 提供的所有输出流和输入流的列表。每个 mixPort 实例都可被视为传输到 Android AudioService 的物理音频流,stream配置了自己的格式、采样率以及mask,并且分为输出、输入流。一个mixPort标签可能有多个profile属性,也就是支持很多编码格式属性

routes

        定义输入和输出设备之间或音频流和设备之间可能存在的连接的列表。route是把deviceport和mixport连接起来的路由,数据由一个stream输出到另一个device,或者从一个device输出到另一个stream。

Android Audio简述

       audio是Android系统是比较重要的一个模块,本人也涉足时间不是很长,经验还是很少的,只是把自己在工作中所遇到的问题记录。

       Audio 即音频, 也就是控制着手机中的各种声音的输出,比如说,音乐的播放,音量大小,按键音,插入耳机,声音从耳机播放,连接蓝牙,声音从蓝牙耳机中播放。还有一些HiFi播放, offload播放,高清播放。

        常见的问题如下:

        POP音,漏音,声音卡顿,耳机无法识别,还有一些音频通路等问题,还有一些稳定性的问题如:ANR、CRASH、tombstone。还有一些安全漏洞的问题(主要是核心库那里)。

       å›žå½’正题

        -------华丽的分割线-------

        audio分为  应用层,fwk层,native fwk, hal层。

        常见的文件有MediaPlayer.java、 AudioSystem.java、 AudioService.java、AudioManager.java 文件路径(framework/base/media)

        AudioFlinger.cpp、AudioTrack.cpp、 AudioPolicyManager.cpp、 Threads.cpp、Tracks.cpp、 Engine.cpp、 Audiosystem.cpp  文件路径(framework/av)

        audio_hw.c  文件路径(vendor/)

        java文件我在这里就不过多的说了,没啥好讲的,主要说一下c++文件吧。

        AudioFlinger 是音频策略的执行者, AudioPolicyManager是制作音频策略的,AudioTrack是负责播放从上层传过来的PCM数据,简单的说就是负责播放的。 

        audio_hw 是每个HAL层的文件,每个手机厂商自己定制的文件。当然Google也有。

        一般呢,我们处理音频相关的问题呢,有一些特定的套路,需要AP 侧的log, 有时还需要kernel 的log,  当然最主要的是需要音频数据。也就是出现问题时,的声音数据,让我们可以快速的定位出现问题的位置。

       ç®€å•çš„说下播放一首歌曲的流程:(以Android O 为例)

        上层创建一个MediaPlayer对象,然后调用NuPlayer框架(播放器),NuPlayer先将当前歌曲的文件信息读取,采样率,比特率,等之类的东西。然后开始调用audio decoder (音频解码器)  将解码出来的PCM数据传给AudioTrack,  Audiotrack 会创建一个Track,(每一个播放都会创建一个属于自己的track,不用了就销毁,最多可以同时创建个),经过AudioFlinger重采样之后,送到HAL层,HAL层在经过一些混音,降噪之类的处理,将声音送到Codec,然后送给硬件输出,进行播放。

        这个是一个大概的播放流程,如果我们在播放过程中遇到了一些问题,比如说是fwk层的问题,我们就在AudioTrack与AudioFlinger之间寻问题的原因。

        比如说,播放无声,我们需要看AudioPolicyManager中的一些策略是不是将当前的track给mute了。或者是一些其他的原因等。

       è¿™é‡Œåªæ˜¯ç®€å•çš„介绍下Audio,Audio算是一个较为复杂的模块,还需要好好的研究。

Android音频模块启动流程分析

       设备开机后,系统启动时,源码执行位于 /system/etc/init/audioserver.rc 的源码内容,启动 audioserver 服务。源码audioserver 会依次实例化 AudioFlinger、源码AudioPolicyService、源码sscom3.2 源码RadioService、源码SoundTriggerHwService。源码若设备集成了杜比音效,源码则会实例化 DolbyMemoryService。源码audioserver.rc 的源码关键代码在 frameworks/av/media/audioserver/main_audioserver.cpp 的 main() 函数中。

       AudioFlinger 进行初始化,源码PMOn编译源码失败包括创建 MIXER 和 DUPLICATING 类型的源码 playback 线程被创建后的等待延时时间,初始化 PatchPanel 对象,源码并将音频模式设置为 AUDIO_MODE_NORMAL。源码关键代码位于 frameworks/av/services/audioflinger/audioflinger.cpp。

       AudioPolicyService 初始化,创建 AudioPolicyManager 对象。为了兼容老版本,系统提供了两种创建 AudioPolicyManager 的方式,通常使用新方式。关键代码在 frameworks/av/services/audiopolicy/AudioPolicyService.cpp 的 AudioPolicyService::onFirstRef() 函数中。

       在 frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp 文件中,脚本破解带源码createAudioPolicyManager() 函数调用 AudioPolicyManager 的构造函数,解析音频策略配置文件,获取设备支持的音频设备信息,加载所有 HwModule,创建所有非 direct 输出类型的 outputStream 和所有 inputStream,并创建 playbackThread 或 recordThread 线程。Android 7.0 的音频策略配置文件使用 XML 格式,文件名为 audio_policy_configuration.xml。关键代码在 frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp 中。

       至此,Android 系统中的ec-cube源码音频模块启动完成。AudioFlinger 和 AudioPolicyService 创建并运行,设备支持的音频硬件信息由 AudioPolicyManager 解析。插入耳机或 APP 播放音乐时,AudioPolicyService 会接收底层通知,切换 Audio Route。设备播放声音时,音频数据从 AudioTrack 传输到 AudioFlinger,经过 Audio HAL,最终写入硬件。对于此过程的了解,可参考 zyuanyun 的热血大明源码下载文章《Android 音频系统:从 AudioTrack 到 AudioFlinger》,文章内容已清晰阐述。

Android音频(1)_AudioTrack::createTrack

       AudioTrack是Android系统中用于播放音频数据的关键类,它是应用与音频引擎之间的接口。通过使用AudioTrack,开发者可以将解码后的音频数据发送至音频引擎进行播放。AudioTrack的核心操作之一是createTrack,这是在播放音频前必须执行的步骤,用于选择和建立音频通道,并开辟数据传送的内存空间。具体实现中,createTrack操作会创建一个share buffer,该缓冲区既能被AudioTrack写入数据,也能被AudioFlinger读取以进行混音处理。

       在介绍AudioTrack的创建流程时,以MediaPlayerService为例进行详细阐述。这一过程中,首先会设置相关标志,并创建一个名为AudioTrackThread的线程。该线程在暂停状态下运行,直到被调用start()方法后才开始活动。AudioTrack的创建涉及一系列关键步骤,包括与AudioFlinger的交互、获取输出设备、以及最终创建实际的AudioTrack实例。

       在获取输出设备的过程中,AudioPolicyService的getOutputForAttr方法发挥着核心作用。这一方法根据特定属性获取对应输出,实际上是在AudioPolicy的服务范畴内进行操作。在汽车等特定应用场景中,如果系统支持动态路由,这一过程会通过AudioPolicyMix处理。通常情况下,通过AudioSystem调用AudioPolicyService的getOutputForAttr方法,最终将selectedDeviceId属性赋值。

       之后,Audio系统通过AudioPolicyManager的getOutputForAttr方法获取输出设备。在播放音乐的场景中,最终选择的输出设备是AUDIO_DEVICE_OUT_SPEAKER。获取设备之后,Audio系统会进一步调用getOutputForDevice方法,从当前存在的设备集合中选择一个符合策略和格式要求的输出。在播放音乐的例子中,这里会设置flags为AUDIO_OUTPUT_FLAG_DEEP_BUFFER,以优化音频播放体验。

       在选择输出设备后,Audio系统会根据提供的输出设备ID获取对应的PlaybackThread,这一过程发生在AudioPolicy初始化时。之后,Audio系统创建匿名共享内存,分配大小通常基于配置的audio buffer大小,例如A设备可能会分配大约7M的共享内存。然后,通过构造MemoryDealer和heap()及allocate()操作,系统从共享内存中获取所需大小的内存块。

       创建AudioTrack的关键步骤包括TrackBase构造函数的调用,该函数首先计算音频缓冲区的大小,并分配相应的内存空间。Audio buffer的结构包括头部的audio_track_cblk_t和后续的音频PCM数据。从已创建的共享内存中获取大小匹配的内存空间,并通过构造共享内存的句柄完成分配过程。最终,通过MemoryDealer和heap()及allocate()操作,AudioTrack得以成功创建,从而实现在Android系统中的音频播放。