蓝牙音乐(A2DP)音频延迟的一些感想跟分析,让你对A2DP体验更佳深入
零.声明
最近做蓝牙协议栈的过程中遇到一些客户偶尔提报音频延迟的问题,所以引发了一些感想,跟大家分享下,音频延迟主要的影响范围是对一些要求实时性比较高的场景有比较差的体验
- 连接蓝牙看视频的过程中,发现音画不同步,比如看电影,看抖音等一些视频类的内容
- 游戏过程中,需要对声音有实时判断的,比如竞技类游戏之类的
- 导航过程中,声音延迟,影响比较大,尤其是我直观的体验一个场景的痛点,就是在高速交叉口的时候,有的时候开车并不会一直盯着屏幕看,反而会听语音播报,但是有的时候交叉口很近的才出来播报,导致措手不及
当然还有其他场景,我只是列举了几个我能想到的。说完这些,那我就从理论的角度给大家分析下这个问题,首先我想公布结论:对于蓝牙连接,没办法完全消除延迟,只能尽量让这个延迟变小。
本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下:
第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。
第二篇:Transport层介绍,主要介绍蓝牙协议栈跟蓝牙芯片之前的硬件传输协议,比如基于UART的H4,H5,BCSP,基于USB的H2等
第三篇:传统蓝牙controller介绍,主要介绍传统蓝牙芯片的介绍,包括射频层(RF),基带层(baseband),链路管理层(LMP)等
第四篇:传统蓝牙host介绍,主要介绍传统蓝牙的协议栈,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的协议吧。
第五篇:低功耗蓝牙controller介绍,主要介绍低功耗蓝牙芯片,包括物理层(PHY),链路层(LL)
第六篇:低功耗蓝牙host介绍,低功耗蓝牙协议栈的介绍,包括HCI,L2CAP,ATT,GATT,SM等
第七篇:蓝牙芯片介绍,主要介绍一些蓝牙芯片的初始化流程,基于HCI vendor command的扩展
第八篇:附录,主要介绍以上常用名词的介绍以及一些特殊流程的介绍等。
另外,开发板如下所示,对于想学习蓝牙协议栈的最好人手一套。以便更好的学习蓝牙协议栈,相信我,学完这一套视频你将拥有修改任何协议栈的能力(比如Linux下的bluez,Android下的bluedroid)。
-------------------------------------------------------------------------------------------------------------------------
蓝牙视频教程(跟韦东山老师合作):
https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22329603896.20.5aeb41f98e267j&id=693788592796
蓝牙交流扣扣群:765961169
入手开发板:https://shop220811498.taobao.com/category-1542116976.htm?spm=a1z10.5-c-s.w4010-22329603913.7.39ca7dbe2EA0K3&search=y&catName=%C0%B6%D1%C0%BF%AA%B7%A2%B0%E5#bd
蓝牙学习目录:一篇文章足够你学习蓝牙技术,提供史上最全的蓝牙技术(传统蓝牙/低功耗蓝牙)文章总结,文档下载总结(2020/12/11更新)_Wireless_Link的博客-CSDN博客_蓝牙eir
--------------------------------------------------------------------------------------------------------------------------
一. A2DP的架构
我们先来介绍下整个A2DP audio path的框架
A2DP source的发送流程
UL(Upper Layer)收集到PCM数据,然后发送到A2DP,A2DP经过codec算法(SBC/AAC/APTX/LDAC/LHDC..)压缩成特定的音频格式,然后交给AVDTP,AVDTP转交给L2CAP,L2CAP通过ACL格式转交给HCI,然后到达BT chip,通过RF射频出去。
A2DP sink的接收流程
BT chip通过RF接收进来数据,然后通过ACL交给HCI,然后交给L2CAP,L2CAP交给AVDTP,AVDTP交给A2DP,A2DP收到的是remote经过压缩的数据,此时通过codec算法(SBC/AAC/APTX/LDAC/LHDC..)解压成PCM数据,然后交于声卡播放
我们在拿一个Source设备(手机)跟一个Sink设备(车载/耳机/音箱)来举例子看下整个结构
整个流程跟上面的A2DP类似,所以我们就不介绍了
二. 延迟原因分析
所以从这个框架中就可以总结归纳出来整个音频延迟可能原因
NOTED: 在这里注意下,音频延迟跟音频卡顿分析思路完全不同,有的人可能会混淆,有机会我再通过另外一篇文章来介绍下音频卡顿的分析思路。
大体的可能得原因如下:
另外,市面上大部分的实测数据如下:
当然这个是多方面原因造成的音频延迟,我们就来拆解下。
1. codec算法本身造成的音频延迟
编解码器 | 开发厂商 | 理论单帧延迟 | 关键设计原理 | 帧尺寸(典型值) |
SBC | SIG | 15~30 ms | 固定分帧(4/8子带) | 4~6 ms音频数据 |
AAC | Fraunhofer IIS | 5~20 ms | 可变分帧(1024/960样本) | 20~24 ms音频数据 |
aptX | 高通 | 1.92 ms | 固定4样本块处理(16kHz子带) | 1.92 ms音频数据 |
aptX HD | 高通 | 2.6 ms | 增强量化精度(24bit) | 2.6 ms音频数据 |
aptX LL | 高通 | 0.67 ms | 超小帧(80样本@48kHz) | 1.67 ms音频数据 |
aptX Adaptive | 高通 | 1~2 ms | 动态帧调整(80~512样本) | 1~6 ms音频数据 |
LDAC | Sony | 8~10 ms | 大帧优化音质(512/1024样本) | 5~10 ms音频数据 |
LC3 | SIG | 0.125 ms | 超短帧(10样本@48kHz) | 0.25 ms音频数据 |
LHDC | Savitech | 3~5 ms | 可变分帧(256/512样本) | 3~6 ms音频数据 |
⚠️ 注意:
- 理论延迟 ≠ 实际端到端延迟(需叠加传输/缓冲/渲染等环节)
- 帧尺寸越小延迟越低,但抗丢包能力下降(需更频繁传输)
当然上面的数据也不一定是绝对的哈·,也要结合多方面因素来考虑
我们来算一个SBC的理论延迟吧,比如一个AVDTP package是1K的数据,然后4-5倍压缩率,所以解压后大概一帧是5K数据,而44.1Khz + 16bit位深 + 2Channel的1S的数据量173Kbyte,是28ms的理论延迟。
也就是你当下要发的数据,必须要等着5K数据压缩完毕才能发送给对方。所以对方收到的第一包数据一定是28ms以前的数据,这个就是理论延迟
2. Sink原因
a. 缓冲buffer过大
为什么会有缓冲buffer呢,在介绍这个之前,我们就要介绍下jitter的概念了,什么是jitter呢?就是比如上面我们介绍了一包数据是28ms的延迟,也可以理解为每包duration如果所有都恒定,那么duration都应该是28ms,但是由于是无线,所以肯定会存在干扰等因素,导致包肯定有重传等,所以在空口的duration肯定不是那么恒定的,比如来了28ms的数据,你就直接播放,那么由于空口有干扰,导致下个包是50ms来(这个是假定制),那么你本应该在29ms播放的时候发现没有数据了,所以这时候会存在22ms的空档没有数据期,所以就会卡存,比如这种空口包
可以看到只要有duration增大的情况,那么后面一定会有duration小的数据过来来补充,我们就成为这种现象为jitter.
为了避免这种情况,所以sink端一定会有缓冲buffer来降低这个卡顿风险,但是谈到这里学问就大了·,你增大缓冲buffer是解决了卡顿的风险,但是就带来了我们本章的问题了,就是莫名其妙多了延迟了,比如你缓冲buffer缓冲100ms,那么就额外多了100ms的延迟。这时候我们就要在特定的平台来权衡这个数值了,这个方面在不同的平台调整的值策略不同,要实测
b. 协议栈调度异常
这个没有啥好介绍的,就是协议栈的调度问题,协议栈的接收或者playback倍其他task或者thread抢占,拿不到资源,这个可能会引起音频卡顿,也可能会引起来音频延迟。
c. 平台驱动问题
平台驱动也会有音频缓冲
ⅰ. Linux驱动缓冲原理
关键参数:
参数 | 内核结构字段 | 影响 | 典型值 |
buffer_size |
| 总缓冲区大小 | 1024-8192帧 |
period_size |
| 单次传输量 | 256-1024帧 |
period_count | 由buffer_size/period_size推导 | 中断频率 | 2-8个周期 |
ⅱ. Android缓冲原理
AudioFlinger 混合缓冲区
- FastMixer线程:专用于低延迟场景(游戏/录音)
- 混合缓冲区大小:默认20ms(可动态调节)
AAudio 直通模式
[App] → [AAudio API] → [HAL层] → [DMA Buffer]
- 绕过AudioFlinger,减少>40ms延迟
- 要求:Android 8.0+,支持
MMAP
的硬件
层级 | 延迟范围 | 可优化极限 |
应用层缓冲 | 10-100ms | 1ms (AAudio) |
AudioFlinger混合 | 20-40ms | 0ms (Bypass) |
内核环形缓冲 | 5-30ms | 2ms (MMAP) |
DMA传输 | 0.5-2ms | 硬件固定 |
Codec处理 | 1-10ms | 硬件固定 |
Android总延迟 | 36-182ms | <15ms |
ⅲ. RTOS
RTOS等就要看SDK的编写源码了
3. Source原因
a. Delay report
Delay report是蓝牙SIG在AVDTP/A2DP提出来的协议规范,就是为了解决音画不同步的问题,但是这个要依赖于sink跟source都支持,什么原理呢?很简单
在连线的时候A2DP sink会告知Source我的delay report时间是多少,Source收到后,在处理视频的时候本来应该当下发送视频,但是因为他知道sink的延迟是多少,所以音频先于视频delay report的时间发送,也就是 音频先于视频早达到delay report的时间,所以就规避了音画不同步的问题·
但是目前看下来支持的Source设备还是比较少,加上现在的一些视频类的APP也不会关注这个点,所以生态个人感觉还不是那么好!
b. UL层送数据延迟
这个也没啥好解释的哈,看标题就能看出来,由于系统问题,Source数据就是送的慢,所以导致到了sink端没有那么及时
三. 未来方向
音频延迟一直在无线领域是一个比较大的课题,想真正解决或者说让end user无感知,还是比较难得,所以百花齐放,有几个点可能要重点关注下。
1. LC3编解码器(LE Audio核心)
通过0.25ms超短帧 + 前向纠错实现端到端<30ms
突破性设计
参数 | 传统SBC/AAC | LC3 | 优势 |
帧长度 | 5~30ms | 0.25ms | 降低基础延迟10倍 |
处理复杂度 | 50 MIPS | <15 MIPS | 功耗降低60% |
抗丢包能力 | 需20%重传 | FEC冗余 | 容忍15%丢包不中断 |
动态码率范围 | 固定 | 64-1024kbps | 自适应网络环境 |
实测延迟表现
场景 | 端到端延迟 | 对比传统编解码 |
语音通话 | 18-22ms | 比aptX LL低40% |
游戏音频 | 25-28ms | 比LDAC低85% |
多设备广播 | 32ms | 首支持≤50ms同步 |
2. 双通道直传
如苹果H2芯片的并行串流,规避中继延迟
- 异构计算架构
-
- 主处理器:处理降噪/空间音频(占用<5% CPU)
- 射频模块:独立管理双通道时序同步(精度±2μs)
- 私有协议优化
-
- 频段:2.402-2.481GHz动态避让Wi-Fi
- 时隙:将传统蓝牙32时隙压缩至8时隙
3. AI预测缓冲
高通S7平台可预测下一帧内容,减少20%缓冲时间
ⅰ. 核心技术创新
模块 | 功能描述 | 延迟优化效果 |
音频特征提取 | 20ms内识别音乐/语音/枪声 | 减少分析延迟 |
LSTM预测模型 | 预测未来80ms音频内容 | 缓冲降低20% |
动态码率适配 | 根据网络质量切换aptX Adaptive | 避免重传延迟 |
端侧推理引擎 | Hexagon NPU加速(15TOPS) | 推理耗时<1ms |
ⅱ. 实测数据(Snapdragon Sound Gen 2)
场景 | 传统方案延迟 | AI预测方案 | 提升幅度 |
地铁中游戏音频 | 142ms | 89ms | -37% |
拥挤WiFi环境 | 210ms | 121ms | -42% |
设备跨房间传输 | 185ms | 98ms | -47% |