1

我正在尝试使用 ffmpeg 库在视频中寻找给定的帧。我知道有av_seek_frame()功能,但建议avformat_seek_file()改用。这里提到了类似的东西。

我知道avformat_seek_file()不能总是把你带到你想要的精确框架,但这对我来说没问题。我只想跳到最近的关键帧。所以我打开视频,找到视频流并像这样调用它:

avformat_seek_file( formatContext, streamId, 0, frameNumber, frameNumber, AVSEEK_FLAG_FRAME )

它总是返回 0,所以我理解它是正确的完成。但是,它不能正常工作。我在调用之前和之后检查字节位置,就像这里avformat_seek_file()一样。实际上它会改变,但是每当我尝试放置不同的目标帧号时,它总是以相同的方式改变!frameNumber我的意思是即使使用不同的值,此调用后的字节位置也始终相同。显然,我做错了什么,但我不知道到底是什么。我不知道这是否重要,但我正在使用 .h264 文件。我尝试了不同的标志、不同的文件、使用时间戳而不是帧、前后刷新缓冲区等等,但它对我不起作用。如果有人能告诉我它有什么问题,我将不胜感激。

4

2 回答 2

5

我有同样的问题,请参阅下面的代码(它适用于我):

    ...
    checkPosition(input_files[file_index].ctx);
    ...

    void checkPosition(AVFormatContext *is) {
        int stream_index = av_find_default_stream_index(is);
        //Convert ts to frame
        tm = av_rescale(tm, is->streams[stream_index]->time_base.den, is->streams[stream_index]->time_base.num);
        tm /= 1000;

        //SEEK
        if (avformat_seek_file(is, stream_index, INT64_MIN, tm, INT64_MAX, 0) < 0) {
            av_log(NULL, AV_LOG_ERROR, "ERROR av_seek_frame: %u\n", tm);
        } else {
            av_log(NULL, AV_LOG_ERROR, "SUCCEEDED av_seek_frame: %u newPos:%d\n", tm, is->pb->pos);
            avcodec_flush_buffers(is->streams[stream_index]->codec);
        }
    }
于 2011-08-15T08:25:31.407 回答
-2

您的问题可能与您的输入是原始 .h264 的事实有关。尝试使用例如 mp4box 将其复用到 .mp4 文件中,然后使用 ffmpeg 加载 mp4 文件并尝试再次寻找关键帧。例如:

mp4box -new -add my_file.h264 my_file.mp4
于 2013-04-19T04:35:42.157 回答