对于音频播放异常的问题,由于我们可以拿到解码前后的数据,因此还是比视频播放异常的问题好分析一些的。通过dump解封装后的es数据和解码后的pcm数据,我们可以快速的定位问题出现的大致位置:demux,decoder,aout。本题也是一样,先dump es和pcm数据,发现都没有问题,那基本就是aout部分惹的祸了。
通过加日志,发现在音频播放快结束的时候,aout调用了两次flush。全局搜索aout_DecFlush函数,发现有三种情况下会调用:1.decoder flush;2.decoder delete;3.decoder drain。decoder flush一般都是发生在seek操作后,本问题是自然播放到音频结束,所以两次aout_DecFlush应该是先后发生在decoder drain(消耗解码器缓存)和decoder delete(销毁解码器)中,后续通过加日志也印证了我们的猜测。我们看下aout_DecFlush具体做了啥:
|
这里可以看到,无论wait是否为true,最终都会调用aout_OutputFlush。如果wait为true,就先把没播放完的音频播放完后再flush。那么问题来了,aout_OutputPlay真的能保证音频全部播放完成吗?答案显然是否定的,不然也就不会出现问题了,我们看下audiotrack.c的Play函数:
|