FFmpeg C/C++获取帧数、时间戳和帧率

7
我正在使用ffmpeg在C语言中解码视频文件。我无法获得当前正在解码的帧数或帧的时间戳。我已经阅读了很多文章,展示了如何根据fps和帧时间戳计算估计的帧编号,但是我无法获得它们中的任何一个。
我需要:视频文件的fps,当前帧的时间戳或帧编号(未计算)。
我拥有的:我能够获取视频的时间。
pFormatCtx->duration/AV_TIME_BASE

我目前正在处理帧并计算它们的数量,得到当前的帧数,但这种方法长期来看是不可行的。我可以使用以下方法获取文件的总帧数:

pFormatCtx->streams[currentStream->videoStream]->nb_frames

我已经阅读,这可能并不适用于所有流,尽管对我尝试过的每个流都有效。

我尝试使用time_base.num和time_base.den值以及packet.pts,但我不能理解从中得到的值,所以我可能需要更好地了解这些值。

有人知道资源,展示如何获取这些值的示例吗?

1个回答

7
这个网址讨论了为什么PTS值可能毫无意义以及如何获得有意义的值:Dranger的ffmpeg和SDL教程 以下是从这个链接中摘取的内容,它提供了关于帧数和时间戳的准确指导。如果这对你有所帮助,那么你可能想阅读更多文档以获得更全面的理解:

So let's say we had a movie, and the frames were displayed like: I B B P. Now, we need to know the information in P before we can display either B frame. Because of this, the frames might be stored like this: I P B B. This is why we have a decoding timestamp and a presentation timestamp on each frame. The decoding timestamp tells us when we need to decode something, and the presentation time stamp tells us when we need to display something. So, in this case, our stream might look like this:

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

Generally the PTS and DTS will only differ when the stream we are playing has B frames in it.

When we get a packet from av_read_frame(), it will contain the PTS and DTS values for the information inside that packet. But what we really want is the PTS of our newly decoded raw frame, so we know when to display it.

Fortunately, FFMpeg supplies us with a "best effort" timestamp, which you can get via, av_frame_get_best_effort_timestamp()


此答案已被标记为需要移除,因为它只是一个链接。您能否扩展一下这个答案,以便回答问题而不需要读者点击链接网页? - josliber
我会尝试满足这个需求,提供不只是链接的内容,但我必须指出两件事:第一,问题要求“展示如何获取这些值的资源”,因此似乎只需要一个链接而不是更长的内容;(2)三年前,回答显然是问题者所需的,因为它被选为答案(它是唯一的答案)。因此,它可能已经帮助原始问题者和其他访问者三年了。 - Beel
1
@Beel 无论它是否长期以来一直有所帮助,Stack Overflow的答案政策指出,仅提供链接的答案并不是完整的答案;如果您剥离格式,只留下文本,它们仍应该回答问题。 - anon

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