AvFilter实现转码音频

来源:互联网 发布:软件资质认证 编辑:程序博客网 时间:2024/06/03 11:27

MP3-->AAC的时候,只能设置


static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,AVCodecContext *enc_ctx, const char *filter_spec){char args[512];int ret = 0;AVFilter *buffersrc = NULL;AVFilter *buffersink = NULL;AVFilterContext *buffersrc_ctx = NULL;AVFilterContext *buffersink_ctx = NULL;AVFilterInOut *outputs = avfilter_inout_alloc();AVFilterInOut *inputs = avfilter_inout_alloc();AVFilterGraph *filter_graph = avfilter_graph_alloc();if (!outputs || !inputs || !filter_graph) {ret = AVERROR(ENOMEM);goto end;}if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {buffersrc = avfilter_get_by_name("buffer");buffersink = avfilter_get_by_name("buffersink");if (!buffersrc || !buffersink) {av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");ret = AVERROR_UNKNOWN;goto end;}snprintf(args, sizeof(args),"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,dec_ctx->time_base.num, dec_ctx->time_base.den,dec_ctx->sample_aspect_ratio.num,dec_ctx->sample_aspect_ratio.den);ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", args, NULL, filter_graph);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");goto end;}ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out", NULL, NULL, filter_graph);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");goto end;}//输出 设置 pix_fmtret = av_opt_set_bin(buffersink_ctx, "pix_fmts", (uint8_t*)&enc_ctx->pix_fmt, sizeof(enc_ctx->pix_fmt), AV_OPT_SEARCH_CHILDREN);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");goto end;}//输出设置宽高}else if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO){buffersrc = avfilter_get_by_name("abuffer");buffersink = avfilter_get_by_name("abuffersink");if (!buffersrc || !buffersink) {av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");ret = AVERROR_UNKNOWN;goto end;}if (!dec_ctx->channel_layout)dec_ctx->channel_layout = av_get_default_channel_layout(dec_ctx->channels);snprintf(args, sizeof(args),"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,dec_ctx->time_base.num, dec_ctx->time_base.den, dec_ctx->sample_rate,av_get_sample_fmt_name(dec_ctx->sample_fmt),dec_ctx->channel_layout);ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",args, NULL, filter_graph);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");goto end;}ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",NULL, NULL, filter_graph);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");goto end;}<span style="white-space:pre"></span><span style="color:#ff0000;">//设置输出filter的 采样率,但是如果是MP3-->AAC 转码的时候,需要设置 frame_size,但是这种方式不能设置,需要在下面红色部分设置</span>ret = av_opt_set_bin(buffersink_ctx, "sample_fmts", (uint8_t*)&enc_ctx->sample_fmt, sizeof(enc_ctx->sample_fmt),AV_OPT_SEARCH_CHILDREN);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");goto end;}ret = av_opt_set_bin(buffersink_ctx, "channel_layouts", (uint8_t*)&enc_ctx->channel_layout, sizeof(enc_ctx->channel_layout), AV_OPT_SEARCH_CHILDREN);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");goto end;}ret = av_opt_set_bin(buffersink_ctx, "sample_rates", (uint8_t*)&enc_ctx->sample_rate, sizeof(enc_ctx->sample_rate), AV_OPT_SEARCH_CHILDREN);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");goto end;}ret = av_opt_set_bin(buffersink_ctx, "sample_rates", (uint8_t*)&enc_ctx->sample_rate, sizeof(enc_ctx->sample_rate), AV_OPT_SEARCH_CHILDREN);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");goto end;}<span style="white-space:pre"></span>}else{ret = AVERROR_UNKNOWN;goto end;}/* Endpoints for the filter graph. */outputs->name = av_strdup("in");outputs->filter_ctx = buffersrc_ctx;outputs->pad_idx = 0;outputs->next = NULL;inputs->name = av_strdup("out");inputs->filter_ctx = buffersink_ctx;inputs->pad_idx = 0;inputs->next = NULL;if (!outputs->name || !inputs->name) {ret = AVERROR(ENOMEM);goto end;}<span style="white-space:pre"></span><span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif;">//  avfilter_graph_parse_ptr 这个函数相当于 avfilter_link ,只能在这设置 frame_size</span>if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_spec, &inputs, &outputs, NULL)) < 0)goto end;<span style="color:#ff0000;">//如果不设置,会出错 ,more buffer into encoder 1152-->1024if (dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO)     {//AVFilterLink *inlink = buffersink_ctx->inputs[0];//inlink->min_samples = inlink->max_samples = inlink->partial_buf_size = enc_ctx->frame_size;av_buffersink_set_frame_size(buffersink_ctx, enc_ctx->frame_size);}</span>if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)goto end;/* Fill FilteringContext */fctx->buffersrc_ctx = buffersrc_ctx;fctx->buffersink_ctx = buffersink_ctx;fctx->filter_graph = filter_graph;end:avfilter_inout_free(&inputs);avfilter_inout_free(&outputs);return ret;}


0 0
原创粉丝点击