如何使用libavcodec高效地查找和解码第N帧?

时间:2013-01-01 11:48:24

标签: c++ ffmpeg video-processing libavcodec

请注意,这不是类似帖子的重复!

我想找到并解码第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帧或B帧,我怎么解码呢?
  2. 我注意到计算出的值与inStream->codec->ticks_per_frame不同,为什么?它们不应该是一样的吗?有什么区别?

1 个答案:

答案 0 :(得分: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,其中每个帧的信息都是存在于文件头中。