ffmpeg avformat_alloc_output_context2的使用说明

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;
	}

你可能感兴趣的:(ffmpeg,音视频)