简体   繁体   English

ffmpeg c/c++ 获取帧数或时间戳和 fps

[英]ffmpeg c/c++ get frame count or timestamp and fps

I am using ffmpeg to decode a video file in C. I am struggling to get either the count of the current frame I am decoding or the timestamp of the frame.我正在使用 ffmpeg 在 C 中解码视频文件。我正在努力获取我正在解码的当前帧的计数或帧的时间戳。 I have read numerous posts that show how to calculate an estimated frame no based on the fps and frame timestamp, however I am not able to get either of those.我已经阅读了许多帖子,这些帖子展示了如何根据 fps 和帧时间戳计算估计的帧数,但是我无法获得其中任何一个。

What I need: fps of video file, timestamp of current frame or frame no(not calculated)我需要什么:视频文件的 fps、当前帧的时间戳或帧号(未计算)

What I have: I am able to get the time of the video using我所拥有的:我能够使用

pFormatCtx->duration/AV_TIME_BASE

I am counting the frames currently as I process them, and getting a current frame count, this is not going to work longterm though.我在处理它们时正在计算当前的帧数,并获得当前的帧数,但这不会长期有效。 I can get the total frame count for the file using我可以使用获得文件的总帧数

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

I have read this may not work for all streams, although it has worked for every stream I have tried.我读过这可能不适用于所有流,尽管它适用于我尝试过的每个流。

I have tried using the time_base.num and time_base.den values and packet.pts, but I can't make any sense of the values that I am getting from those, so I may just need to understand better what those values are.我曾尝试使用 time_base.num 和 time_base.den 值以及 packet.pts,但我无法理解从这些值中获得的值,因此我可能只需要更好地了解这些值是什么。

Does anyone know of resources that show examples on how to get this values?有谁知道展示如何获取此值的示例的资源?

This url discusses why the pts values may not make sense and how to get sensible ones: An ffmpeg and SDL Tutorial by Dranger这个 url 讨论了为什么 pts 值可能没有意义以及如何获得合理的值: Dranger 的 ffmpeg 和 SDL 教程

Here is an excerpt from that link, which gives guidance on exactly what you are looking for in terms of frame numbers and timestamps.这是该链接的摘录,它为您在帧数和时间戳方面准确寻找什么提供了指导。 If this seems useful to you then you may want to read more of the document for a fuller understanding:如果这对您有用,那么您可能需要阅读更多文档以获得更全面的理解:

So let's say we had a movie, and the frames were displayed like: IBB P. Now, we need to know the information in P before we can display either B frame.假设我们有一部电影,帧显示为:IBB P。现在,我们需要知道 P 中的信息,然后才能显示 B 帧。 Because of this, the frames might be stored like this: IPB B. This is why we have a decoding timestamp and a presentation timestamp on each frame.因此,帧可能会像这样存储:IPB B。这就是为什么我们在每一帧上都有一个解码时间戳和一个呈现时间戳。 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: IPBB

Generally the PTS and DTS will only differ when the stream we are playing has B frames in it.通常,PTS 和 DTS 仅在我们正在播放的流中包含 B 帧时才会有所不同。

When we get a packet from av_read_frame() , it will contain the PTS and DTS values for the information inside that packet.当我们从av_read_frame()获取数据包时,它将包含该数据包内信息的 PTS 和 DTS 值。 But what we really want is the PTS of our newly decoded raw frame, so we know when to display it.但我们真正想要的是我们新解码的原始帧的 PTS,所以我们知道什么时候显示它。

Fortunately, FFMpeg supplies us with a "best effort" timestamp, which you can get via, av_frame_get_best_effort_timestamp()幸运的是,FFMpeg 为我们提供了“尽力而为”的时间戳,您可以通过av_frame_get_best_effort_timestamp()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM