在 FFmpeg 中查找后获取帧显示编号的公式

Formula to get frame display number after seek in FFmpeg

对于给定的 AV 文件,我需要能够在文件中查找特定的视频帧编号。由于解码的工作原理,我正在寻找最近的 I-Frame before 所需的帧(可能是也可能不是请求的帧),然后解码 GOP 中的帧,直到我到达我需要去的地方。因此,我需要在寻求后知道我现在的位置。

SO 上发现了一些性质相似的帖子后,我离开并收集了一些有趣的样本,看看我是否可以得到一个适用于许多不同的公式文件,但我很难过。什么有效或 1 个文件可能不适用于另一个文件:

文件 #1(播客盒)

请求成名#1500。第一个视频帧报告:

AVFrame::pts = 760320
AVFrame::pkt_duration = 512

AVStream::time_base = {1,12800}
AVStream::start_time = 0
AVStream::avg_frame_rate = {25,1}

文件 #2 (HTE54959)

请求成名#1500。第一个视频帧报告:

AVFrame::pts = 1500
AVFrame::pkt_duration = 1

AVStream::time_base = {1,25}
AVStream::start_time = 0
AVStream::avg_frame_rate = {25,1}

文件 #3(巴克兔)

请求成名#1800。第一个视频帧报告:

AVFrame::pts = 1563562
AVFrame::pkt_duration = 1001

AVStream::time_base = {1,30000}
AVStream::start_time = 0
AVStream::avg_frame_rate = {30000,1001}

文件 #4 (HouseDance)

请求成名#1800。第一个视频帧报告:

AVFrame::pts = 1800
AVFrame::pkt_duration = 1

AVStream::time_base = {1001,30000}
AVStream::start_time = 0
AVStream::avg_frame_rate = {30000,1001}

对于上述文件,以下成员总是零:

AVFrame::coded_picture_number
AVFrame::display_picture_number

我考虑过只使用 AVFrame::pts / AVFrame::pkt_duration,但我不确定这是正确的做事方式。我知道对于某些编解码器,可以有可变帧率 (VFR),这意味着我的方法是错误的?我假设 AVFrame::pkt_duration 可以根据 AVFrame 改变?

我想强调一下,我的问题是无法搜索。我正在寻找正确的位置 - 我已经使用时间码直观地验证了这一点。我的问题是以编程方式识别搜索位置的帧号

使用 FFmpeg v4.2.4

大多数格式和 ffmpeg 不跟踪绝对帧索引。时间戳是基准。

有两种解决方法:

#1 Remux 到 MP4 或 MOV 然后寻找。分路器将打印跟踪级别日志。

stream 0, found sample 320

这是最近的先前关键帧。

#2 从开始解码所有帧并计数:(