当前位置: 首页 > news >正文

Android11 AudioTrack 创建过程

Android 系统播放声音,需要创建AudioTrack来和AudioFlinger通信,其创建过程如下
在这里插入图片描述

  1. 根据传入的声音属性得到output
  2. 通过得到的output,找到播放线程
  3. AudioFlinger在播放线程内,创建Track,和AudioTrack对应。后续通过它们进行通信

接下来分别看下其过程

找到output
在getOutputForAttr函数内,直接调用getOutputForAttrInt函数

//frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
status_t AudioPolicyManager::getOutputForAttrInt(audio_attributes_t *resultAttr,audio_io_handle_t *output,audio_session_t session,const audio_attributes_t *attr,audio_stream_type_t *stream,uid_t uid,const audio_config_t *config,audio_output_flags_t *flags,audio_port_handle_t *selectedDeviceId,bool *isRequestedDeviceForExclusiveUse,std::vector<sp<AudioPolicyMix>> *secondaryMixes,output_type_t *outputType)
{DeviceVector outputDevices;const audio_port_handle_t requestedPortId = *selectedDeviceId;DeviceVector msdDevices = getMsdAudioOutDevices();const sp<DeviceDescriptor> requestedDevice =mAvailableOutputDevices.getDeviceFromId(requestedPortId);*outputType = API_OUTPUT_INVALID;status_t status = getAudioAttributes(resultAttr, attr, *stream);//将attr赋值给resultAttr//省略outputDevices = mEngine->getOutputDevicesForAttributes(*resultAttr, requestedDevice, false);//根据resultAttr,找到device//省略if (*output == AUDIO_IO_HANDLE_NONE) {*output = getOutputForDevices(outputDevices, session, *stream, config,flags, resultAttr->flags & AUDIO_FLAG_MUTE_HAPTIC);//根据device,找到output}//省略
}

1,找到device

//frameworks/av/services/audiopolicy/enginedefault/src/Engine.cpp
DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes,const sp<DeviceDescriptor> &preferredDevice,bool fromCache) const
{product_strategy_t strategy = getProductStrategyForAttributes(attributes);//省略return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
}

首先,通过声音属性,从mProductStrategies中找到strategy,然后根据strategy,找到对应的device。getDevicesForProductStrategy这个函数由厂商自定义,修改声音的音频策略,大多数情况下可以修改这个函数。

2,根据device,找到output

//frameworks/av/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
audio_io_handle_t AudioPolicyManager::getOutputForDevices(const DeviceVector &devices,audio_session_t session,audio_stream_type_t stream,const audio_config_t *config,audio_output_flags_t *flags,bool forceMutingHaptic)
{//省略if (audio_is_linear_pcm(config->format)) {SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);*flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_DIRECT);output = selectOutput(outputs, *flags, config->format, channelMask, config->sample_rate);}return output;}

mOutputs中,支持该device的output可能有多个,通过getOutputsForDevices把它们找出来,然后调用selectOutput从中选择一个最符合的。怎么从中找到最合适的output,可以看其注释

	// select one output among several that provide a path to a particular device or set of// devices (the list was previously build by getOutputsForDevices()).// The priority is as follows:// 1: the output supporting haptic playback when requesting haptic playback// 2: the output with the highest number of requested functional flags// 3: the output supporting the exact channel mask// 4: the output with a higher channel count than requested// 5: the output with a higher sampling rate than requested// 6: the output with the highest number of requested performance flags// 7: the output with the bit depth the closest to the requested one// 8: the primary output// 9: the first output in the list

综上,找到output的流程为: audio_attributes_t >>> strategy >>> device >>> output

找到播放线程

AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
{return mPlaybackThreads.valueFor(output).get();
}

根据output,从mPlaybackThreads中找到对应的播放线程

创建Track

//frameworks/av/services/audioflinger/Threads.cpp
sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(/*省略*/)
{//省略track = new Track(this, client, streamType, attr, sampleRate, format,channelMask, frameCount,nullptr /* buffer */, (size_t)0 /* bufferSize */, sharedBuffer,sessionId, creatorPid, uid, *flags, TrackBase::TYPE_DEFAULT, portId,SIZE_MAX /*frameCountToBeReady*/, opPackageName);//省略mTracks.add(track);//省略
}

AudioFlinger的PlaybackThread中有一个mTracks数组,先创建Track,然后将该Track保存到mTracks中。

总结
应用程序创建AudioTrack,导致在对应的播放线程内,创建Track和其对应。如何找到对应的播放线程?

  1. 根据传入的声音属性,找到strategy
  2. 根据strategy ,找到device
  3. 根据device找到output
  4. 根据output,从mPlaybackThreads中找到对应的播放线程
http://www.lryc.cn/news/362018.html

相关文章:

  • 数学建模 —— 层次分析法(2)
  • Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:人工智能消防应用
  • Flutter 中的 KeepAlive 小部件:全面指南
  • C语言 恼人的结合性和优先级和副作用
  • Vue——初识组件
  • MQ消息丢失/重复/顺序/挤压
  • 利用Quarkus构建高效微服务——Java的云原生革新
  • python 批量ts合并成一个mp4
  • Java | Leetcode Java题解之第129题求根节点到叶节点数字之和
  • SpringBoot【注解 01】@Scheduled实现定时任务的串行和并行执行
  • 【工具】redis的安装使用
  • 汇编:数据定义数据填充
  • Python画图(多图展示在一个平面)
  • python-web应用程序-Django数据库-操作表中的数据
  • 绕过WAF(Web应用程序防火墙)--介绍、主要功能、部署模式、分类及注入绕过方式等
  • 11.7 堆排序
  • Patchwork++:基于点云的快速、稳健的地面分割方法
  • Llama改进之——分组查询注意力
  • 英伟达开源新利器NV-Embed向量模型,基于双向注意力的LLM嵌入模型,MTEB 56项任务排名第一
  • JVM之【GC-垃圾清除算法】
  • 数据分析每周挑战——心衰患者特征数据集
  • 单例模式(Java实现)
  • 24.面向对象六大原则
  • Vue3-shallowRef与shallowReactive
  • CI/CD(基于ESP-IDF)
  • 聚观早报 | 东风奕派eπ008将上市;苹果Vision Pro发布会
  • k8s牛客面经篇
  • 第9周 基于MinIO与OSS实现分布式与云存储
  • 【Linux内核-编程指南】
  • Go 编程风格指南 - 最佳实践