音频样本格式 s16p、ffmpeg 或音频编解码器错误?
audio sample format s16p, ffmpeg or audio codec bug?
我有一个视频文件,大约 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 the FFmpeg developers)。
...
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
但这只是一个 hack。有人遇到这个问题吗?如何让ffmpeg正常工作?任何提示表示赞赏。谢谢!
输出格式changed。这样做的原因相当复杂和技术性,但无论如何让我试着解释一下。
大多数音频编解码器的结构使得每个通道的输出最好单独重建,通道的合并(将 "left" 和 "right" 缓冲区交织成一个样本数组 left0 right0 left1 right1 [etc]) 发生在最后。你大概可以想象,如果编码器要再次去交织,那么音频的转码就涉及到两个冗余操作(interleaving/deinterleaving)。因此,所有有意义的解码器都切换为输出平面音频(因此 s16 更改为 s16p,其中 p 表示平面),其中每个通道都是其自己的缓冲区。
所以:如今,交织是在解码后使用重采样库 (libswresample) 完成的,而不是作为解码的一个组成部分,并且只有在用户明确想要这样做的情况下,而不是 automatically/always.
您确实可以将请求样本格式设置为 S16 以强制解码为 s16 而不是 s16p。将此视为一种兼容性 hack,在某些时候将针对它确实适用的少数解码器以及不适用于新解码器的解码器将其删除。相反,请考虑向您的应用程序添加 libswresample 支持,以在解码器的任何本机输出格式与您要用于进一步数据处理的格式(例如使用声卡播放)之间进行转换。
我有一个视频文件,大约 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 the FFmpeg developers)。
...
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
但这只是一个 hack。有人遇到这个问题吗?如何让ffmpeg正常工作?任何提示表示赞赏。谢谢!
输出格式changed。这样做的原因相当复杂和技术性,但无论如何让我试着解释一下。
大多数音频编解码器的结构使得每个通道的输出最好单独重建,通道的合并(将 "left" 和 "right" 缓冲区交织成一个样本数组 left0 right0 left1 right1 [etc]) 发生在最后。你大概可以想象,如果编码器要再次去交织,那么音频的转码就涉及到两个冗余操作(interleaving/deinterleaving)。因此,所有有意义的解码器都切换为输出平面音频(因此 s16 更改为 s16p,其中 p 表示平面),其中每个通道都是其自己的缓冲区。
所以:如今,交织是在解码后使用重采样库 (libswresample) 完成的,而不是作为解码的一个组成部分,并且只有在用户明确想要这样做的情况下,而不是 automatically/always.
您确实可以将请求样本格式设置为 S16 以强制解码为 s16 而不是 s16p。将此视为一种兼容性 hack,在某些时候将针对它确实适用的少数解码器以及不适用于新解码器的解码器将其删除。相反,请考虑向您的应用程序添加 libswresample 支持,以在解码器的任何本机输出格式与您要用于进一步数据处理的格式(例如使用声卡播放)之间进行转换。