gpt4 book ai didi

c - 使用 libavfilter 过滤视频时出现巨大的内存泄漏

转载 作者:行者123 更新时间:2023-11-30 14:56:58 24 4
gpt4 key购买 nike

我有一个相对简单的 FFMPEG C 程序,视频帧被馈送到该程序,通过过滤器图进行处理并发送到帧渲染器。

以下是一些代码片段:

/* Filter graph here */
char args[512];
enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_RGB32 };
AVFilterGraph *filter_graph;
avfilter_register_all();
AVFilter *buffersrc = avfilter_get_by_name("buffer");
AVFilter *buffersink = avfilter_get_by_name("ffbuffersink");
AVBufferSinkParams *buffersink_params;
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
filter_graph = avfilter_graph_alloc();

snprintf(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
av->codec_ctx->width, av->codec_ctx->height, av->codec_ctx->pix_fmt,
av->codec_ctx->time_base.num, av->codec_ctx->time_base.den,
av->codec_ctx->sample_aspect_ratio.num, av->codec_ctx->sample_aspect_ratio.den);

if(avfilter_graph_create_filter(&av->buffersrc_ctx, buffersrc, "in",args, NULL, filter_graph) < 0)
{
fprintf(stderr, "Cannot create buffer source\n");
return(0);
}

/* buffer video sink: to terminate the filter chain. */
buffersink_params = av_buffersink_params_alloc();
buffersink_params->pixel_fmts = pix_fmts;

if(avfilter_graph_create_filter(&av->buffersink_ctx, buffersink, "out",NULL, buffersink_params, filter_graph) < 0)
{
printf("Cannot create buffer sink\n");
return(HACKTV_ERROR);
}

/* Endpoints for the filter graph. */
outputs->name = av_strdup("in");
outputs->filter_ctx = av->buffersrc_ctx;
outputs->pad_idx = 0;
outputs->next = NULL;

inputs->name = av_strdup("out");
inputs->filter_ctx = av->buffersink_ctx;
inputs->pad_idx = 0;
inputs->next = NULL;

const char *filter_descr = "vflip";

if (avfilter_graph_parse_ptr(filter_graph, filter_descr, &inputs, &outputs, NULL) < 0)
{
printf("Cannot parse filter graph\n");
return(0);
}

if (avfilter_graph_config(filter_graph, NULL) < 0)
{
printf("Cannot configure filter graph\n");
return(0);
}

av_free(buffersink_params);
avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs);

上面的代码被其他地方调用:

av->frame_in->pts = av_frame_get_best_effort_timestamp(av->frame_in);

/* push the decoded frame into the filtergraph*/
if (av_buffersrc_add_frame(av->buffersrc_ctx, av->frame_in) < 0)
{
printf( "Error while feeding the filtdergraph\n");
break;
}

/* pull filtered pictures from the filtergraph */
if(av_buffersink_get_frame(av->buffersink_ctx, av->frame_out) < 0)
{
printf( "Error while sourcing the filtergraph\n");
break;
}

/* do stuff with frame */

现在,代码工作得非常好,视频按照我预期的方式显示(出于测试目的垂直翻转)。

我遇到的最大问题是存在大量内存泄漏。高分辨率视频将在几秒钟内消耗 2Gb 空间并使程序崩溃。我追踪到了这段代码的泄漏:

/* push the decoded frame into the filtergraph*/
if (av_buffersrc_add_frame(av->buffersrc_ctx, av->frame_in) < 0)

如果我通过执行 av->frame_out=av->frame_in; 绕过过滤器而不将框架插入其中(显然没有从中拉出),则不会发生泄漏,并且内存使用量也会减少稳定。

现在,我对 C 很陌生,所以要温柔,但似乎我应该以某种方式清除 buffersrc_ctx 但不知道如何。我查看了官方文档但没有找到任何内容。

有人可以建议吗?

最佳答案

发布后 5 分钟,看起来我所要做的就是在处理每个帧后取消引用帧。

        av_frame_unref(av->frame_in);
av_frame_unref(av->frame_out);

关于c - 使用 libavfilter 过滤视频时出现巨大的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44247448/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com