ffmpeg 函数 avformat_seek_file() 的问题

发布于 2024-11-15 19:39:18 字数 863 浏览 4 评论 0原文

我正在尝试使用 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 文件。我尝试了不同的标志、不同的文件、使用时间戳而不是帧、前后刷新缓冲区等等,但它对我不起作用。如果有人能告诉我它出了什么问题,我将非常感激。

I am trying to seek the given frame in the video using ffmpeg library. I knew that there is av_seek_frame() function but it was recommended to use avformat_seek_file()instead. Something similar mentioned here.

I know that avformat_seek_file() can't always take you to exact frame you want, but this is ok for me. I just want to jump to the nearest keyframe. So i open the video, find videostream and calling it like this:

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

It always returns 0, so i understand it as correct finish. However, it doesn't work as it should to. I check byte position like here before and after calling avformat_seek_file(). Actually it changes, but it changes always in the same way whenever i'm trying to put different target frame numbers! I mean that byteposition after this call is always same even with different frameNumber values. Obviously, i'm doing something wrong but i don't know what exactly. I don't know if it does matter but i'm using .h264 files for that. I tried different flags, different files, using timestamps instead of frames, flushing buffers before and after and so on but it doesn't work for me. I will be very grateful if someone could show me what is wrong with it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

左耳近心 2024-11-22 19:39:18

我遇到了同样的问题,请参阅下面的代码(它对我有用):

    ...
    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);
        }
    }

I had the same issue, see the code bellow (it works for me):

    ...
    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);
        }
    }
微暖i 2024-11-22 19:39:18

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

mp4box -new -add my_file.h264 my_file.mp4

your problem may be related to the fact that your input is raw .h264. try using e.g. mp4box to mux it into a .mp4 file, then load the mp4 file with ffmpeg and try to seek to a keyframe again. e.g.:

mp4box -new -add my_file.h264 my_file.mp4
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文