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;
	}
avformat_alloc_output_context2是FFmpeg中一个函数,用于分配一个输出格式的AVFormatContext结构体,并将其与指定的输出格式相关联。该函数的原型如下: ```c int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat, const char *format_name, const char *filename); ``` 其中,参数解释如下: - avctx:指向指针的指针,该指针将存储分配的AVFormatContext结构体的地址。 - oformat:指向AVOutputFormat结构体的指针,该结构体指定了要使用的输出格式。如果为NULL,则由FFmpeg自动选择输出格式。 - format_name:输出格式名称。如果oformat为NULL,则可以通过该参数指定要使用的输出格式的名称。如果不需要,则可以将其设置为NULL。 - filename:输出文件名。如果为NULL,则可以在稍后使用avio_open2函数打开输出文件。 该函数返回0表示成功,否则表示失败。 以下是一个示例代码,演示如何使用avformat_alloc_output_context2函数创建一个AVFormatContext结构体,以及如何将其与输出文件相关联: ```c #include <libavformat/avformat.h> int main(int argc, char *argv[]) { AVFormatContext *out_ctx = NULL; AVOutputFormat *out_fmt = NULL; const char *out_filename = "output.mp4"; int ret; // 初始化FFmpegav_register_all(); // 查找输出格式 out_fmt = av_guess_format("mp4", NULL, NULL); if (!out_fmt) { fprintf(stderr, "Could not find output format.\n"); return -1; } // 分配AVFormatContext结构体 ret = avformat_alloc_output_context2(&out_ctx, out_fmt, NULL, out_filename); if (ret < 0) { fprintf(stderr, "Could not allocate output context.\n"); return -1; } // 打开输出文件 ret = avio_open2(&out_ctx->pb, out_filename, AVIO_FLAG_WRITE, NULL, NULL); if (ret < 0) { fprintf(stderr, "Could not open output file: %s.\n", av_err2str(ret)); return -1; } // 设置AVFormatContext的输出格式 out_ctx->oformat = out_fmt; // 输出文件头 ret = avformat_write_header(out_ctx, NULL); if (ret < 0) { fprintf(stderr, "Error writing header: %s.\n", av_err2str(ret)); return -1; } // TODO: 写入媒体数据 // 输出文件尾 ret = av_write_trailer(out_ctx); if (ret < 0) { fprintf(stderr, "Error writing trailer: %s.\n", av_err2str(ret)); return -1; } // 释放AVFormatContext结构体 avformat_free_context(out_ctx); return 0; } ``` 在上面的示例代码中,首先通过av_guess_format函数查找要使用的输出格式(这里是mp4格式)。然后,使用avformat_alloc_output_context2函数分配一个AVFormatContext结构体,并将其与输出文件相关联。接着,使用avio_open2函数打开输出文件,并将其与AVFormatContextAVIOContext相关联。然后,设置AVFormatContext的输出格式,并调用avformat_write_header函数输出文件头。在此之后,可以向文件中写入媒体数据。最后,调用av_write_trailer函数输出文件尾,并释放AVFormatContext结构体。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值