FFMPEG研究: avdevice库是如何注册V4L2设备的

首先要运行函数:

<span style="font-size:18px;">void avdevice_register_all(void)
{
    static int initialized;

    if (initialized)
        return;
    initialized = 1;

    /* devices */
    REGISTER_INOUTDEV(ALSA,             alsa);
    REGISTER_INDEV   (AVFOUNDATION,     avfoundation);
    REGISTER_INDEV   (BKTR,             bktr);
    REGISTER_OUTDEV  (CACA,             caca);
    REGISTER_INOUTDEV(DECKLINK,         decklink);
    REGISTER_INDEV   (DSHOW,            dshow);
    REGISTER_INDEV   (DV1394,           dv1394);
    REGISTER_INOUTDEV(FBDEV,            fbdev);
    REGISTER_INDEV   (GDIGRAB,          gdigrab);
    REGISTER_INDEV   (IEC61883,         iec61883);
    REGISTER_INDEV   (JACK,             jack);
    REGISTER_INDEV   (LAVFI,            lavfi);
    REGISTER_INDEV   (OPENAL,           openal);
    REGISTER_OUTDEV  (OPENGL,           opengl);
    REGISTER_INOUTDEV(OSS,              oss);
    REGISTER_INOUTDEV(PULSE,            pulse);
    REGISTER_INDEV   (QTKIT,            qtkit);
    REGISTER_OUTDEV  (SDL,              sdl);
    REGISTER_INOUTDEV(SNDIO,            sndio);
    REGISTER_INOUTDEV(V4L2,             v4l2);
//    REGISTER_INDEV   (V4L,              v4l
    REGISTER_INDEV   (VFWCAP,           vfwcap);
    REGISTER_INDEV   (X11GRAB,          x11grab);
    REGISTER_INDEV   (X11GRAB_XCB,      x11grab_xcb);
    REGISTER_OUTDEV  (XV,               xv);

    /* external libraries */
    REGISTER_INDEV   (LIBCDIO,          libcdio);
    REGISTER_INDEV   (LIBDC1394,        libdc1394);

</span>

这个函数里面调用了很多宏函数,注意这里开始是一个坑!巨坑。以v4l2为例。

<span style="font-size:18px;"> REGISTER_INOUTDEV(V4L2,             v4l2);</span>


<span style="font-size:18px;">REGISTER_INOUTDEV</span>
的定义如下:

<span style="font-size:18px;">#define REGISTER_OUTDEV(X, x)                                           \
    {                                                                   \
        extern AVOutputFormat ff_##x##_muxer;                           \
        if (CONFIG_##X##_OUTDEV)                                        \
            av_register_output_format(&ff_##x##_muxer);                 \
    }


#define REGISTER_INDEV(X, x)                                            \
    {                                                                   \
        extern AVInputFormat ff_##x##_demuxer;                          \
        if (CONFIG_##X##_INDEV)                                         \
            av_register_input_format(&ff_##x##_demuxer);                \
    }


#define REGISTER_INOUTDEV(X, x) REGISTER_OUTDEV(X, x); REGISTER_INDEV(X, x)</span>

一次性注册了x这种类型的输入和输出设备。

在这里,ff_##x##_demuxer 在进行宏替换的时候会变成,ff_v4l2_demuxer,

然后也就声明了extern AVInputFormat ff_v4l2_demuxer

最后av_register_input_format注册这个结构体,实际上是把这个设备描述的结构体添加到单向链表里面,后面av_find_input_format遍历这个链表查找需要的格式。


而实际上v4l2模块(v4l2.c)中的定义如下:

<span style="font-size:18px;">AVInputFormat ff_v4l2_demuxer = {
    .name           = "video4linux2,v4l2",
    .long_name      = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
    .priv_data_size = sizeof(struct video_data),
    .read_probe     = v4l2_read_probe,
    .read_header    = v4l2_read_header,
    .read_packet    = v4l2_read_packet,
    .read_close     = v4l2_read_close,
    .get_device_list = v4l2_get_device_list,
    .flags          = AVFMT_NOFILE,
    .priv_class     = &v4l2_class,
};

</span>

所以你在FFMPEG中搜索ff_v4l2_demuxer的被使用的地方,你作死都搜索不到!巨坑啊!


===================================================================================================

粗略的理解:

<span style="font-size:18px;">v4l2_read_header  初始化V4L2 设备和API</span>

v4l2_read_packet 读取数据缓冲区


v4l2_read_close 关闭设备















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值