你好!这里是风筝的博客,
欢迎和我一起交流。
自从去年来了手机厂搬砖,就好久没有更新了,实在是太忙了。。。。。。
现在疫情原因,就居家办公了,抽空整理下最近遇到的一些音频问题,供大家学习参考。
测试报了一个拍照音卡顿的问题: 【前提条件】【Prerequistes】暗环境 【操作步骤】【Operation steps】夜景模式点击拍照 【实际结果】【Actual results】拍照声音卡顿
emmm,卡顿问题在音频里面老生常谈了,拿到log之后,打开音频dump文件看了下,主要查看ivdump信号。 ivdump是功放的反馈信号,反馈了功放这边输出的的信号。
打开正常拍照音的ivdump:
可以看出,频谱信号还是比较连贯的,没有卡顿的现象。
打开异常的拍照音ivdump:
可以看出频谱那里出现了异常,数据断开了,有个26ms左右的空缺,也就是出现了卡顿。 说明PA播放确实出现了卡顿。
但是进一步查看framework里服务层要往HAL写的数据的dump,也就是StreamOut.wav,未发现异常,说明上层服务传下来的音源数据是正常的。 再次查看HAL往kernel写的数据的dump,也就是TaskPlayback_dataout.pcm,居然也是正常的,这就比较奇怪了。
之前文章就说过,如果音源没问题的话,卡顿问题总归就两种情况: 1.overrun:写数据快,播数据慢,导致buffer满了,导致卡顿。 2.underrun:写数据慢,播数据快,导致buffer空了,无数据可播,出现卡顿。
打开kernel log看了下:
- -(0)[13588:writer]snd_audio_dsp snd_audio_dsp: mtk_dsp_start() task id:10 adsp xrun
简单log里搜了下,确实出现了xrun,不过没标明是overrun还是underrun,而且不像以前接触的芯片通路比较简单,现在高端点的芯片都是带ADSP的,涉及DSP确实不太好搞。 而且手机场景比较多且繁杂,我也不好随意更改buffer size,因为会增大播放时延。
现在一般Kernel和ADSP代码都是由芯片原厂维护,我们厂商音频一般不太好看,所以一般我都是从上层入手分析。
卡顿问题一般都是由性能原因引起的,重新抓了systrace分析。 查看log:
06:07:21.408285 19316 10173 D AudioTrack: start(45): prior state:STATE_STOPPED output 29 stream 1 session 225
06:07:21.408662 935 1227 D APM_AudioPolicyManager: startOutput() output +++ 29, stream 1, session 225
06:07:21 时间Track开始起播,记住这个时间点。
打开perfetto工具网站:https://ui.perfetto.dev/#!/viewer
导入抓到的trace文件,网上有很多教怎么抓trace的文章,我就不累述了。 搜索surfaceflinger ,查看时间点,看到包含06:07:21这个时间点:
就说明本次trace有正常抓到出异常那个时间点,上面的nRdy是播放的数据,说明这个点在播放拍照音,OK,log对得上。
之后分别星标nRdy、AudioOut、write这几个线程: nRdy是服务层传下的要播放的数据,可以看到,再HAL层的write线程,出现了一个橙色的表示,长达27ms,和文章开头的拍照音卡顿的间隔时间差不多一样,就是这里出了问题。
systrace里一般有四种状态:
- running(runnable过多考虑是否cpu过忙,无法及时完成调度
- runnable(running过长考虑是否线程做事太多
- sleeping(sleeping过多考虑是否被其他线程blocking住
- uninterruptible sleep(uninterruptible sleep过多可能IO过重
这个橙色是Uninterruptible Sleep状态,看起来是卡IO了,从perfetto看,没有写non-IO或者IO,也不太确定是什么引起的,看唤醒关系的话,往后找running状态,找它是被谁唤醒的:
发现是com.oplus.camera唤醒了HAL里面write线程,所以可能和camera有比较大的关系。
继续看其他几个Uninterruptible Sleep状态,查看他的running,是kworker24035唤醒:
查看kworker24035,前面确实出现一大段时间的Uninterruptible Sleep:
看来确实由24035这个线程号引起的!
查看ps文件,查找24035是哪个线程:
root 24035 24035 2 0 0 cmdq_pkt_wait_complete 0 D kworker/u16:3
看起来是cmdq_pkt_wait_complete这个函数,但是看了下也不知道是谁在调用这个API,看起来是公用的,囧。。。
不过按前面分析,camera嫌疑比较大,和camera的同事沟通了下,他们果然给出了方案: 1.音乐播放场景,取消camera调度补偿,播放停止恢复camera调度补偿。 2.提升前台播放app的小线程调度优先级 3.camera 对负载开销优化
camera同事这三把斧下来,问题果然不复现了。
总结下来,虽然问题不是音频这边导致的,但是还要分析是谁导致的问题,真累啊
|