欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > 7.0.1版本的FFmpeg源码中av_probe_input_format3函数和AVInputFormat结构体的改变

7.0.1版本的FFmpeg源码中av_probe_input_format3函数和AVInputFormat结构体的改变

2024/10/25 5:27:45 来源:https://blog.csdn.net/u014552102/article/details/141128103  浏览:    关键词:7.0.1版本的FFmpeg源码中av_probe_input_format3函数和AVInputFormat结构体的改变

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

FFmpeg源码:av_probe_input_format3函数分析:

FFmpeg源码:av_probe_input_format3函数和AVInputFormat结构体分析(FFmpeg源码5.0.3版本)

7.0.1版本的FFmpeg源码中av_probe_input_format3函数和AVInputFormat结构体的改变

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

一、引言

之前我一直用5.0.3版本的FFmpeg,最近下载了7.0.1版本的FFmpeg,发现新版本的源码中,某些地方(比如av_probe_input_format3函数和AVInputFormat结构体)发生了变化。所以写下这篇文章记录新版的FFmpeg源码中av_probe_input_format3函数和AVInputFormat结构体的改变。阅读本文之前推荐先阅读《FFmpeg源码:av_probe_input_format3函数分析(FFmpeg源码5.0.3版本)》。

二、AVInputFormat结构体的变化

新版本的AVInputFormat结构体还是声明在libavformat/avformat.h中。可以看到它的部分成员变量(name、long_name、flags、extensions、codec_tag、priv_class、mime_type)被保留了下来,但是其它成员变量被删掉了,被删掉的成员变量被移动到了FFInputFormat中:

/*** @addtogroup lavf_decoding* @{*/
typedef struct AVInputFormat {/*** A comma separated list of short names for the format. New names* may be appended with a minor bump.*/const char *name;/*** Descriptive name for the format, meant to be more human-readable* than name. You should use the NULL_IF_CONFIG_SMALL() macro* to define it.*/const char *long_name;/*** Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS,* AVFMT_NOTIMESTAMPS, AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH,* AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS.*/int flags;/*** If extensions are defined, then no probe is done. You should* usually not use extension format guessing because it is not* reliable enough*/const char *extensions;const struct AVCodecTag * const *codec_tag;const AVClass *priv_class; ///< AVClass for the private context/*** Comma-separated list of mime types.* It is used check for matching mime types while probing.* @see av_probe_input_format2*/const char *mime_type;
} AVInputFormat;

三、FFInputFormat结构体

FFInputFormat是新版本FFmpeg源码中新增加的结构体,AVInputFormat结构体被删除的成员变量被移动到了FFInputFormat中:

typedef struct FFInputFormat {/*** The public AVInputFormat. See avformat.h for it.*/AVInputFormat p;/*** Raw demuxers store their codec ID here.*/enum AVCodecID raw_codec_id;/*** Size of private data so that it can be allocated in the wrapper.*/int priv_data_size;/*** Internal flags. See FF_INFMT_FLAG_* above and FF_FMT_FLAG_* in internal.h.*/int flags_internal;/*** Tell if a given file has a chance of being parsed as this format.* The buffer provided is guaranteed to be AVPROBE_PADDING_SIZE bytes* big so you do not have to check for that unless you need more.*/int (*read_probe)(const AVProbeData *);/*** Read the format header and initialize the AVFormatContext* structure. Return 0 if OK. 'avformat_new_stream' should be* called to create new streams.*/int (*read_header)(struct AVFormatContext *);/*** Read one packet and put it in 'pkt'. pts and flags are also* set. 'avformat_new_stream' can be called only if the flag* AVFMTCTX_NOHEADER is used and only in the calling thread (not in a* background thread).* @return 0 on success, < 0 on error.*         Upon returning an error, pkt must be unreferenced by the caller.*/int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);/*** Close the stream. The AVFormatContext and AVStreams are not* freed by this function*/int (*read_close)(struct AVFormatContext *);/*** Seek to a given timestamp relative to the frames in* stream component stream_index.* @param stream_index Must not be -1.* @param flags Selects which direction should be preferred if no exact*              match is available.* @return >= 0 on success (but not necessarily the new offset)*/int (*read_seek)(struct AVFormatContext *,int stream_index, int64_t timestamp, int flags);/*** Get the next timestamp in stream[stream_index].time_base units.* @return the timestamp or AV_NOPTS_VALUE if an error occurred*/int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index,int64_t *pos, int64_t pos_limit);/*** Start/resume playing - only meaningful if using a network-based format* (RTSP).*/int (*read_play)(struct AVFormatContext *);/*** Pause playing - only meaningful if using a network-based format* (RTSP).*/int (*read_pause)(struct AVFormatContext *);/*** Seek to timestamp ts.* Seeking will be done so that the point from which all active streams* can be presented successfully will be closest to ts and within min/max_ts.* Active streams are all streams that have AVStream.discard < AVDISCARD_ALL.*/int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);/*** Returns device list with it properties.* @see avdevice_list_devices() for more details.*/int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list);
} FFInputFormat;

FFInputFormat结构体通过一个AVInputFormat类型的成员变量p来存放AVInputFormat结构体的其它成员(name、long_name、flags、extensions、codec_tag、priv_class、mime_type)。所以新版本FFmpeg源码中解复用器结构体从AVInputFormat变成了FFInputFormat,每种作为输入的封装格式(例如BMP、FLV、WAV、MP4、TS、H.264裸流文件等)都对应一种FFInputFormat结构。

比如BMP这种图片的封装格式,它对应的FFInputFormat结构为:

const FFInputFormat ff_image_bmp_pipe_demuxer = {
.p.name         = "bmp_pipe",
.p.long_name    = "piped bmp sequence",
.p.priv_class   = &imagepipe_class,
.p.flags        = 256,
.priv_data_size = 1208,
.read_probe     = bmp_probe,
.read_header    = ff_img_read_header,
.read_packet    = ff_img_read_packet,
.raw_codec_id   = AV_CODEC_ID_BMP,
};

H.264裸流文件对应的FFInputFormat结构为:

const AVInputFormat ff_h264_demuxer= {
.p.name           = "h264",
.p.long_name      = "raw H.264 video",
.p.priv_class     = &ff_rawvideo_demuxer_class,
.p.flags          = 384,
.priv_data_size   = 40,
.read_probe       = h264_probe,
.read_header      = ff_raw_video_read_header,
.read_packet      = ff_raw_read_partial_packet,
.raw_codec_id     = AV_CODEC_ID_H264,
};

wav音频文件对应的FFInputFormat结构为:

const FFInputFormat ff_wav_demuxer = {.p.name         = "wav",.p.long_name    = "WAV / WAVE (Waveform Audio)",.p.priv_class   = &wav_demuxer_class,.p.flags        = 256,.p.codec_tag    = ff_wav_codec_tags_list,.priv_data_size = 88,.read_probe     = wav_probe,.read_header    = wav_read_header,.read_packet    = wav_read_packet,.read_seek      = wav_read_seek,
};

四、全局数组demuxer_list的变化

全局数组demuxer_list定义在libavformat/demuxer_list.c中,它的元素从AVInputFormat类型变为了FFInputFormat类型:

static const FFInputFormat * const demuxer_list[] = {&ff_aa_demuxer,&ff_aac_demuxer,&ff_aax_demuxer,&ff_ac3_demuxer,&ff_ac4_demuxer,&ff_ace_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_alp_demuxer,&ff_amr_demuxer,&ff_amrnb_demuxer,&ff_amrwb_demuxer,&ff_anm_demuxer,&ff_apac_demuxer,&ff_apc_demuxer,&ff_ape_demuxer,&ff_apm_demuxer,&ff_apng_demuxer,&ff_aptx_demuxer,&ff_aptx_hd_demuxer,&ff_aqtitle_demuxer,&ff_argo_asf_demuxer,&ff_argo_brp_demuxer,&ff_argo_cvg_demuxer,&ff_asf_demuxer,&ff_asf_o_demuxer,&ff_ass_demuxer,&ff_ast_demuxer,&ff_au_demuxer,&ff_av1_demuxer,&ff_avi_demuxer,&ff_avr_demuxer,&ff_avs_demuxer,&ff_avs2_demuxer,&ff_avs3_demuxer,&ff_bethsoftvid_demuxer,&ff_bfi_demuxer,&ff_bintext_demuxer,&ff_bink_demuxer,&ff_binka_demuxer,&ff_bit_demuxer,&ff_bitpacked_demuxer,&ff_bmv_demuxer,&ff_bfstm_demuxer,&ff_brstm_demuxer,&ff_boa_demuxer,&ff_bonk_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_derf_demuxer,&ff_dfa_demuxer,&ff_dfpwm_demuxer,&ff_dhav_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_evc_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_fwse_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_hca_demuxer,&ff_hcom_demuxer,&ff_hevc_demuxer,&ff_hls_demuxer,&ff_hnm_demuxer,&ff_iamf_demuxer,&ff_ico_demuxer,&ff_idcin_demuxer,&ff_idf_demuxer,&ff_iff_demuxer,&ff_ifv_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_ipu_demuxer,&ff_ircam_demuxer,&ff_iss_demuxer,&ff_iv8_demuxer,&ff_ivf_demuxer,&ff_ivr_demuxer,&ff_jacosub_demuxer,&ff_jv_demuxer,&ff_jpegxl_anim_demuxer,&ff_kux_demuxer,&ff_kvag_demuxer,&ff_laf_demuxer,&ff_lmlm4_demuxer,&ff_loas_demuxer,&ff_luodat_demuxer,&ff_lrc_demuxer,&ff_lvf_demuxer,&ff_lxf_demuxer,&ff_m4v_demuxer,&ff_mca_demuxer,&ff_mcc_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_mods_demuxer,&ff_moflex_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_msp_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_obu_demuxer,&ff_ogg_demuxer,&ff_oma_demuxer,&ff_osq_demuxer,&ff_paf_demuxer,&ff_pcm_alaw_demuxer,&ff_pcm_mulaw_demuxer,&ff_pcm_vidc_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_pdv_demuxer,&ff_pjs_demuxer,&ff_pmp_demuxer,&ff_pp_bnk_demuxer,&ff_pva_demuxer,&ff_pvf_demuxer,&ff_qcp_demuxer,&ff_qoa_demuxer,&ff_r3d_demuxer,&ff_rawvideo_demuxer,&ff_realtext_demuxer,&ff_redspark_demuxer,&ff_rka_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_scd_demuxer,&ff_sdns_demuxer,&ff_sdp_demuxer,&ff_sdr2_demuxer,&ff_sds_demuxer,&ff_sdx_demuxer,&ff_segafilm_demuxer,&ff_ser_demuxer,&ff_sga_demuxer,&ff_shorten_demuxer,&ff_siff_demuxer,&ff_simbiosis_imx_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_svs_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_usm_demuxer,&ff_v210_demuxer,&ff_v210x_demuxer,&ff_vag_demuxer,&ff_vc1_demuxer,&ff_vc1t_demuxer,&ff_vividas_demuxer,&ff_vivo_demuxer,&ff_vmd_demuxer,&ff_vobsub_demuxer,&ff_voc_demuxer,&ff_vpk_demuxer,&ff_vplayer_demuxer,&ff_vqf_demuxer,&ff_vvc_demuxer,&ff_w64_demuxer,&ff_wady_demuxer,&ff_wavarc_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_xmd_demuxer,&ff_xmv_demuxer,&ff_xvag_demuxer,&ff_xwma_demuxer,&ff_yop_demuxer,&ff_yuv4mpegpipe_demuxer,&ff_image_bmp_pipe_demuxer,&ff_image_cri_pipe_demuxer,&ff_image_dds_pipe_demuxer,&ff_image_dpx_pipe_demuxer,&ff_image_exr_pipe_demuxer,&ff_image_gem_pipe_demuxer,&ff_image_gif_pipe_demuxer,&ff_image_hdr_pipe_demuxer,&ff_image_j2k_pipe_demuxer,&ff_image_jpeg_pipe_demuxer,&ff_image_jpegls_pipe_demuxer,&ff_image_jpegxl_pipe_demuxer,&ff_image_pam_pipe_demuxer,&ff_image_pbm_pipe_demuxer,&ff_image_pcx_pipe_demuxer,&ff_image_pfm_pipe_demuxer,&ff_image_pgmyuv_pipe_demuxer,&ff_image_pgm_pipe_demuxer,&ff_image_pgx_pipe_demuxer,&ff_image_phm_pipe_demuxer,&ff_image_photocd_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_qoi_pipe_demuxer,&ff_image_sgi_pipe_demuxer,&ff_image_svg_pipe_demuxer,&ff_image_sunrast_pipe_demuxer,&ff_image_tiff_pipe_demuxer,&ff_image_vbn_pipe_demuxer,&ff_image_webp_pipe_demuxer,&ff_image_xbm_pipe_demuxer,&ff_image_xpm_pipe_demuxer,&ff_image_xwd_pipe_demuxer,NULL };

五、av_probe_input_format3函数的变化

av_probe_input_format3函数声明在头文件libavformat/avformat.h中:

/*** Guess the file format.** @param is_opened Whether the file is already opened; determines whether*                  demuxers with or without AVFMT_NOFILE are probed.* @param score_ret The score of the best detection.*/
const AVInputFormat *av_probe_input_format3(const AVProbeData *pd,int is_opened, int *score_ret);

可以看到7.0.1版本的av_probe_input_format3函数的形参和返回值和5.0.3版本中的是完全一样的,作用也是一样。不一样的只是它返回的AVInputFormat结构体的结构发生了改变。

旧版本的AVInputFormat直接包含了read_probe等函数指针,但新版本的函数指针在FFInputFormat结构体中。所以如果想要调用这些指针指向的回调函数,可以使用ffifmt函数进行结构体强转,该函数定义在libavformat/demux.h中:

static inline const FFInputFormat *ffifmt(const AVInputFormat *fmt)
{return (const FFInputFormat*)fmt;
}

ffifmt函数作用是把AVInputFormat结构体强转为FFInputFormat结构体,使用方式如下:

if (ffifmt(fmt1)->read_probe)score = ffifmt(fmt1)->read_probe(&lpd);

六、av_demuxer_iterate函数的变化

av_probe_input_format3函数内部调用了av_demuxer_iterate函数,我们来看看新版av_demuxer_iterate函数的变化:

const AVInputFormat *av_demuxer_iterate(void **opaque)
{static const uintptr_t size = sizeof(demuxer_list)/sizeof(demuxer_list[0]) - 1;uintptr_t i = (uintptr_t)*opaque;const FFInputFormat *f = NULL;uintptr_t tmp;if (i < size) {f = demuxer_list[i];} else if (tmp = atomic_load_explicit(&indev_list_intptr, memory_order_relaxed)) {const FFInputFormat *const *indev_list = (const FFInputFormat *const *)tmp;f = indev_list[i - size];}if (f) {*opaque = (void*)(i + 1);return &f->p;}return NULL;
}

可以看到av_demuxer_iterate函数中,由于全局数组demuxer_list的元素从AVInputFormat类型变为了FFInputFormat类型,所以该函数的部分细节也发生了改变。

av_demuxer_iterate函数最后通过下面语句返回demuxer_list[i]对应的AVInputFormat结构:

    if (f) {*opaque = (void*)(i + 1);return &f->p;}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com