2016-02-05 925 views
1

我有一个视频文件,并且我在近3年前将视频信息转储到ffmpeg的txt文件中。音频采样格式s16p,ffmpeg或音频编解码器错误?

... 
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正确工作?任何暗示是赞赏。谢谢!

+0

请参阅http://stackoverflow.com/q/18888986/5726027 – Mulvya

+0

我知道s16和s16p之间的区别。我的问题是关于ffmpeg用新旧版本输出不同的音频信息。我的测试视频是s16,但新的ffmpeg说它是s16p。 – Arton

+0

ffplay可以很好地播放视频,所以我认为界面可能会发生很大变化,我会跟踪ffplay来找出根本原因。 – Arton

回答

3

输出格式changed。原因是相当复杂和技术性的,但让我尝试解释它。

大多数音频编解码器的结构使得每个通道的输出最好单独进行重构,并且将通道合并(将“左”和“右”缓冲器交织成一排样本,排序为left0 right0 left1 right1 [etc ])发生在最后。您大概可以想象,如果编码器想要再次解交织,则音频转码涉及两个冗余操作(交织/解交织)。因此,所有有意义的解码器都切换到输出平面音频(因此s16变为s16p,其中p表示平面),其中每个通道都是自己的缓冲区。因此:现在,在解码之后使用重新采样库(libswresample)完成交织,而不是作为解码的组成部分,并且仅在用户明确希望这样做时,而不是自动/总是。

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

+0

但是为什么当前ffprobe不能正确地报告旧文件中使用的打包方案? – Mulvya

+0

打包不依赖于文件(或编解码器,例如mp2),它取决于解码器(实现)。目前的ffprobe使用当前的ffmpeg mp2解码器,该解码器本身为所有文件输出s16p。旧的ffprobe使用旧的ffmpeg mp2解码器,它本身为所有文件输出s16。 –

+0

这可以帮助我很多!描述非常清楚。非常感谢你! – Arton