函数原型:
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
工作流程:
-
首先判断oformat是否为NULL;
-
如果oformat不为NULL;
直接初始化ctx结构((*ctx)->oformat, 保存filename到(*ctx)->url);
- 如果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