av_dump_format 获得正确的 fps,尝试复制其来源却没有

av_dump_format gets correct fps, trying to copy its source doesn't

我正在尝试使用 FFmpeg 库来处理视频文件,我需要获取视频的 fps。我正在以恒定 fps 加载 mp4 h264 视频。

我的代码是 demuxing and decoding example 的稍微修改的副本。我删除了输出视频和音频的代码,以及所有与音频相关的东西。 open_codec_context 功能除了删除音频内容外没有变化。

调用 open_codec_context 后,我的代码执行以下操作:

if(open_codec_context(&video_stream_idx, &video_dec_ctx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0)
{
    video_stream = fmt_ctx->streams[video_stream_idx];

    double fps = get_fps(video_stream);
    
    printf("Framerate: %f\n", fps);
}

av_dump_format(fmt_ctx, 0, src_filename, 0);

av_dump_format 将视频流的 fps 打印为:25 fps, 25 tbr, 12800 tbn, 50 tbc

我检查了 source for av_dump_format, and for each stream it calls dump_stream_format,它与其他东西一起执行以下操作:

static void dump_stream_format(const AVFormatContext *ic, int i, int index, int is_output)
{
    // (...)
    const AVStream *st = ic->streams[i];
    // (...)
    
    // The part where it actually prints the fps
    if(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
    {
        int fps = st->avg_frame_rate.den && st->avg_frame_rate.num;
        int tbr = st->r_frame_rate.den && st->r_frame_rate.num;
        int tbn = st->time_base.den && st->time_base.num;

        if (fps || tbr || tbn)
            av_log(NULL, AV_LOG_INFO, "%s", separator);

        if (fps)
            print_fps(av_q2d(st->avg_frame_rate), tbr || tbn ? "fps, " : "fps");
        if (tbr)
            print_fps(av_q2d(st->r_frame_rate), tbn ? "tbr, " : "tbr");
        if (tbn)
            print_fps(1 / av_q2d(st->time_base), "tbn");
    }

    // (...)
}

所以我将逻辑复制到 get_fps 函数中:

static double get_fps(AVStream *st)
{
    int fps = st->avg_frame_rate.den && st->avg_frame_rate.num;
    int tbr = st->r_frame_rate.den && st->r_frame_rate.num;
    int tbn = st->time_base.den && st->time_base.num;

    if(fps) return av_q2d(st->avg_frame_rate);
    if(tbr) return av_q2d(st->r_frame_rate);
    if(tbn) return 1.0 / av_q2d(st->time_base);
}

但是结果呢returns是废话。 我让我的代码只打印 avg_frame_rater_frame_ratetime_base 的值并得到:

avg_frame_rate 每次我 运行 它都有随机值(包括负数),看起来像是初始化的垃圾。

r_frame_rate 是 0/0。

time_base 也有像 avg_frame_rate.

这样的随机值

有人知道这是怎么回事吗? av_dump_format 如何获得正确的 fps?

我尝试了不同的视频文件,结果相同。

好的,我已经找出问题所在了。

我从源代码(master)构建了 ffmpeg,我一定是搞砸了配置,因为缺少某些东西。链接器非常有用地从我的包管理器(稳定版 4.4.1)中找到了我的常规 ffmpeg 中缺少的库。所以我的程序链接到 half master 和 half 4.4.1,导致未定义的行为。

原来我得到的随机值来自那个未定义的行为。与稳定的 4.4.1 版本链接直接解决了这个问题,现在我 get_fps returns 预期值。

我很惊讶我竟然不知不觉走到了这一步。甚至不是段错误。