音频样本格式s16p,ffmpeg或音频编解码器bug?

时间:2016-02-05 14:12:01

标签: audio video ffmpeg codec

我有一个视频文件,我将视频信息转发到近3年前使用ffmpeg的txt文件。

...
Stream #0:1[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16, 256 kb/s
Stream #0:2[0x1c1]: Audio: mp2, 48000 Hz, stereo, s16, 256 kb/s

但是当我使用更新ffprobe(ffprobe版本N-78046-g46f67f4版权所有(c)2007-2016 FFmpeg开发人员)时,我发现格式发生了变化。

...
Stream #0:1[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16p, 256 kb/s
Stream #0:2[0x1c1]: Audio: mp2, 48000 Hz, stereo, s16p, 256 kb/s

使用相同的视频,其样本格式更改为s16p。

我实现了一个使用ffmpeg的简单视频播放器。它可以在3年前播放视频,但在更改为更新ffmpeg后无法输出正确的pcm流。我花了很多时间,终于发现音频应该是s16而不是s16p。在调用avcodec_decode_audio4之前添加了行之后,解码后的音频流工作,

audio_codec_ctx->sample_fmt = AV_SAMPLE_FMT_S16

但它只是一个黑客。有人遇到过这个问题吗?如何让ffmpeg正常工作?任何提示都表示赞赏。谢谢!

1 个答案:

答案 0 :(得分:4)

输出格式changed。这样做的原因相当复杂和技术性,但无论如何我都要尝试解释它。

大多数音频编解码器的结构使得每个通道的输出最佳地单独重建,并且通道的合并(将"左"和#34;右"缓冲区交织成阵列有序的样本left0 right0 left1 right1 [etc])发生在最后。您可以想象如果编码器想要再次解交织,那么音频的转码涉及两个冗余操作(交错/解交织)。因此,所有有意义的解码器都切换到输出平面音频(所以s16改为s16p,其中p表示平面),其中每个通道都是自己的缓冲区。

所以:现在,交换是在解码后使用重采样库(libswresample)完成的,而不是作为解码的组成部分,并且只有在用户明确想要这样做时才进行,而不是自动/始终。 / p>

您确实可以将请求样本格式设置为S16,以强制解码为s16而不是s16p。考虑这是一个兼容性黑客,它将在某些时候被删除它为其工作的少数解码器,也是一个不适用于新解码器的解码器。相反,请考虑向应用程序添加libswresample支持,以便在解码器的本机输出格式和您希望用于进一步数据处理的格式(例如使用声卡播放)之间进行转换。