我如何用ffmpeg来寻找X号框架?

我正在写一个视频编辑器,我需要寻找准确的帧,知道帧数.

stackoverflow上的其他帖子告诉我,ffmpeg可能会在寻求后给我一些破碎的帧,这不是播放问题,而是视频编辑器的一个大问题.

而我需要通过帧号查找,而不是时间,当转换为帧号时,它将变得不准确.

我已经阅读了dranger的提示(现在已经过时了),最终得到:

av_seek_frame(fmt_ctx,video_stream_id,frame,AVSEEK_FLAG_ANY);

它始终追求0号,并始终返回0,这意味着成功.
然后我试图阅读Blender的源代码,发现它真的很复杂(也许我应该实现一个图像缓冲区?).

那么,有没有什么简单的方法来寻找一个简单的调用,如seek(上下文,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,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);
    }
}

解决方法

av_seek_frame将仅基于时间戳寻找关键帧.因为它寻求关键帧,你可能不会得到你想要的.因此,建议寻求最近的关键帧,然后逐帧读取您到达所需的帧.

但是,如果您正在处理固定的FPS值,则可以轻松将时间戳映射到帧索引.

在寻求之前,如果您指定了流,则需要将您的时间转换为AVStream.time_base单位.在avformat.h中阅读av_seek_frame的ffmpeg文档.

例如,如果你想寻求1.23秒的剪辑:

double m_out_start_time = 1.23;
 int flgs = AVSEEK_FLAG_ANY;
 int seek_ts = (m_out_start_time*(m_in_vid_strm->time_base.den))/(m_in_vid_strm->time_base.num);
 if(av_seek_frame(m_informat,m_in_vid_strm_idx,seek_ts,flgs) < 0)
 {
     PRINT_MSG("Failed to seek Video ")
 }

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...