在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