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

Posted

技术标签:

【中文标题】ffmpeg.c pts 和 dts 是啥?这个代码块在 ffmpeg.c 中做了啥?【英文标题】:ffmpeg.c what are pts and dts ? what does this code block do in ffmpeg.c?ffmpeg.c pts 和 dts 是什么?这个代码块在 ffmpeg.c 中做了什么? 【发布时间】:2011-08-28 00:14:51 【问题描述】: 简单来说什么是 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    

【问题讨论】:

【参考方案1】:

它们是解码时间戳 (DTS) 和呈现时间戳 (PTS)。你可以在这里找到解释inside a tutorial。

假设我们有一部电影,帧显示为:I B B P。现在,我们需要知道 P 中的信息才能显示任一 B 帧。正因为如此,帧可能会像这样存储:I P B B。这就是为什么我们在每个帧上都有一个解码时间戳和一个呈现时间戳。解码时间戳告诉我们什么时候需要解码,演示时间戳告诉我们什么时候需要显示。因此,在这种情况下,我们的流可能如下所示:

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

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

【讨论】:

@nirvanaswap 实际上在这里解释得很好en.wikipedia.org/wiki/Video_compression_picture_types 我还是不明白。流必须显示为 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 帧? 快速跟进:通常,解码时间戳总是按升序排列吗?看起来是这样。 不,您按 IBBP 顺序显示。但是因为第一个 B 依赖于它之前的 I 和它之后的 B,而随后的第二个 B 帧依赖于最后的 P 帧,所以为了能够显示第一个 B 帧,你已经需要 P 帧的信息.这就是为什么流是 IPBB 的原因。 @neevek 应该; ffmpeg 在没有时会抱怨,例如“Non-monotonous DTS in output stream”(在这种情况下,他们使用了-c copy)。【参考方案2】:

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

所以在IP B1 B2的序列中,解码顺序是IP B1 B2,显示顺序是I B1 B2 P。P是从I预测的,B1是从I和P预测的,B2又是从I和P预测的。

【讨论】:

以上是关于ffmpeg.c pts 和 dts 是啥?这个代码块在 ffmpeg.c 中做了啥?的主要内容,如果未能解决你的问题,请参考以下文章

STC,PCR,DTS,PTS

如何在 FFmpeg C/C++ 中寻找

了解视频帧中的 PTS 和 DTS

FFMPEG 中dts和pts区别

dts,pts

理解ffmpeg中的pts,dts,time_base