avformat_alloc_output_context2函数用于设置输出context,其函数原型如下:
/**
* Allocate an AVFormatContext for an output format.
* avformat_free_context() can be used to free the context and
* everything allocated by the framework within it.
*
* @param *ctx is set to the created format context, or to NULL in
* case of failure
* @param oformat format to use for allocating the context, if NULL
* format_name and filename are used instead
* @param format_name the name of output format to use for allocating the
* context, if NULL filename is used instead
* @param filename the name of the filename to use for allocating the
* context, may be NULL
* @return >= 0 in case of success, a negative AVERROR code in case of
* failure
*/
int avformat_alloc_output_context2(AVFormatContext **ctx, const AVOutputFormat *oformat,
const char *format_name, const char *filename);
总共4个参数,其中第一个参数是输出,其他都是输入。
第二个参数和第三个参数都是封装格式,第二个是结构体类型,第三个是字符串类型,比如format_name为mp4时,其对应的AVOutputFormat结构(第二个参数)详情如下:
const AVOutputFormat ff_mp4_muxer = {
.name = "mp4",
.long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
.mime_type = "video/mp4",
.extensions = "mp4",
.priv_data_size = sizeof(MOVMuxContext),
.audio_codec = AV_CODEC_ID_AAC,
.video_codec = CONFIG_LIBX264_ENCODER ?
AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
.init = mov_init,
.write_header = mov_write_header,
.write_packet = mov_write_packet,
.write_trailer = mov_write_trailer,
.deinit = mov_free,
.flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
.codec_tag = mp4_codec_tags_list,
.check_bitstream = mov_check_bitstream,
.priv_class = &mp4_muxer_class,
};
该变量定义在文件libavformat/movenc.c里面
flv的AVOutputFormat如下:
const AVOutputFormat ff_flv_muxer = {
.name = "flv",
.long_name = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),
.mime_type = "video/x-flv",
.extensions = "flv",
.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,
.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,
};
像ff_mp4_muxer和ff_flv_muxer这种变量,是ffmpeg内部的变量,外面没法直接引用,所以在ffmpeg里面,设置封装格式时,不会用到该参数;而实际上,ffmpeg给出的工具ffmpeg.exe的代码里面,该参数就是设置为NULL。
这时,可以通过下面方式设置封装格式
const char* filename = "out.bak";
ret = avformat_alloc_output_context2(&avFormCtx_Out, NULL, "mp4", filename);
if (ret < 0)
{
printf("Init avformat object is faild! \n");
return 0;
}
注意,文件名我设置的是out.bak,其实正常是设置out.mp4。设置为out.bak是有时候程序写文件的时候,文件后缀名暂时不方便定义为封装格式的情况。
第三个参数也可以如设置为NULL,此时,第四个参数文件名的后缀就需要带封装格式了,比如:
const char* filename = "out.mp4";
ret = avformat_alloc_output_context2(&avFormCtx_Out, NULL, NULL, filename);
if (ret < 0)
{
printf("Init avformat object is faild! \n");
return 0;
}