FFMPEG之 --- 组件注册

在ffmpeg中,组件分为device类,包括input device和output device;filter;demuxer&muxer;codec(encoder/decoder);network protocol等,根据使用者的要求,调用相关的函数来进行加载注册:

avdevice_register_all();          // 用来注册device设备,包括input device和output device;
avcodec_register_all();           // 用来注册codec,包括encoder和decoder;
avfilter_register_all();              // 音视频滤波所需的组件;
av_register_all();                     // 所有的demuxer和muxer;


1. 所有device的注册过程:
      所有的device注册定义在libavdevice/alldevices.c中,开发者需要调用avdevice_register_all(), 注册后所有的input和output device将被作为链表中的一个节点,链表定义在libavformat/format.c中,如下:
/**
 * @file
 * Format register and lookup
 */
/** head of registered input format linked list */
static AVInputFormat *first_iformat = NULL;
/** head of registered output format linked list */
static AVOutputFormat *first_oformat = NULL;

static AVInputFormat **last_iformat = &first_iformat;
static AVOutputFormat **last_oformat = &first_oformat;

开发者需要调用的注册函数avdevice_register_all():
void avdevice_register_all(void)
{
    static AVOnce control = AV_ONCE_INIT;

    ff_thread_once(&control, register_all);
}

所有的input和output device的注册过程
static void register_all(void)
{
    /* 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  (SDL2,             sdl2);
    REGISTER_INOUTDEV(SNDIO,            sndio);
    REGISTER_INOUTDEV(V4L2,             v4l2);
//    REGISTER_INDEV   (V4L,              v4l
    REGISTER_INDEV   (VFWCAP,           vfwcap);
    REGISTER_INDEV   (XCBGRAB,          xcbgrab);
    REGISTER_OUTDEV  (XV,               xv);

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

注册过程中定义的宏定义:
#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)

真正的注册函数定义在libavformat/format.c中,所有的Input device由AVInputFormat结构来代表,对应的所有的Output device由AVOutputFormat结构来代表:
void av_register_input_format(AVInputFormat *format)
{
    AVInputFormat **p = last_iformat;

    // Note, format could be added after the first 2 checks but that implies that *p is no longer NULL
    while(p != &format->next && !format->next && avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
        p = &(*p)->next;

    if (!format->next)
        last_iformat = &format->next;
}

void av_register_output_format(AVOutputFormat *format)
{
    AVOutputFormat **p = last_oformat;

    // Note, format could be added after the first 2 checks but that implies that *p is no longer NULL
    while(p != &format->next && !format->next && avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
        p = &(*p)->next;

    if (!format->next)
        last_oformat = &format->next;
}

注册后可以调用如下的函数进行device的枚举:
AVInputFormat *av_iformat_next(const AVInputFormat *f);
AVOutputFormat *av_oformat_next(const AVOutputFormat *f);


2.  所有codec的注册过程:
     所有codec的注册过程定义在libavcodec/allcodecs.c中,使用者需调用avcodec_register_all(),注册后所有的decoder和encoder将被保存在全局静态链表中,每一个节点代表一个encoder或者decoder,其定义在libavcodec/utils.c中。
/* encoder management */
static AVCodec *first_avcodec = NULL;
static AVCodec **last_avcodec = &first_avcodec;
static AVHWAccel *first_hwaccel = NULL;
static AVHWAccel **last_hwaccel = &first_hwaccel;
static AVCodecParser *av_first_parser = NULL;

使用者需要调用的注册函数:
void avcodec_register_all(void)
{
    static AVOnce control = AV_ONCE_INIT;

    ff_thread_once(&control, register_all);
}

下面的函数实现中分为三部分的codec注册:
a). 硬件加速组件注册,所有硬件加速组件被放在first_hwaccel链表中,每一个组件由AVHWAccel来表示;
b). codec组件注册,所有的codec(encoder和decoder)组件被放在first_avcodec链表中,每一个组件由AVCodec来表示;
c). parser组件注册,所有的parser组件被放在av_first_parser链表中,每个组件由AVCodecParser来表示;
static void register_all(void)
{
    /* hardware accelerators */
    REGISTER_HWACCEL(H263_VAAPI,        h263_vaapi);
    REGISTER_HWACCEL(H263_VIDEOTOOLBOX, h263_videotoolbox);
    REGISTER_HWACCEL(H264_CUVID,        h264_cuvid);
    REGISTER_HWACCEL(H264_D3D11VA,      h264_d3d11va);
    REGISTER_HWACCEL(H264_DXVA2,        h264_dxva2);
    REGISTER_HWACCEL(H264_MEDIACODEC,   h264_mediacodec);
    REGISTER_HWACCEL(H264_MMAL,         h264_mmal);
    REGISTER_HWACCEL(H264_QSV,          h264_qsv);
    REGISTER_HWACCEL(H264_VAAPI,        h264_vaapi);
    REGISTER_HWACCEL(H264_VDA,          h264_vda);
    REGISTER_HWACCEL(H264_VDA_OLD,      h264_vda_old);
    REGISTER_HWACCEL(H264_VDPAU,        h264_vdpau);
    REGISTER_HWACCEL(H264_VIDEOTOOLBOX, h264_videotoolbox);
    REGISTER_HWACCEL(HEVC_CUVID,        hevc_cuvid);
    REGISTER_HWACCEL(HEVC_D3D11VA,      hevc_d3d11va);
    REGISTER_HWACCEL(HEVC_DXVA2,        hevc_dxva2);
    REGISTER_HWACCEL(HEVC_MEDIACODEC,   hevc_mediacodec);
    REGISTER_HWACCEL(HEVC_QSV,          hevc_qsv);
    REGISTER_HWACCEL(HEVC_VAAPI,        hevc_vaapi);
    REGISTER_HWACCEL(HEVC_VDPAU,        hevc_vdpau);
    REGISTER_HWACCEL(MJPEG_CUVID,       mjpeg_cuvid);
    REGISTER_HWACCEL(MPEG1_CUVID,       mpeg1_cuvid);
    REGISTER_HWACCEL(MPEG1_XVMC,        mpeg1_xvmc);
    REGISTER_HWACCEL(MPEG1_VDPAU,       mpeg1_vdpau);
    REGISTER_HWACCEL(MPEG1_VIDEOTOOLBOX, mpeg1_videotoolbox);
    REGISTER_HWACCEL(MPEG2_CUVID,       mpeg2_cuvid);
    REGISTER_HWACCEL(MPEG2_XVMC,        mpeg2_xvmc);
    REGISTER_HWACCEL(MPEG2_D3D11VA,     mpeg2_d3d11va);
    REGISTER_HWACCEL(MPEG2_DXVA2,       mpeg2_dxva2);
    REGISTER_HWACCEL(MPEG2_MMAL,        mpeg2_mmal);
    REGISTER_HWACCEL(MPEG2_QSV,         mpeg2_qsv);
    REGISTER_HWACCEL(MPEG2_VAAPI,       mpeg2_vaapi);
    REGISTER_HWACCEL(MPEG2_VDPAU,       mpeg2_vdpau);
    REGISTER_HWACCEL(MPEG2_VIDEOTOOLBOX, mpeg2_videotoolbox);
    REGISTER_HWACCEL(MPEG4_CUVID,       mpeg4_cuvid);
    REGISTER_HWACCEL(MPEG4_MEDIACODEC,  mpeg4_mediacodec);
    REGISTER_HWACCEL(MPEG4_MMAL,        mpeg4_mmal);
    REGISTER_HWACCEL(MPEG4_VAAPI,       mpeg4_vaapi);
    REGISTER_HWACCEL(MPEG4_VDPAU,       mpeg4_vdpau);
    REGISTER_HWACCEL(MPEG4_VIDEOTOOLBOX, mpeg4_videotoolbox);
    REGISTER_HWACCEL(VC1_CUVID,         vc1_cuvid);
    REGISTER_HWACCEL(VC1_D3D11VA,       vc1_d3d11va);
    REGISTER_HWACCEL(VC1_DXVA2,         vc1_dxva2);
    REGISTER_HWACCEL(VC1_VAAPI,         vc1_vaapi);
    REGISTER_HWACCEL(VC1_VDPAU,         vc1_vdpau);
    REGISTER_HWACCEL(VC1_MMAL,          vc1_mmal);
    REGISTER_HWACCEL(VC1_QSV,           vc1_qsv);
    REGISTER_HWACCEL(VP8_CUVID,         vp8_cuvid);
    REGISTER_HWACCEL(VP8_MEDIACODEC,    vp8_mediacodec);
    REGISTER_HWACCEL(VP8_QSV,           vp8_qsv);
    REGISTER_HWACCEL(VP9_CUVID,         vp9_cuvid);
    REGISTER_HWACCEL(VP9_D3D11VA,       vp9_d3d11va);
    REGISTER_HWACCEL(VP9_DXVA2,         vp9_dxva2);
    REGISTER_HWACCEL(VP9_MEDIACODEC,    vp9_mediacodec);
    REGISTER_HWACCEL(VP9_VAAPI,         vp9_vaapi);
    REGISTER_HWACCEL(WMV3_D3D11VA,      wmv3_d3d11va);
    REGISTER_HWACCEL(WMV3_DXVA2,        wmv3_dxva2);
    REGISTER_HWACCEL(WMV3_VAAPI,        wmv3_vaapi);
    REGISTER_HWACCEL(WMV3_VDPAU,        wmv3_vdpau);

    /* video codecs */
    REGISTER_ENCODER(A64MULTI,          a64multi);
    REGISTER_ENCODER(A64MULTI5,         a64multi5);
    REGISTER_DECODER(AASC,              aasc);
    REGISTER_DECODER(AIC,               aic);
    REGISTER_ENCDEC (ALIAS_PIX,         alias_pix);
    REGISTER_ENCDEC (AMV,               amv);
    REGISTER_DECODER(ANM,               anm);
    REGISTER_DECODER(ANSI,              ansi);
    REGISTER_ENCDEC (APNG,              apng);
    REGISTER_ENCDEC (ASV1,              asv1);
    REGISTER_ENCDEC (ASV2,              asv2);
    REGISTER_DECODER(AURA,              aura);
    REGISTER_DECODER(AURA2,             aura2);
    REGISTER_ENCDEC (AVRP,              avrp);
    REGISTER_DECODER(AVRN,              avrn);
    REGISTER_DECODER(AVS,               avs);
    REGISTER_ENCDEC (AVUI,              avui);
    REGISTER_ENCDEC (AYUV,              ayuv);
    REGISTER_DECODER(BETHSOFTVID,       bethsoftvid);
    REGISTER_DECODER(BFI,               bfi);
    REGISTER_DECODER(BINK,              bink);
    REGISTER_ENCDEC (BMP,               bmp);
    REGISTER_DECODER(BMV_VIDEO,         bmv_video);
    REGISTER_DECODER(BRENDER_PIX,       brender_pix);
    REGISTER_DECODER(C93,               c93);
    REGISTER_DECODER(CAVS,              cavs);
    REGISTER_DECODER(CDGRAPHICS,        cdgraphics);
    REGISTER_DECODER(CDXL,              cdxl);
    REGISTER_DECODER(CFHD,              cfhd);
    REGISTER_ENCDEC (CINEPAK,           cinepak);
    REGISTER_DECODER(CLEARVIDEO,        clearvideo);
    REGISTER_ENCDEC (CLJR,              cljr);
    REGISTER_DECODER(CLLC,              cllc);
    REGISTER_ENCDEC (COMFORTNOISE,      comfortnoise);
    REGISTER_DECODER(CPIA,              cpia);
    REGISTER_DECODER(CSCD,              cscd);
    REGISTER_DECODER(CYUV,              cyuv);
    REGISTER_DECODER(DDS,               dds);
    REGISTER_DECODER(DFA,               dfa);
    REGISTER_DECODER(DIRAC,             dirac);
    REGISTER_ENCDEC (DNXHD,             dnxhd);
    REGISTER_ENCDEC (DPX,               dpx);
    REGISTER_DECODER(DSICINVIDEO,       dsicinvideo);
    REGISTER_DECODER(DVAUDIO,           dvaudio);
    REGISTER_ENCDEC (DVVIDEO,           dvvideo);
    REGISTER_DECODER(DXA,               dxa);
    REGISTER_DECODER(DXTORY,            dxtory);
    REGISTER_DECODER(DXV,               dxv);
    REGISTER_DECODER(EACMV,             eacmv);
    REGISTER_DECODER(EAMAD,             eamad);
    REGISTER_DECODER(EATGQ,             eatgq);
    REGISTER_DECODER(EATGV,             eatgv);
    REGISTER_DECODER(EATQI,             eatqi);
    REGISTER_DECODER(EIGHTBPS,          eightbps);
    REGISTER_DECODER(EIGHTSVX_EXP,      eightsvx_exp);
    REGISTER_DECODER(EIGHTSVX_FIB,      eightsvx_fib);
    REGISTER_DECODER(ESCAPE124,         escape124);
    REGISTER_DECODER(ESCAPE130,         escape130);
    REGISTER_DECODER(EXR,               exr);
    REGISTER_ENCDEC (FFV1,              ffv1);
    REGISTER_ENCDEC (FFVHUFF,           ffvhuff);
    REGISTER_DECODER(FIC,               fic);
    REGISTER_ENCDEC (FLASHSV,           flashsv);
    REGISTER_ENCDEC (FLASHSV2,          flashsv2);
    REGISTER_DECODER(FLIC,              flic);
    REGISTER_ENCDEC (FLV,               flv);
    REGISTER_DECODER(FMVC,              fmvc);
    REGISTER_DECODER(FOURXM,            fourxm);
    REGISTER_DECODER(FRAPS,             fraps);
    REGISTER_DECODER(FRWU,              frwu);
    REGISTER_DECODER(G2M,               g2m);
    REGISTER_ENCDEC (GIF,               gif);
    REGISTER_ENCDEC (H261,              h261);
    REGISTER_ENCDEC (H263,              h263);
    REGISTER_DECODER(H263I,             h263i);
    REGISTER_ENCDEC (H263P,             h263p);
    REGISTER_DECODER(H264,              h264);
    REGISTER_DECODER(H264_CRYSTALHD,    h264_crystalhd);
    REGISTER_DECODER(H264_MEDIACODEC,   h264_mediacodec);
    REGISTER_DECODER(H264_MMAL,         h264_mmal);
    REGISTER_DECODER(H264_QSV,          h264_qsv);
    REGISTER_DECODER(H264_VDA,          h264_vda);
#if FF_API_VDPAU
    REGISTER_DECODER(H264_VDPAU,        h264_vdpau);
#endif
    REGISTER_ENCDEC (HAP,               hap);
    REGISTER_DECODER(HEVC,              hevc);
    REGISTER_DECODER(HEVC_QSV,          hevc_qsv);
    REGISTER_DECODER(HNM4_VIDEO,        hnm4_video);
    REGISTER_DECODER(HQ_HQA,            hq_hqa);
    REGISTER_DECODER(HQX,               hqx);
    REGISTER_ENCDEC (HUFFYUV,           huffyuv);
    REGISTER_DECODER(IDCIN,             idcin);
    REGISTER_DECODER(IFF_ILBM,          iff_ilbm);
    REGISTER_DECODER(INDEO2,            indeo2);
    REGISTER_DECODER(INDEO3,            indeo3);
    REGISTER_DECODER(INDEO4,            indeo4);
    REGISTER_DECODER(INDEO5,            indeo5);
    REGISTER_DECODER(INTERPLAY_VIDEO,   interplay_video);
    REGISTER_ENCDEC (JPEG2000,          jpeg2000);
    REGISTER_ENCDEC (JPEGLS,            jpegls);
    REGISTER_DECODER(JV,                jv);
    REGISTER_DECODER(KGV1,              kgv1);
    REGISTER_DECODER(KMVC,              kmvc);
    REGISTER_DECODER(LAGARITH,          lagarith);
    REGISTER_ENCODER(LJPEG,             ljpeg);
    REGISTER_DECODER(LOCO,              loco);
    REGISTER_DECODER(M101,              m101);
    REGISTER_DECODER(MAGICYUV,          magicyuv);
    REGISTER_DECODER(MDEC,              mdec);
    REGISTER_DECODER(MIMIC,             mimic);
    REGISTER_ENCDEC (MJPEG,             mjpeg);
    REGISTER_DECODER(MJPEGB,            mjpegb);
    REGISTER_DECODER(MMVIDEO,           mmvideo);
    REGISTER_DECODER(MOTIONPIXELS,      motionpixels);
#if FF_API_XVMC
    REGISTER_DECODER(MPEG_XVMC,         mpeg_xvmc);
#endif /* FF_API_XVMC */
    REGISTER_ENCDEC (MPEG1VIDEO,        mpeg1video);
    REGISTER_ENCDEC (MPEG2VIDEO,        mpeg2video);
    REGISTER_ENCDEC (MPEG4,             mpeg4);
    REGISTER_DECODER(MPEG4_CRYSTALHD,   mpeg4_crystalhd);
    REGISTER_DECODER(MPEG4_MMAL,        mpeg4_mmal);
#if FF_API_VDPAU
    REGISTER_DECODER(MPEG4_VDPAU,       mpeg4_vdpau);
#endif
    REGISTER_DECODER(MPEGVIDEO,         mpegvideo);
#if FF_API_VDPAU
    REGISTER_DECODER(MPEG_VDPAU,        mpeg_vdpau);
    REGISTER_DECODER(MPEG1_VDPAU,       mpeg1_vdpau);
#endif
    REGISTER_DECODER(MPEG2_MMAL,        mpeg2_mmal);
    REGISTER_DECO

你可能感兴趣的:(ffmpeg)