AVInputFormat 再分析

AVInputFormat 是 FFmpeg 中用于描述输入格式(如文件容器、设备流等)的核心结构体,属于 libavformat 库的一部分。其主要功能是定义解封装(demuxing)过程中如何解析不同格式的输入数据。以下是其关键特性与使用方式的总结:

复制代码
/**
 * @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;

    /*****************************************************************
     * No fields below this line are part of the public API. They
     * may not be used outside of libavformat and can be changed and
     * removed at will.
     * New public fields should be added right above.
     *****************************************************************
     */
    ff_const59 struct AVInputFormat *next;

    /**
     * Raw demuxers store their codec ID here.
     */
    int raw_codec_id;

    /**
     * Size of private data so that it can be allocated in the wrapper.
     */
    int priv_data_size;

    /**
     * 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);

    /**
     * Initialize device capabilities submodule.
     * @see avdevice_capabilities_create() for more details.
     */
    int (*create_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);

    /**
     * Free device capabilities submodule.
     * @see avdevice_capabilities_free() for more details.
     */
    int (*free_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);
} AVInputFormat;
/**
 * @}
 */

1. 结构与字段

AVInputFormat 包含以下核心字段:

  • ‌**name** ‌:格式的短标识符(如 mp4avfoundation)。
  • ‌**long_name** ‌:格式的详细描述(如 MPEG-4 Part 14)。
  • ‌**extensions** ‌:支持的文件扩展名(如 mp4,mov)。
  • ‌**mime_type** ‌:关联的 MIME 类型(如 video/mp4)。
  • 函数指针 ‌:定义了操作输入格式的方法:
    • read_probe: 探测输入数据是否匹配当前格式。
    • read_header: 读取文件头信息。
    • read_packet: 读取数据包(如音频/视频帧)。
    • read_close: 关闭输入流并释放资源。

2. 功能与用途

  • 格式识别 ‌:通过 read_probe 自动探测输入数据的格式,或在调用 avformat_open_input 时显式指定。
  • 解封装流程‌:将容器文件(如 MP4)分离为独立的音视频流,供后续解码使用。
  • 设备支持 ‌:不仅支持文件格式,还可处理摄像头、麦克风等设备输入(如 macOS 的 avfoundation)。

3. 使用场景示例

初始化与注册

通过 av_register_all()(旧版本 FFmpeg)注册所有支持的格式,AVInputFormat 实例会以链表形式存储,供后续查找匹配46。

代码片段示例:

复制代码

cCopy Code

#include <libavformat/avformat.h> int main() { av_register_all(); // 注册格式(旧版本) AVFormatContext *fmt_ctx = avformat_alloc_context(); AVInputFormat *fmt = av_find_input_format("mp4"); // 显式指定格式 avformat_open_input(&fmt_ctx, "input.mp4", fmt, NULL); // ...后续处理 }

自动探测格式

若未指定 AVInputFormat,FFmpeg 会通过 init_input 函数分析文件内容或扩展名,调用匹配的 read_probe 确定格式57。


4. 与其他结构的关联

  • AVFormatContext ‌:上下文对象,存储解封装过程中的状态数据(如流信息、私有数据指针 priv_data)36。
  • AVOutputFormat‌:对应输出格式的结构,用于封装(muxing)流程78。

5. 扩展与定制

开发者可通过自定义 AVInputFormat 实现对新容器格式的支持,需实现探测、读包头、读数据包等函数,并注册到 FFmpeg 的全局链表中6。例如,SRT 字幕格式的解封装器实现中,定义了 srt_read_packet 等函数处理字幕数据包6。

6.那么具体的有哪些 AVInputFormat呢?

复制代码
static const AVInputFormat * const demuxer_list[] = {
    &ff_aa_demuxer,
    &ff_aac_demuxer,
    &ff_aax_demuxer,
    &ff_ac3_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_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_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_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_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_pjs_demuxer,
    &ff_pmp_demuxer,
    &ff_pp_bnk_demuxer,
    &ff_pva_demuxer,
    &ff_pvf_demuxer,
    &ff_qcp_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_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_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 };

也就是说,对于不同容器来说或者设备流来说,都有自己对应的 AVInputFormat。

7.那么某一个具体的mp4文件或者aac文件对应的 AVInputFormat如何知道呢?

av_find_input_format(const char *short_name);方法分析-CSDN博客

我们以mp4 和 aac 文件举例说明:

aac 对应的 AVInputFormat 为:

复制代码
const AVInputFormat ff_aac_demuxer = {
    .name         = "aac",
    .long_name    = NULL_IF_CONFIG_SMALL("raw ADTS AAC (Advanced Audio Coding)"),
    .read_probe   = adts_aac_probe,
    .read_header  = adts_aac_read_header,
    .read_packet  = adts_aac_read_packet,
    .flags        = AVFMT_GENERIC_INDEX,
    .extensions   = "aac",
    .mime_type    = "audio/aac,audio/aacp,audio/x-aac",
    .raw_codec_id = AV_CODEC_ID_AAC,
};

那么对应的三个方法

  • read_probe: 探测输入数据是否匹配当前格式。对于aac则调用adts_aac_probe方法
  • read_header: 读取文件头信息。对于aac则调用adts_aac_read_header方法
  • read_packet: 读取数据包(如音频/视频帧)。对于aac则调用adts_aac_read_packet方法

如果要理解 adts_aac_probe,adts_aac_read_header,adts_aac_read_packet这三个方法为什么这么写,就必要要 知道 aac 协议的情况,才能完整理解。从这里也能看出,ffmpeg是多么的强大,它将音视频所有格式的解封装都给开发者打包好了,再开发者不知道具体协议的情况下,调用一个函数就能搞定。

mp4 对应的 AVInputFormat 为:

复制代码
const AVInputFormat ff_mov_demuxer = {
    .name           = "mov,mp4,m4a,3gp,3g2,mj2",
    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
    .priv_class     = &mov_class,
    .priv_data_size = sizeof(MOVContext),
    .extensions     = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif",
    .flags_internal = FF_FMT_INIT_CLEANUP,
    .read_probe     = mov_probe,
    .read_header    = mov_read_header,
    .read_packet    = mov_read_packet,
    .read_close     = mov_read_close,
    .read_seek      = mov_read_seek,
    .flags          = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS | AVFMT_SHOW_IDS,
};

这个mp4对应的AVInputFormat 是如何找到的呢?一般的想法是从 demuxer_list.c中用眼睛看,有没有mp4之类的关键字,实际上这样是不合适的。

合适的方法是通过 av_find_input_format()

复制代码
int avinputformat() {

    AVInputFormat* input_format = av_find_input_format("mp4");
    if (input_format) {
        printf("Found input format: %s\n", input_format->name);
        cout << "input_format->long_name = " << input_format->long_name<< endl;
        //input_format.
    }
    else {
        printf("Input format not found!\n");
    }
    return 0;
}

可以通过打印出来的 short name,long name 等再search ffmpeg 源码,进而找到对应的 解复用器的 具体方法

例如我们 对于mp4打印的信息如下,

Found input format: mov,mp4,m4a,3gp,3g2,mj2

input_format->long_name = QuickTime / MOV

那么就可以在源码中search "mov,mp4,m4a,3gp,3g2,mj2" 关键字,进而找到解复用mp4文件的具体的 AVInputFormat。

复制代码
const AVInputFormat ff_mov_demuxer = {
    .name           = "mov,mp4,m4a,3gp,3g2,mj2",
    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
    .priv_class     = &mov_class,
    .priv_data_size = sizeof(MOVContext),
    .extensions     = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v,avif",
    .flags_internal = FF_FMT_INIT_CLEANUP,
    .read_probe     = mov_probe,
    .read_header    = mov_read_header,
    .read_packet    = mov_read_packet,
    .read_close     = mov_read_close,
    .read_seek      = mov_read_seek,
    .flags          = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS | AVFMT_SHOW_IDS,
};

同理,如果要知道mp4文件的对应的这些方法 为什么 这么写,就必要要明白 mp4协议,才能理解。

8.从解复用流程上再说明

在解复用文件的时候,会调用如下的如下三个函数

AVFormatContext *avformat_alloc_context(void);

int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat*fmt, AVDictionary **options);

int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);

在实际开发中,在avformat_open_input函数中,需要传递一个 AVInputFormat ,当我们传递的AVInputFormat 为nullptr时,ffmpeg 在 avformat_open_input源码中是如何知道你要解析的文件,用的是那个具体的 AVInputFormat呢?

参考 avformat_open_input的过程分析,这个哥们很多博客都写的不错。

ffmpeg的avformat_open_input()分析过程--以mp4为例(十)_ffmpeg mp4 avformat-CSDN博客

‌9. 设备支持 ‌:从摄像头、麦克风等设备输入(如 macOS 的 avfoundation)。

​从前面的学习我们知道,

用于根据输入格式的名称(如 "mp4"、"wav"、"avfoundation" 等)查找对应的输入格式结构体 AVInputFormat。

av_find_input_format(const char *short_name);方法分析-CSDN博客

相关推荐
RIKI_12 小时前
【浅学】Windows下ffmpeg+nginx+flv将本地视频推流在本地搭建的Web前端页面中播放,超详细步骤
windows·nginx·ffmpeg·html
hunandede2 小时前
AVFormatContext 再分析零
ffmpeg
hunandede3 小时前
AVDictionary 再分析
ffmpeg
yanjiee3 小时前
用docker ffmpeg测试视频vmaf分数,很快不用编译
docker·ffmpeg·音视频
achene_ql7 小时前
深入探索 AAC 编码原理与 ADTS 格式:音频世界的智慧结晶
ffmpeg·音视频·aac
NO Exception?16 小时前
完美解决 mobile-ffmpeg Not overwriting - exiting
android·ffmpeg·pcm
shao91851616 小时前
Gradio全解20——Streaming:流式传输的多媒体应用(3)——实时语音识别技术
人工智能·ffmpeg·语音识别·transformers·gradio·asr
Antonio91519 小时前
【音视频】RTMP流媒体服务器搭建、推流拉流
服务器·ffmpeg·音视频
hunandede2 天前
ffmpeg 元数据
ffmpeg