zoukankan      html  css  js  c++  java
  • ffmpeg水印处理

    //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 ", 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 ", (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 ", (ret));
    break;
    }

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

    if ((ret = av_buffersrc_add_frame(pBufferSrcContext, pSrcFrame)) < 0)
    {
    sprintf(szErrMsg, "Cannot add frame from buffersrc, error:%d ", (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 ", (ret));
    break;
    }
    } while (0);

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

  • 相关阅读:
    无向连通图求割边+缩点+LCA
    poj 1417(并查集+简单dp)
    java系统时间的调用和格式转换
    Delphi程序的主题(Theme)设置
    分块读取Blob字段数据(Oracle)
    Delphi xe5 编译报environment.proj错误的解决
    DataSnap服务器从xe2升级到xe5报错的处理
    分块读取Blob字段数据(MSSQL)
    Delphi XE5 for Android (十一)
    Delphi XE5 for Android (十)
  • 原文地址:https://www.cnblogs.com/suhq/p/13284359.html
Copyright © 2011-2022 走看看