ffmpeg.c 中的 PTS 和 DTS 是什么?ffmpeg.c 中的这个代码块是做什么用的?

90
  • 简单来说,什么是pts和dts值?
  • 为什么在视频转码 [解码-编码] 过程中它们很重要?

这段代码在 ffmpeg.c 中是做什么用的?它的目的是什么?

01562    ist->next_pts = ist->pts = picture.best_effort_timestamp;
01563    if (ist->st->codec->time_base.num != 0) {
01564        int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame;
01565        ist->next_pts += ((int64_t)AV_TIME_BASE *
01566                         ist->st->codec->time_base.num * ticks) /
01567                         ist->st->codec->time_base.den;
01568    }
2个回答

167

这里所说的是解码时间戳(DTS)和显示时间戳(PTS)。你可以在教程中找到更详细的解释。

假设我们有一部电影,帧的显示顺序为:I B B P。现在,在我们能够显示任何B帧之前,我们需要知道P帧中的信息。因此,帧可能被存储为:I P B B。这就是为什么每个帧都有一个解码时间戳和一个显示时间戳的原因。解码时间戳告诉我们何时需要解码某些内容,而显示时间戳告诉我们何时需要显示某些内容。因此,在这种情况下,我们的流可能如下所示:

   PTS: 1 4 2 3
   DTS: 1 2 3 4
Stream: I P B B

通常情况下,当我们播放的流中含有B帧时,PTS和DTS之间才会有差异。


16
@nirvanaswap,这个网页其实已经很好地解释了视频压缩的图像类型,可以参考:https://en.wikipedia.org/wiki/Video_compression_picture_types。 - Bart
2
我还是不明白。流应该按照 I B B P 的顺序显示,但由于 P 应该在 B 之前出现,所以我们将其存储为 I P B B。因此,我们按照 1 2 3 4 的顺序进行解码,这是有道理的。但是,我们不应该按照 1 3 4 2 的顺序呈现吗?为什么是 1 4 2 3?当我们有连续的 B 帧时,这些 B 帧是否仅利用相邻的 I 和 P 帧,还是也使用相邻的 B 帧? - nirvanaswap
5
不,你正在显示IBBP顺序。但是因为第一个B依赖于它前面的I和后面的B,并且随后的第二个B帧依赖于最后一个P帧,为了能够显示第一个B帧,你已经需要拥有P帧的信息。这就是流IPBB的原因。 - Bart
4
@neevek应该在使用-c copy时遵循ffmpeg的要求,否则ffmpeg会报错,例如“输出流中存在非单调DTS”(非单调时间戳)。 - arielCo
7
请注意:像我一样困惑的读者们,I、P 和 B 不是任意的帧名,它们分别代表关键帧、预测帧和双向预测帧。 - ahmetknk
显示剩余8条评论

-7

B帧是从I和P帧预测出来的。与I和P相比,B帧通常具有更多的错误,因此不建议用于预测,尽管它们可能更接近时间。有一些算法可以使用B进行预测,但是它是从过去的B帧而不是未来的B帧中得出的。

因此,在I P B1 B2的序列中,解码顺序为I P B1 B2,显示顺序为I B1 B2 P。P是从I预测出来的,B1是从I和P预测出来的,B2再次从I和P预测出来。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接