【问题标题】:How to find and decode efficiently Nth frame with libavcodec?如何使用 libavcodec 高效地查找和解码第 N 帧?
【发布时间】:2012-12-16 02:49:28
【问题描述】:

拜托,这不是类似帖子的重复!

我想找到并解码第 N 帧,例如第 7 帧。

据我了解,使用time_base 我可以计算每帧有多少刻度,然后将其乘以 7,我们将得到第 7 帧的位置。计算我所做的刻度

AVStream inStream = getStreamFromAVFormatContext();

int fps = inStream->r_frame_rate.num;
AVRational timeBase = inStream->time_base;

int ticks_per_frame = (1/fps) / timeBase;
int _7thFramePos = ticks_per_frame * 7;
  1. 我是否正确计算了第 7 帧的位置?如果我这样做了,那么要进入那个框架,我就做av_seek_frame(pFormatCtx, -1, _7thFramePos, AVSEEK_FLAG_ANY),对吗? 如果第 7 帧是 P-Frame 或 B-Frame 会怎样,我如何解码?
  2. 我注意到计算的值与inStream->codec->ticks_per_frame 不同,为什么?他们不应该是一样的吗?有什么区别?

【问题讨论】:

    标签: c++ ffmpeg video-processing libavcodec


    【解决方案1】:

    这篇文章很好地解释了这个问题。 http://www.hackerfactor.com/blog/index.php?/archives/307-Picture-Go-Back.html

    [1] 对 AVStream 结构的评论清楚地提到“r_frame_rate”是一个猜测,可能不准确,因为即使我的帧速率(比如说)25fps,就 base_time 而言,我可能有 24 或 26 帧一秒钟。

    [2] 要找到从一开始就解码帧所需的确切帧号并保留一个计数器,但这非常低效,这可以针对 MP4 等某些文件格式进行优化,其中有关每一帧的信息是存在于文件头中。

    【讨论】:

    • 可以提供一些例子吗?
    • 那么我如何计算时间戳以传递给av_seek_frame 函数?
    • 如果您不想 100% 准确,您也可以使用带有 AVSEEK_FLAG_FRAME 标志的 avformat_seek_file()。如果您想 100% 准确,那么您将从流的开头开始解码并保持计数器直到达到所需的帧,并在达到所需的帧号后停止解码。
    • 1 - avformat_seek_file 和 AVSEEK_FLAG_FRAME 会做什么?它会找到哪个帧,最接近第 N 帧的 I 帧还是什么? 2 - 你的意思是如果我需要 X 次才能获得 X 帧,我每次都会从流的开头开始?
    • 1. AVSEEK_FLAG_FRAME - 允许您根据帧号指定搜索位置,avformat_seek_file() 允许您指定与所需帧号的最小-最大偏差。 2.是的,如果您需要转到第 X 帧,则需要解码前 X 帧,但是如果您可以第一次保留关键帧的索引并且下次您可以寻找精确的壁橱关键帧,则可以对此进行优化avformat_seek_file() 然后移动到所需的帧。
    猜你喜欢
    • 2012-11-15
    • 2012-11-12
    • 2021-07-09
    • 2014-06-20
    • 2014-08-19
    • 2023-03-20
    • 2017-06-29
    • 2013-04-21
    • 2021-03-01
    相关资源
    最近更新 更多