ffmpeg av libs可以返回一个精确的PTS吗?

我正在使用一个使用IBBP ... GOP序列的MPEG流。返回前4个AVPackets的(DTS,PTS)值如下:I =(0,3)B =(1,1)B =(2,2)P =(3,6)

I帧上的PTS看起来像是合法的,但是B帧上的PTS不能正确,因为B帧不应该在I帧之前显示,因为它们的PTS值表示。我也尝试解码数据包,并在生成的AVFrame中使用pts值,将PTS始终设置为零。

有没有办法从ffmpeg中获得准确的PTS?如果不是,那么同步音频的最佳方法是什么?

0

2 答案

我想我最终根据 http://www.dranger中的评论发现了一些情况。 COM /的ffmpeg/tutorial05.html

ffmpeg重新排列数据包,以便由avcodec_decode_video()处理的数据包的DTS始终与它返回帧的PTS相同

翻译:如果我将一个数据包送入具有12的PTS的avcodec_decode_video(),avcodec_decode_video()将不会返回该数据包中包含的解码帧,直到我给它一个后来的包,其DTS为12.如果数据包的PTS与其DTS相同,则给出的数据包与返回的帧相同。如果数据包的PTS比它的DTS迟了2帧,那么avcodec_decode_video()会延迟帧并且不会返回它,直到我提供2个数据包。

基于这种行为,我猜测av_read_frame()可能会重新排列IPBB到IBBP的数据包,这样avcodec_decode_video()只需要缓冲3帧而不是5帧的P帧。例如,输入和这个排序的P帧的输出是3(6 - 3):

|                  I B B P B B P
|             DTS: 0 1 2 3 4 5 6
| decode() result:       I B B P

与标准排序(6 - 1)相差5:

|                  I P B B P B B
|             DTS: 0 1 2 3 4 5 6
| decode() result:       I B B P

but that is pure conjecture.

0
额外

我相当肯定你正在获得准确的价值。如果您将MPEG流视为流,那么它可能会有所帮助。在那种情况下,在你看到的IBBPBB之前通常会有另一个GOP。也许像这样(使用与原始问题相同的符号):

P(-3,-2)  B(-2,-1)  B(-1,0)

基本上,I帧之后的B帧基于I帧和来自之前 GOP的最后一个P帧。

虽然从视频开始看起来合乎逻辑:

Start GOP: IPBBPBBPBB...

稍后它必须是

Start GOP: IBBPBBPBBPBB
Start GOP: IBBPBBPBBPBB
Start GOP: IBB... 

请记住,解码任何B帧需要在它之前和之后有一个完整的帧。因此,每对B帧应该在文件之前的I或P帧之前显示。

FFMPEG可能只是放弃了第一个GOP的“特殊情况”。

由于前两个B帧没有先前的帧进行操作,因此应该能够安全地丢弃它们。只需将第一帧中的时间戳重新分配,并将音频流调整为相同的数量即可。

这是否会导致帧丢失取决于FFMPEG的实现,但更糟糕的情况是,您会失去83毫秒(24帧/秒时2帧)。

0
额外
这些类型的黑客(接受2帧的损失)是...哈克:)写文档的无聊感觉太无聊了,几乎没有人会困扰。
额外 作者 Roman Starkov,