ffmpeg 源代码简单分析 av_register_all() 基于4.02 author:上官可编程(抖音)
void av_register_all(void)
{
ff_thread_once(&av_format_next_init, av_format_init_next);
}
static inline int ff_thread_once(char *control, void (*routine)(void))
{
if (!*control) {
routine();
*control = 1;
}
return 0;
}
static AVOnce av_format_next_init = AV_ONCE_INIT;
#define AV_ONCE_INIT 0
ff_thread_once 第一个实参定义为static AVOnce av_format_next_init = AV_ONCE_INIT;
AV_ONCE_INIT初始值为0
所以ff_thread_once中的if(!*control)条件成立,执行函数指针routine代表的函数,也就是调用ff_thread_once中第二个实参 av_format_init_next 函数,同时写入cotrol的值为1,下次被调用的时候,就不满足条件判断,这边处理体现了所谓的ff_thread_once 中的once定义
真正的初始化函数是av_format_init_next,这种处理方式能导致不管调用多少次的av_register_all,都才执行一次的av_format_init_next真实初始化函数。
——————————————————————————————————————————
接着看下av_format_init_next做哪些事儿
static void av_format_init_next(void)
{
AVOutputFormat *prevout = NULL, *out;
AVInputFormat *previn = NULL, *in;
ff_mutex_lock(&avpriv_register_devices_mutex);
for (int i = 0; (out = (AVOutputFormat*)muxer_list[i]); i++) {
if (prevout)
prevout->next = out;
prevout = out;
}
if (outdev_list) {
for (int i = 0; (out = (AVOutputFormat*)outdev_list[i]); i++) {
if (prevout)
prevout->next = out;
prevout = out;
}
}
for (int i = 0; (in = (AVInputFormat*)demuxer_list[i]); i++) {
if (previn)
previn->next = in;
previn = in;
}
if (indev_list) {
for (int i = 0; (in = (AVInputFormat*)indev_list[i]); i++) {
if (previn)
previn->next = in;
previn = in;
}
}
ff_mutex_unlock(&avpriv_register_devices_mutex);
}
这个初始化函数主要针对输入输出的复用器和解复用器加载,每一种复用器用结构体表示,所支持的复用器和解复用器以简单工厂模式的设计方法进行管理。放在链表 AVOutputFormat *prevout中进行管理。
于是这个函数执行的结果生产输入和输出的(复用器,编码器)的”资源整合“。后面根据特定开发场景在两个链表中找到目标复用器和解复用器使用。(复用可以理解成封装,比如封装成flv格式)
复用器列表如下
static const AVOutputFormat * const muxer_list[] = {
&ff_a64_muxer,
&ff_ac3_muxer,
&ff_adts_muxer,
&ff_adx_muxer,
&ff_aiff_muxer,
&ff_amr_muxer,
&ff_apng_muxer,
&ff_aptx_muxer,
&ff_aptx_hd_muxer,
&ff_asf_muxer,
&ff_ass_muxer,
&ff_ast_muxer,
&ff_asf_stream_muxer,
&ff_au_muxer,
&ff_avi_muxer,
&ff_avm2_muxer,
&ff_bit_muxer,
&ff_caf_muxer,
&ff_cavsvideo_muxer,
&ff_codec2_muxer,
&ff_codec2raw_muxer,
&ff_crc_muxer,
&ff_dash_muxer,
&ff_data_muxer,
&ff_daud_muxer,
&ff_dirac_muxer,
&ff_dnxhd_muxer,
&ff_dts_muxer,
&ff_dv_muxer,
&ff_eac3_muxer,
&ff_f4v_muxer,
&ff_ffmetadata_muxer,
&ff_fifo_muxer,
&ff_fifo_test_muxer,
&ff_filmstrip_muxer,
&ff_fits_muxer,
&ff_flac_muxer,
&ff_flv_muxer,
&ff_framecrc_muxer,
&ff_framehash_muxer,
&ff_framemd5_muxer,
&ff_g722_muxer,
&ff_g723_1_muxer,
&ff_g726_muxer,
&ff_g726le_muxer,
&ff_gif_muxer,
&ff_gsm_muxer,
&ff_gxf_muxer,
&ff_h261_muxer,
&ff_h263_muxer,
&ff_h264_muxer,
&ff_hash_muxer,
&ff_hds_muxer,
&ff_hevc_muxer,
&ff_hls_muxer,
&ff_ico_muxer,
&ff_ilbc_muxer,
&ff_image2_muxer,
&ff_image2pipe_muxer,
&ff_ipod_muxer,
&ff_ircam_muxer,
&ff_ismv_muxer,
&ff_ivf_muxer,
&ff_jacosub_muxer,
&ff_latm_muxer,
&ff_lrc_muxer,
&ff_m4v_muxer,
&ff_md5_muxer,
&ff_matroska_muxer,
&ff_matroska_audio_muxer,
&ff_microdvd_muxer,
&ff_mjpeg_muxer,
&ff_mlp_muxer,
&ff_mmf_muxer,
&ff_mov_muxer,
&ff_mp2_muxer,
&ff_mp3_muxer,
&ff_mp4_muxer,
&ff_mpeg1system_muxer,
&ff_mpeg1vcd_muxer,
&ff_mpeg1video_muxer,
&ff_mpeg2dvd_muxer,
&ff_mpeg2svcd_muxer,
&ff_mpeg2video_muxer,
&ff_mpeg2vob_muxer,
&ff_mpegts_muxer,
&ff_mpjpeg_muxer,
&ff_mxf_muxer,
&ff_mxf_d10_muxer,
&ff_mxf_opatom_muxer,
&ff_null_muxer,
&ff_nut_muxer,
&ff_oga_muxer,
&ff_ogg_muxer,
&ff_ogv_muxer,
&ff_oma_muxer,
&ff_opus_muxer,
&ff_pcm_alaw_muxer,
&ff_pcm_mulaw_muxer,
&ff_pcm_f64be_muxer,
&ff_pcm_f64le_muxer,
&ff_pcm_f32be_muxer,
&ff_pcm_f32le_muxer,
&ff_pcm_s32be_muxer,
&ff_pcm_s32le_muxer,
&ff_pcm_s24be_muxer,
&ff_pcm_s24le_muxer,
&ff_pcm_s16be_muxer,
&ff_pcm_s16le_muxer,
&ff_pcm_s8_muxer,
&ff_pcm_u32be_muxer,
&ff_pcm_u32le_muxer,
&ff_pcm_u24be_muxer,
&ff_pcm_u24le_muxer,
&ff_pcm_u16be_muxer,
&ff_pcm_u16le_muxer,
&ff_pcm_u8_muxer,
&ff_psp_muxer,
&ff_rawvideo_muxer,
&ff_rm_muxer,
&ff_roq_muxer,
&ff_rso_muxer,
&ff_rtp_muxer,
&ff_rtp_mpegts_muxer,
&ff_rtsp_muxer,
&ff_sap_muxer,
&ff_sbc_muxer,
&ff_scc_muxer,
&ff_segafilm_muxer,
&ff_segment_muxer,
&ff_stream_segment_muxer,
&ff_singlejpeg_muxer,
&ff_smjpeg_muxer,
&ff_smoothstreaming_muxer,
&ff_sox_muxer,
&ff_spx_muxer,
&ff_spdif_muxer,
&ff_srt_muxer,
&ff_sup_muxer,
&ff_swf_muxer,
&ff_tee_muxer,
&ff_tg2_muxer,
&ff_tgp_muxer,
&ff_mkvtimestamp_v2_muxer,
&ff_truehd_muxer,
&ff_tta_muxer,
&ff_uncodedframecrc_muxer,
&ff_vc1_muxer,
&ff_vc1t_muxer,
&ff_voc_muxer,
&ff_w64_muxer,
&ff_wav_muxer,
&ff_webm_muxer,
&ff_webm_dash_manifest_muxer,
&ff_webm_chunk_muxer,
&ff_webp_muxer,
&ff_webvtt_muxer,
&ff_wtv_muxer,
&ff_wv_muxer,
&ff_yuv4mpegpipe_muxer,
NULL };
解复用器列表如下;
static const AVInputFormat * const demuxer_list[] = {
&ff_aa_demuxer,
&ff_aac_demuxer,
&ff_ac3_demuxer,
&ff_acm_demuxer,
&ff_act_demuxer,
&ff_adf_demuxer,
&ff_adp_demuxer,
&ff_ads_demuxer,
&ff_adx_demuxer,
&ff_aea_demuxer,
&ff_afc_demuxer,
&ff_aiff_demuxer,
&ff_aix_demuxer,
&ff_amr_demuxer,
&ff_amrnb_demuxer,
&ff_amrwb_demuxer,
&ff_anm_demuxer,
&ff_apc_demuxer,
&ff_ape_demuxer,
&ff_apng_demuxer,
&ff_aptx_demuxer,
&ff_aptx_hd_demuxer,
&ff_aqtitle_demuxer,
&ff_asf_demuxer,
&ff_asf_o_demuxer,
&ff_ass_demuxer,
&ff_ast_demuxer,
&ff_au_demuxer,
&ff_avi_demuxer,
&ff_avr_demuxer,
&ff_avs_demuxer,
&ff_bethsoftvid_demuxer,
&ff_bfi_demuxer,
&ff_bintext_demuxer,
&ff_bink_demuxer,
&ff_bit_demuxer,
&ff_bmv_demuxer,
&ff_bfstm_demuxer,
&ff_brstm_demuxer,
&ff_boa_demuxer,
&ff_c93_demuxer,
&ff_caf_demuxer,
&ff_cavsvideo_demuxer,
&ff_cdg_demuxer,
&ff_cdxl_demuxer,
&ff_cine_demuxer,
&ff_codec2_demuxer,
&ff_codec2raw_demuxer,
&ff_concat_demuxer,
&ff_data_demuxer,
&ff_daud_demuxer,
&ff_dcstr_demuxer,
&ff_dfa_demuxer,
&ff_dirac_demuxer,
&ff_dnxhd_demuxer,
&ff_dsf_demuxer,
&ff_dsicin_demuxer,
&ff_dss_demuxer,
&ff_dts_demuxer,
&ff_dtshd_demuxer,
&ff_dv_demuxer,
&ff_dvbsub_demuxer,
&ff_dvbtxt_demuxer,
&ff_dxa_demuxer,
&ff_ea_demuxer,
&ff_ea_cdata_demuxer,
&ff_eac3_demuxer,
&ff_epaf_demuxer,
&ff_ffmetadata_demuxer,
&ff_filmstrip_demuxer,
&ff_fits_demuxer,
&ff_flac_demuxer,
&ff_flic_demuxer,
&ff_flv_demuxer,
&ff_live_flv_demuxer,
&ff_fourxm_demuxer,
&ff_frm_demuxer,
&ff_fsb_demuxer,
&ff_g722_demuxer,
&ff_g723_1_demuxer,
&ff_g726_demuxer,
&ff_g726le_demuxer,
&ff_g729_demuxer,
&ff_gdv_demuxer,
&ff_genh_demuxer,
&ff_gif_demuxer,
&ff_gsm_demuxer,
&ff_gxf_demuxer,
&ff_h261_demuxer,
&ff_h263_demuxer,
&ff_h264_demuxer,
&ff_hevc_demuxer,
&ff_hls_demuxer,
&ff_hnm_demuxer,
&ff_ico_demuxer,
&ff_idcin_demuxer,
&ff_idf_demuxer,
&ff_iff_demuxer,
&ff_ilbc_demuxer,
&ff_image2_demuxer,
&ff_image2pipe_demuxer,
&ff_image2_alias_pix_demuxer,
&ff_image2_brender_pix_demuxer,
&ff_ingenient_demuxer,
&ff_ipmovie_demuxer,
&ff_ircam_demuxer,
&ff_iss_demuxer,
&ff_iv8_demuxer,
&ff_ivf_demuxer,
&ff_ivr_demuxer,
&ff_jacosub_demuxer,
&ff_jv_demuxer,
&ff_lmlm4_demuxer,
&ff_loas_demuxer,
&ff_lrc_demuxer,
&ff_lvf_demuxer,
&ff_lxf_demuxer,
&ff_m4v_demuxer,
&ff_matroska_demuxer,
&ff_mgsts_demuxer,
&ff_microdvd_demuxer,
&ff_mjpeg_demuxer,
&ff_mjpeg_2000_demuxer,
&ff_mlp_demuxer,
&ff_mlv_demuxer,
&ff_mm_demuxer,
&ff_mmf_demuxer,
&ff_mov_demuxer,
&ff_mp3_demuxer,
&ff_mpc_demuxer,
&ff_mpc8_demuxer,
&ff_mpegps_demuxer,
&ff_mpegts_demuxer,
&ff_mpegtsraw_demuxer,
&ff_mpegvideo_demuxer,
&ff_mpjpeg_demuxer,
&ff_mpl2_demuxer,
&ff_mpsub_demuxer,
&ff_msf_demuxer,
&ff_msnwc_tcp_demuxer,
&ff_mtaf_demuxer,
&ff_mtv_demuxer,
&ff_musx_demuxer,
&ff_mv_demuxer,
&ff_mvi_demuxer,
&ff_mxf_demuxer,
&ff_mxg_demuxer,
&ff_nc_demuxer,
&ff_nistsphere_demuxer,
&ff_nsp_demuxer,
&ff_nsv_demuxer,
&ff_nut_demuxer,
&ff_nuv_demuxer,
&ff_ogg_demuxer,
&ff_oma_demuxer,
&ff_paf_demuxer,
&ff_pcm_alaw_demuxer,
&ff_pcm_mulaw_demuxer,
&ff_pcm_f64be_demuxer,
&ff_pcm_f64le_demuxer,
&ff_pcm_f32be_demuxer,
&ff_pcm_f32le_demuxer,
&ff_pcm_s32be_demuxer,
&ff_pcm_s32le_demuxer,
&ff_pcm_s24be_demuxer,
&ff_pcm_s24le_demuxer,
&ff_pcm_s16be_demuxer,
&ff_pcm_s16le_demuxer,
&ff_pcm_s8_demuxer,
&ff_pcm_u32be_demuxer,
&ff_pcm_u32le_demuxer,
&ff_pcm_u24be_demuxer,
&ff_pcm_u24le_demuxer,
&ff_pcm_u16be_demuxer,
&ff_pcm_u16le_demuxer,
&ff_pcm_u8_demuxer,
&ff_pjs_demuxer,
&ff_pmp_demuxer,
&ff_pva_demuxer,
&ff_pvf_demuxer,
&ff_qcp_demuxer,
&ff_r3d_demuxer,
&ff_rawvideo_demuxer,
&ff_realtext_demuxer,
&ff_redspark_demuxer,
&ff_rl2_demuxer,
&ff_rm_demuxer,
&ff_roq_demuxer,
&ff_rpl_demuxer,
&ff_rsd_demuxer,
&ff_rso_demuxer,
&ff_rtp_demuxer,
&ff_rtsp_demuxer,
&ff_s337m_demuxer,
&ff_sami_demuxer,
&ff_sap_demuxer,
&ff_sbc_demuxer,
&ff_sbg_demuxer,
&ff_scc_demuxer,
&ff_sdp_demuxer,
&ff_sdr2_demuxer,
&ff_sds_demuxer,
&ff_sdx_demuxer,
&ff_segafilm_demuxer,
&ff_shorten_demuxer,
&ff_siff_demuxer,
&ff_sln_demuxer,
&ff_smacker_demuxer,
&ff_smjpeg_demuxer,
&ff_smush_demuxer,
&ff_sol_demuxer,
&ff_sox_demuxer,
&ff_spdif_demuxer,
&ff_srt_demuxer,
&ff_str_demuxer,
&ff_stl_demuxer,
&ff_subviewer1_demuxer,
&ff_subviewer_demuxer,
&ff_sup_demuxer,
&ff_svag_demuxer,
&ff_swf_demuxer,
&ff_tak_demuxer,
&ff_tedcaptions_demuxer,
&ff_thp_demuxer,
&ff_threedostr_demuxer,
&ff_tiertexseq_demuxer,
&ff_tmv_demuxer,
&ff_truehd_demuxer,
&ff_tta_demuxer,
&ff_txd_demuxer,
&ff_tty_demuxer,
&ff_ty_demuxer,
&ff_v210_demuxer,
&ff_v210x_demuxer,
&ff_vag_demuxer,
&ff_vc1_demuxer,
&ff_vc1t_demuxer,
&ff_vivo_demuxer,
&ff_vmd_demuxer,
&ff_vobsub_demuxer,
&ff_voc_demuxer,
&ff_vpk_demuxer,
&ff_vplayer_demuxer,
&ff_vqf_demuxer,
&ff_w64_demuxer,
&ff_wav_demuxer,
&ff_wc3_demuxer,
&ff_webm_dash_manifest_demuxer,
&ff_webvtt_demuxer,
&ff_wsaud_demuxer,
&ff_wsd_demuxer,
&ff_wsvqa_demuxer,
&ff_wtv_demuxer,
&ff_wve_demuxer,
&ff_wv_demuxer,
&ff_xa_demuxer,
&ff_xbin_demuxer,
&ff_xmv_demuxer,
&ff_xvag_demuxer,
&ff_xwma_demuxer,
&ff_yop_demuxer,
&ff_yuv4mpegpipe_demuxer,
&ff_image_bmp_pipe_demuxer,
&ff_image_dds_pipe_demuxer,
&ff_image_dpx_pipe_demuxer,
&ff_image_exr_pipe_demuxer,
&ff_image_j2k_pipe_demuxer,
&ff_image_jpeg_pipe_demuxer,
&ff_image_jpegls_pipe_demuxer,
&ff_image_pam_pipe_demuxer,
&ff_image_pbm_pipe_demuxer,
&ff_image_pcx_pipe_demuxer,
&ff_image_pgmyuv_pipe_demuxer,
&ff_image_pgm_pipe_demuxer,
&ff_image_pictor_pipe_demuxer,
&ff_image_png_pipe_demuxer,
&ff_image_ppm_pipe_demuxer,
&ff_image_psd_pipe_demuxer,
&ff_image_qdraw_pipe_demuxer,
&ff_image_sgi_pipe_demuxer,
&ff_image_svg_pipe_demuxer,
&ff_image_sunrast_pipe_demuxer,
&ff_image_tiff_pipe_demuxer,
&ff_image_webp_pipe_demuxer,
&ff_image_xpm_pipe_demuxer,
NULL };
解复用器:
static const AVInputFormat * const indev_list[] = {
&ff_fbdev_demuxer,
&ff_lavfi_demuxer,
&ff_oss_demuxer,
&ff_v4l2_demuxer,
NULL };
复用器
static const AVOutputFormat * const outdev_list[] = {
&ff_fbdev_muxer,
&ff_oss_muxer,
&ff_sdl2_muxer,
&ff_v4l2_muxer,
NULL };
随便找个复用器看看内容,比如AVI文件的复用器
AVOutputFormat ff_avi_muxer = {
.name = "avi",
.long_name = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
.mime_type = "video/x-msvideo",
.extensions = "avi",
.priv_data_size = sizeof(AVIContext),
.audio_codec = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_AC3,
.video_codec = AV_CODEC_ID_MPEG4,
.init = avi_init,
.write_header = avi_write_header,
.write_packet = avi_write_packet,
.write_trailer = avi_write_trailer,
.codec_tag = (const AVCodecTag * const []) {
ff_codec_bmp_tags, ff_codec_wav_tags, 0
},
.priv_class = &avi_muxer_class,
};
总结:
这个函数做ffmpegSDK开发之前必须要被调用的函数,主要是对资源的初始化,简单工厂模式的设计原理。Linux内核也大量采用如此设计方式,值得各位coder在做应用层项目时候学习。
关于本人更多信息,可以参考抖音:上官可编程 已培养众多海康,大华,中兴,华为等嵌入式工程师。
文章来自于网络,如果侵犯了您的权益,请联系站长删除!