ffmpeg av libs可以返回准确的PTS吗?

时间:2008-09-18 19:35:56

标签: ffmpeg dts mpeg 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?如果没有,那么同步音频的最佳方法是什么呢?

3 个答案:

答案 0 :(得分:10)

我想我终于根据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()只需将P帧缓冲3帧而不是5帧。例如,具有此排序的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

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

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

<耸肩/>但那是纯粹的推测。

答案 1 :(得分:1)

好的,抓住我之前的困惑回复。

对于IBBPBBI电影,您希望PTS看起来像这样(按解码顺序)

0, 3, 1, 2, 6, 4, 5, ...

对应框架

I, P, B, B, I, B, B, ...

所以你似乎在序列的开头错过了一个I,但其他时间戳看起来是正确的。

答案 2 :(得分: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可能只是放弃了第一个共和党的“特殊情况”。

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

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