[FFmpeg] 解决av_find_input_format找不到v4l2的问题

从问题入手
在网上找了段代码测试v4l2,在第一行调用av_find_input_format("v4l2")发现找不到v4l2,用ffmpeg.exe 执行ffmpeg -formats发现有v4l2,所以就从这里开始找为什么找不到v4l2。

先找到av_find_input_format的定义在源码的format.c文件。

const AVInputFormat *av_find_input_format(const char *short_name)
{
    const AVInputFormat *fmt = NULL;
    void *i = 0;
    while ((fmt = av_demuxer_iterate(&i)))//遍历
        if (av_match_name(short_name, fmt->name))//匹配名称
            return fmt;
    return NULL;
}

在libavformat 58 版本后添加的av_demuxer_iterate这个函数。
在allformats.c里找到了av_demuxer_iterate的定义:

const AVInputFormat *av_demuxer_iterate(void **opaque)
{
    static const uintptr_t size = sizeof(demuxer_list)/sizeof(demuxer_list[0]) - 1;
    uintptr_t i = (uintptr_t)*opaque;
    const AVInputFormat *f = NULL;
    uintptr_t tmp;

    if (i < size) {
        f = demuxer_list[i];
    } else if (tmp = atomic_load_explicit(&indev_list_intptr, memory_order_relaxed)) {
        const AVInputFormat *const *indev_list = (const AVInputFormat *const *)tmp;
        f = indev_list[i - size];
    }

    if (f)
        *opaque = (void*)(i + 1);
    return f;
}

这里是在迭代AVInputFormat demuxer_list,而迭代的所有的dmuxer包含在allformats.c。

/* (de)muxers */
extern const FFOutputFormat ff_a64_muxer;
extern const AVInputFormat  ff_aa_demuxer;
extern const AVInputFormat  ff_aac_demuxer;
extern const AVInputFormat  ff_aax_demuxer;
extern const AVInputFormat  ff_ac3_demuxer;
extern const FFOutputFormat ff_ac3_muxer;
extern const AVInputFormat  ff_ac4_demuxer;
extern const FFOutputFormat ff_ac4_muxer;
extern const AVInputFormat  ff_ace_demuxer;
extern const AVInputFormat  ff_acm_demuxer;
....

翻完了都没找到v4l2。
在libavdevice/alldevices.c里找到了v4l2 的fmt。难怪找不到。
extern const AVInputFormat ff_v4l2_demuxer;

所以正确的用法是,先调用
avdevice_register_all()

posted @ 2024-12-10 16:15  莫如风  阅读(318)  评论(0)    收藏  举报