您的位置:首页 > 编程语言

FFmpeg源代码简单分析:libavdevice的avdevice_register_all()

2017-06-30 15:55 721 查看
转载:http://blog.csdn.net/leixiaohua1020/article/details/41211121
=====================================================
FFmpeg的库函数源代码分析文章列表:
架构图】
FFmpeg源代码结构图
- 解码
FFmpeg源代码结构图
- 编码
【通用】
FFmpeg
源代码简单分析:av_register_all()
FFmpeg
源代码简单分析:avcodec_register_all()
FFmpeg
源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)
FFmpeg
源代码简单分析:常见结构体的初始化和销毁(AVFormatContext,AVFrame等)
FFmpeg
源代码简单分析:avio_open2()
FFmpeg
源代码简单分析:av_find_decoder()和av_find_encoder()
FFmpeg
源代码简单分析:avcodec_open2()
FFmpeg
源代码简单分析:avcodec_close()
【解码】

图解FFMPEG打开媒体的函数avformat_open_input
FFmpeg
源代码简单分析:avformat_open_input()
FFmpeg
源代码简单分析:avformat_find_stream_info()
FFmpeg
源代码简单分析:av_read_frame()
FFmpeg
源代码简单分析:avcodec_decode_video2()
FFmpeg
源代码简单分析:avformat_close_input()
【编码】
FFmpeg
源代码简单分析:avformat_alloc_output_context2()
FFmpeg
源代码简单分析:avformat_write_header()
FFmpeg
源代码简单分析:avcodec_encode_video()
FFmpeg
源代码简单分析:av_write_frame()
FFmpeg
源代码简单分析:av_write_trailer()
【其它】
FFmpeg源代码简单分析:日志输出系统(av_log()等)
FFmpeg源代码简单分析:结构体成员管理系统-AVClass
FFmpeg源代码简单分析:结构体成员管理系统-AVOption
FFmpeg源代码简单分析:libswscale的sws_getContext()
FFmpeg源代码简单分析:libswscale的sws_scale()
FFmpeg源代码简单分析:libavdevice的avdevice_register_all()
FFmpeg源代码简单分析:libavdevice的gdigrab
【脚本】
FFmpeg源代码简单分析:makefile
FFmpeg源代码简单分析:configure
【H.264】
FFmpeg的H.264解码器源代码简单分析:概述
=====================================================

Avdevice.h (libavdevice)

Alldevices.c (libavdevice)

 

/**

* Initialize libavdevice and register all the input and output devices.

* @warning This function is not thread safe.

*/

void avdevice_register_all(void);

 

注册avdevice 多媒体交互设备
通过分析函数多媒体INDEV OUTDEV在ffmpeg中就是AvInputFormat AvOutputFormat

常见的多媒体设备:

音频:oss alsa

视频:in:dshow avfoundation v4l2 openal

    Out:sdl opengl v4l2

例如:

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,  

};  

REGISTER_INOUTDEV(V4L2, v4l2);

 

ES:宏定义 函数指针

本文简单记录一下FFmpeg中libavdevice注册设备的函数avdevice_register_all()。avdevice_register_all()在编程中的使用示例可以参考文章:
最简单的基于FFmpeg的AVDevice例子(读取摄像头)》
在使用libavdevice之前,必须先运行avdevice_register_all()对设备进行注册,否则就会出错。avdevice_register_all()的注册方式和av_register_all()、avcodec_register_all()这几个函数是类似的。可以参考文章:
FFmpeg
源代码简单分析:av_register_all()》
avdevice_register_all()代码如下。
[cpp] view
plain copy

/* 

 * 雷霄骅 

 * http://blog.csdn.net/leixiaohua1020 

 */  

   

#include "config.h"  

#include "avdevice.h"  

//输出设备  

#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)  

   

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_OUTDEV  (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_OUTDEV  (XV,               xv);  

   

    /* external libraries */  

    REGISTER_INDEV   (LIBCDIO,          libcdio);  

    REGISTER_INDEV   (LIBDC1394,        libdc1394);  

}  

从代码中可以看出,avdevice_register_all()调用3个函数进行设备组建的注册:REGISTER_INDEV(),REGISTER_OUTDEV(),REGISTER_INOUTDEV()。上述3个函数实际上是预定义的3个宏:
REGISTER_INDEV():注册输入设备。实际上调用了av_register_input_format()将输入设备注册成一个AVInputFormat。
REGISTER_OUTDEV():注册输出设备。实际上调用了av_register_output_format()将输出设备注册成一个AVOutputFormat。
REGISTER_INOUTDEV():注册输入设备和输出设备。实际上将上述两个宏定义合并了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息