[英]Huge memory leak when filtering video with libavfilter
我有一個相對簡單的FFMPEG C程序,將視頻幀饋送到該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;
繞過過濾器av->frame_out=av->frame_in;
無需將框架推入框架(顯然也不會從框架中拉出),就不會泄漏並且內存使用情況穩定。
現在,我對C還是很陌生,所以要保持柔和,但似乎我應該以某種方式清除buffersrc_ctx,但不知道如何清除。 我查看過官方文檔,但找不到任何東西。
有人可以建議嗎?
發布5分鍾后,看起來我要做的就是在處理完每個參考幀后取消引用幀。
av_frame_unref(av->frame_in);
av_frame_unref(av->frame_out);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.