ffmpeg.c什么是pts和dts?这个代码块在ffmpeg.c中做了什么?

Adi*_*a P 50 c ffmpeg

  • 简单来说,什么是pts和dts值?
  • 为什么它们在转码[decode-encode]视频时很重要?

这段代码在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    }
Run Code Online (Sandbox Code Playgroud)

Bar*_*art 92

那些是解码时间标记(DTS)和显示时间标记(PTS).您可以在教程中找到解释.

所以我们假设我们有一部电影,框架显示如下:IBB P.现在,我们需要知道P中的信息才能显示B帧.因此,帧可能存储如下:IPB B.这就是我们在每个帧上都有解码时间戳和显示时间戳的原因.解码时间戳告诉我们何时需要解码某些内容,并且演示时间戳告诉我们何时需要显示某些内容.因此,在这种情况下,我们的流可能如下所示:

   PTS: 1 4 2 3
   DTS: 1 2 3 4
Stream: I P B B
Run Code Online (Sandbox Code Playgroud)

一般来说,PTS和DTS只有在我们正在播放的流中有B帧时才会有所不同.

  • 像我这样困惑的读者请注意:I、P 和 B 不是任意的帧名称,它们分别代表帧内编码帧、预测帧、双向预测帧。 (7认同)
  • @nirvanaswap实际上在这里解释得相当好https://en.wikipedia.org/wiki/Video_compression_picture_types (4认同)
  • 不,您正在以IBBP顺序显示.但是因为第一个B依赖于它之前的I和它之后的B,并且随后第二个B帧依赖于最后的P帧,为了能够显示第一个B帧,你将需要P帧的信息.这就是流是IPBB的原因. (3认同)
  • 我还是不明白。流必须显示为 IBBP,但由于 P 应该出现在 B 之前,因此我们将其存储为 IPB B。因此我们按照 1 2 3 4 的顺序对其进行解码,这是有道理的。但我们不应该按照 1 3 4 2 的顺序来呈现吗?为什么是1 4 2 3?当我们有连续的 B 帧时,这些 B 帧是单独利用 I 帧和 P 帧,还是也使用彼此相邻的 B 帧? (2认同)
  • @neevek 应该;ffmpeg 在不这样做时会抱怨,例如“输出流中的非单调 DTS”(在本例中他们使用了“-c copy”)。 (2认同)