代码改变世界

ffmpeg水印处理

2020-07-11 17:14  su_hq  阅读(812)  评论(0编辑  收藏  举报

//avfilter_register_all():注册所有AVFilter。
//avfilter_graph_alloc():为FilterGraph分配内存。
//avfilter_graph_create_filter():创建并向FilterGraph中添加一个Filter。
//avfilter_graph_parse_ptr():将一串通过字符串描述的Graph添加到FilterGraph中。
//avfilter_graph_config():检查FilterGraph的配置。
//av_buffersrc_add_frame():向FilterGraph中加入一个AVFrame。
//av_buffersink_get_frame():从FilterGraph中取出一个AVFrame。
void ffmpeg_DrawWaterToFrame(AVFrame* pSrcFrame, AVFrame* pDestFrame,char *pFilterContent)
{
AVFilterGraph* pFilterGraph = avfilter_graph_alloc();
char szErrMsg[128] = { 0 };
char szArgs[512] = { 0 };

AVFilter* pBufferSrc = (AVFilter*)avfilter_get_by_name("buffer");
AVFilter* pBufferSink = (AVFilter*)avfilter_get_by_name("buffersink");
AVFilterInOut* pFilterOut = avfilter_inout_alloc();
AVFilterInOut* pFilterIn = avfilter_inout_alloc();
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE };
AVBufferSinkParams* pBufferSinkParams;

//最后的几个参数没有使用真实的视频格式参数
snprintf(szArgs, sizeof(szArgs), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
pSrcFrame->width, pSrcFrame->height, pSrcFrame->format, 1, 1, 1, 1);

int ret = 0;
AVFilterContext* pBufferSinkContext = NULL;
AVFilterContext* pBufferSrcContext = NULL;
if ((ret = avfilter_graph_create_filter(&pBufferSrcContext, pBufferSrc, "in", szArgs, NULL, pFilterGraph)) < 0)
{
sprintf(szErrMsg, "Cannot graph create filter, error:%d\n", ret);
return;
}
pBufferSinkParams = av_buffersink_params_alloc();
pBufferSinkParams->pixel_fmts = pix_fmts;
if ((ret = avfilter_graph_create_filter(&pBufferSinkContext, pBufferSink, "out", NULL, pBufferSinkParams, pFilterGraph)) < 0)
{
sprintf(szErrMsg, "Cannot graph create filter, error:%d\n", (ret));
return;
}

pFilterOut->name = av_strdup("in");
pFilterOut->filter_ctx = pBufferSrcContext;
pFilterOut->pad_idx = 0;
pFilterOut->next = NULL;

pFilterIn->name = av_strdup("out");
pFilterIn->filter_ctx = pBufferSinkContext;
pFilterIn->pad_idx = 0;
pFilterIn->next = NULL;

do
{
if ((ret = avfilter_graph_parse_ptr(pFilterGraph, pFilterContent, &pFilterIn, &pFilterOut, NULL)) < 0)
{
sprintf(szErrMsg, "Cannot graph parse ptr, error:%d\n", (ret));
break;
}

if ((ret = avfilter_graph_config(pFilterGraph, NULL)) < 0)
{
//sprintf(szErrMsg, "Cannot graph config filter, error:%s\n", av_err2str(ret));
break;
}

if ((ret = av_buffersrc_add_frame(pBufferSrcContext, pSrcFrame)) < 0)
{
sprintf(szErrMsg, "Cannot add frame from buffersrc, error:%d\n", (ret));
break;
}
//pDestFrame帧的长宽必须指定
//图像格式转换之后,pSrcFrame中的data数据被置为NULL,pSrcFrame结构不可用
if ((ret = av_buffersink_get_frame(pBufferSinkContext, pDestFrame)) < 0)
{
sprintf(szErrMsg, "Cannot get frame frome buffersink, error:%d\n", (ret));
break;
}
} while (0);

avfilter_inout_free(&pFilterIn);
avfilter_inout_free(&pFilterOut);
av_free(pBufferSinkParams);
avfilter_graph_free(&pFilterGraph);
}