Dynamic change avfilter configuration?(谷歌搜过了,没看到解决方案,^_^)
最近通过libav做了视频抠像的功能,前端反应不能调整参数,然后巴拉巴拉。。。
一开始,我想得比较简单,不就是重启一下filter吗?每次filter的时候重新alloc一次,然后得到反馈:程序崩溃(si被你忒)
跟着baidu,google。。。搜一天多了,没得到合适的代码示例或提示,后来在另外一个讲配置libav内部结构体的文章看到av_opt_set,然后灵光乍现,filter内部不就是封装的结构体吗?然后尝试写了点调试代码。
最终确定通过(AVFilterGraph *)videoFilterGraph可以定位到相应的(AVFilterContext *)ctx;我采用最挫的方法,直接比较ctx->filter->name,定位到相应的AVFilterContext,然后直接对ctx->priv进行操作,打完收工。
static void modify_filter_opts(Video_Object *video_obj, unsigned int color, double similarity, double blend)
{
AVFilterGraph *videoFilterGraph = video_obj->filter_graph;
if (!videoFilterGraph)
{
return;
}
int nb_filters = videoFilterGraph->nb_filters;
char options[1024];
for (size_t i = 0; i < nb_filters; i++)
{
AVFilterContext *ctx1 = videoFilterGraph->filters[i];
//printf("ctx2=%s\n", ctx1->name);
if (strcmp(ctx1->filter->name, "colorkey")==0 || strcmp(ctx1->filter->name, "chromakey")==0)
{
const AVOption *opt0 = av_opt_find(ctx1->priv, "color", NULL, 0, 0);
if (opt0)
{
memset(options, 0, 1024);
//color = AARRGGB
sprintf(options, "0x%06X", color & 0x00FFFFFF);
av_opt_set(ctx1->priv, "color", options, 0); //color=RRGGBB(AA)
}
const AVOption *opt1 = av_opt_find(ctx1->priv, "similarity", NULL, 0, 0);
if (opt1)
{
memset(options, 0, 1024);
sprintf(options, "%.6f", similarity);
av_opt_set(ctx1->priv, "similarity", options, 0);
}
const AVOption *opt2 = av_opt_find(ctx1->priv, "blend", NULL, 0, 0);
if (opt2)
{
memset(options, 0, 1024);
sprintf(options, "%.6f", blend);
av_opt_set(ctx1->priv, "blend", options, 0);
}
//unsigned char *out = NULL;
//av_opt_get(ctx1->priv, "color", 0, &out);
//av_opt_get(ctx1->priv, "similarity", 0, &out); //0.000000
//av_opt_get(ctx1->priv, "blend", 0, &out); //0.000000
//printf("out=%s\n", (char *)out);
break;
}
}
}
是以记录下来,以供参考。