ffmpeg之avformat_alloc_output_context2

函数原型:

复制代码
int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat,
                                   const char *format_name, const char *filename);

功能:

查找根据format_name或者filename或者oformat输出类型,并且初始化ctx结构。

参数:

ctx:      AVFormatContext结构体,ffmpeg核心结构体,会在函数内部给ctx分配AVFormatContext空间并初始化。

oformat:    指定输出格式的 AVOutputFormat 结构体指针。可以使用 NULL,此时将根据 format_name 自动选择输出格式。

format_name:  输出格式名称

filename:    输出文件/URL名称

返回值:

成功:0;失败:非0

工作流程:

  1. 首先判断oformat是否为NULL;

  2. 如果oformat不为NULL;

直接初始化ctx结构((*ctx)->oformat, 保存filename到(*ctx)->url);

  1. 如果oformat为NULL:

format_name不为NULL:会循环查找muxer_list结构成员的name成员是否与format_name相同;

filename不为NULL:会循环查找muxer_list结构成员的extensions成员与filename的后缀是否相同;

找到后初始化ctx结构((*ctx)->oformat, 保存filename到(*ctx)->url); 如果没找到的话释放分配的ctx空间,返回错误码!

有关muxer_list的信息参考后续代码;

注意:

那么会产生一个问题:如果format_name和filename都不为NULL呢?当然如果format_name = "flv"和filename="file.flv"这是没问题的,肯定找到同一个结构;那么如果format_name = "flv"和filename="file.mp4"呢?到底以谁为准呢?

其实在avformat_alloc_output_context2函数内部有一个评分机制:format_name是100分;filename是5分;

如果匹配到filename会获得5分,继续循环匹配;如果又匹配到format_name获得100分;100分大于5分所以以format_name的类型为准;

也就是以format_name类型优先,mime_type次之(avformat_alloc_output_context2不考虑),filename最后。

附件

muxer_list结构

复制代码
static const AVOutputFormat * const muxer_list[] = {
    &ff_a64_muxer,
    &ff_ac3_muxer,
    &ff_adts_muxer,
    &ff_adx_muxer,
    &ff_aiff_muxer,
    &ff_alp_muxer,
    &ff_amr_muxer,
    &ff_amv_muxer,
    &ff_apm_muxer,
    &ff_apng_muxer,
    &ff_aptx_muxer,
    &ff_aptx_hd_muxer,
    &ff_argo_asf_muxer,
    &ff_argo_cvg_muxer,
    &ff_asf_muxer,
    &ff_ass_muxer,
    &ff_ast_muxer,
    &ff_asf_stream_muxer,
    &ff_au_muxer,
    &ff_avi_muxer,
    &ff_avif_muxer,
    &ff_avm2_muxer,
    &ff_avs2_muxer,
    &ff_avs3_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_dfpwm_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_kvag_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_obu_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_vidc_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_smjpeg_muxer,
    &ff_smoothstreaming_muxer,
    &ff_sox_muxer,
    &ff_spx_muxer,
    &ff_spdif_muxer,
    &ff_srt_muxer,
    &ff_streamhash_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_ttml_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_wsaud_muxer,
    &ff_wtv_muxer,
    &ff_wv_muxer,
    &ff_yuv4mpegpipe_muxer,
    NULL };

muxer_list的成员结构(&ff_flv_muxer为例)

复制代码
const AVOutputFormat ff_flv_muxer = {
    .name           = "flv",//输出格式类型,avformat_alloc_output_context2的第三个参数(format_name)会与该字段匹配
    .long_name      = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),
    .mime_type      = "video/x-flv",
    .extensions     = "flv",//输出文件的后缀,avformat_alloc_output_context2的第四个参数(filename)会与该字段匹配
    .priv_data_size = sizeof(FLVContext),
    .audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_ADPCM_SWF,
    .video_codec    = AV_CODEC_ID_FLV1,
    .init           = flv_init,
    .write_header   = flv_write_header,
    .write_packet   = flv_write_packet,
    .write_trailer  = flv_write_trailer,
    .deinit         = flv_deinit,
    .check_bitstream= flv_check_bitstream,
    .codec_tag      = (const AVCodecTag* const []) {
                          flv_video_codec_ids, flv_audio_codec_ids, 0
                      },
    .flags          = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |
                      AVFMT_TS_NONSTRICT,
    .priv_class     = &flv_muxer_class,
};

mime_type

MIME类型:是一种标准化的互联网媒体类型,用于标识在互联网上传输的数据的格式。每种文件都有一个唯一的 MIME 类型,它描述了文件的内容和格式。MIME 类型通常由两个部分组成:主类型和子类型,中间由斜杠分隔。avformat_alloc_output_context2函数不作考虑!

常见的 MIME 类型包括:

文本文件:text/plain

HTML 文件:text/html

图片文件:image/jpeg、image/png

音频文件:audio/mpeg

视频文件:video/mp4

应用程序文件:application/pdf、application/json