我正在写一个视频编辑器,我需要寻找精确的帧,知道帧号。
stackoverflow 上的其他帖子告诉我,ffmpeg 搜索后可能会给我一些碎帧,这对于播放来说不是问题,但对于视频编辑器来说是个大问题。
而且我需要按帧号而不是时间来寻找,当转换为帧号时会变得不准确。
我读过danger's tuts(现在已经过时了),最终得到:
av_seek_frame(fmt_ctx, video_stream_id, frame, AVSEEK_FLAG_ANY);
它总是寻求框架No. 0
,并且总是return 0
意味着成功。然后我尝试阅读 Blender 的源代码,发现它真的很复杂(也许我应该实现一个图像缓冲区?)。
那么,有没有什么简单的方法可以通过一个简单的调用来寻找一个帧seek(context, frame_number)
(同时获得一个完整的帧,而不是一个破碎的帧)?或者,是否有任何轻量级库可以简化这一点?
编辑: 感谢praks411,我找到了解决方案:
void AV_seek(AV * av, size_t frame)
{
int frame_delta = frame - av->frame_id;
if (frame_delta < 0 || frame_delta > 5)
av_seek_frame(av->fmt_ctx, av->video_stream_id,
frame, AVSEEK_FLAG_BACKWARD);
while (av->frame_id != frame)
AV_read_frame(av);
}
void AV_read_frame(AV * av)
{
AVPacket packet;
int frame_done;
while (av_read_frame(av->fmt_ctx, &packet) >= 0) {
if (packet.stream_index == av->video_stream_id) {
avcodec_decode_video2(av->codec_ctx, av->frame, &frame_done, &packet);
if (frame_done) {
...
av->frame_id = packet.dts;
av_free_packet(&packet);
return;
}
}
av_free_packet(&packet);
}
}
EDIT2: 原来有一个库:FFMS2。它是“一个基于 FFmpeg 的源库 [...],便于帧准确访问”,并且是可移植的(至少跨 Windows 和 Linux)。