首页 > 其他分享 >Filter FilterChain FilterGraph

Filter FilterChain FilterGraph

时间:2023-03-17 11:46:59浏览次数:37  
标签:filter buffer graph avfilter ctx ret Filter FilterGraph FilterChain

基础

  1. filter: 数据处理器
  2. filter_chain: 链表链接链接所有的filter
  3. filter_graph:数据处理管理器

初始化过滤器

创建graph

    //avfilter_register_all();  // 4.0后被删除,同avdevice_regeister_all
    AVFilterGraph *filter_graph = avfilter_graph_alloc();
    if (!filter_graph) {
        printf("failed to create filter graph\n");
        return -1;
    }

创建chain

编码创建

创建输入buffer

    char args[512];
    memset(args, 0, 512);
    sprintf(args,
            "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
            in_width,
            in_height,
            AV_PIX_FMT_YUV420P,
            1,
            25,
            1,
            1);
    AVFilter *buffser_src =
        avfilter_get_by_name("buffer");  // AVFilterGraph的输入源
    AVFilterContext *buffer_src_ctx;
    ret = avfilter_graph_create_filter(
        &buffer_src_ctx, buffser_src, "in", args, NULL, filter_graph);
    if (ret < 0) {
        printf("failed to create filter buffersrc\n");
        return -1;
    }

输出buffersink

    // sink filter
    AVBufferSinkParams *buffer_sink_paras;
    AVFilterContext    *buffer_sink_ctx;
    AVFilter           *buffer_sink = avfilter_get_by_name("buffersink");
    enum AVPixelFormat  pix_fmts[]  = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
    buffer_sink_paras               = av_buffersink_params_alloc();
    buffer_sink_paras->pixel_fmts   = pix_fmts;
    ret = avfilter_graph_create_filter(&buffer_sink_ctx,
                                       buffer_sink,
                                       "out",
                                       NULL,
                                       buffer_sink_paras,
                                       filter_graph);
    if (ret < 0) {
        printf("failed to create split filter\n");
        return -1;
    }

个人需要使用的filter

    // split fitler
    AVFilter        *split_filter = avfilter_get_by_name("split");
    AVFilterContext *split_filter_ctx;
    ret = avfilter_graph_create_filter(&split_filter_ctx,
                                       split_filter,
                                       "split",
                                       "outputs=2",
                                       NULL,
                                       filter_graph);
    if (ret < 0) {
        printf("failed to create split filter\n");
        return -1;
    }

    // crop filter
    AVFilter        *crop_filter = avfilter_get_by_name("crop");
    AVFilterContext *crop_filter_ctx;
    ret = avfilter_graph_create_filter(&crop_filter_ctx,
                                       crop_filter,
                                       "crop",
                                       "out_w=iw:out_h=ih/2:x=0:y=0",
                                       NULL,
                                       filter_graph);
    if (ret < 0) {
        printf("failed to create crop filter\n");
        return -1;
    }

    // vflip filter
    AVFilter        *vflip_filter = avfilter_get_by_name("vflip");
    AVFilterContext *vflip_filter_ctx;
    ret = avfilter_graph_create_filter(
        &vflip_filter_ctx, vflip_filter, "vflip", NULL, NULL, filter_graph);
    if (ret < 0) {
        printf("failed to create vflip filter\n");
        return -1;
    }

    // overlap filter
    AVFilter        *overlay_filter = avfilter_get_by_name("overlay");
    AVFilterContext *overlay_filter_ctx;
    ret = avfilter_graph_create_filter(&overlay_filter_ctx,
                                       overlay_filter,
                                       "overlay",
                                       "y=0:H/2",
                                       NULL,
                                       filter_graph);
    if (ret < 0) {
        printf("failed to create overlay filter\n");
        return -1;
    }

link需要的filters

    // src filter to split filter
    ret = avfilter_link(buffer_src_ctx, 0, split_filter_ctx, 0);
    if (ret != 0) {
        printf("failed to link src filter and split filter\n");
        return -1;
    }
    // split filter's first pad to overlay fiilter's main pad
    ret = avfilter_link(split_filter_ctx, 0, overlay_filter_ctx, 0);
    if (ret != 0) {
        printf("failed to link split filter's first pad and overlay filter\n");
        return -1;
    }
    // split fitler's second pad to crop filter
    ret = avfilter_link(split_filter_ctx, 1, crop_filter_ctx, 0);
    if (ret != 0) {
        printf("failed to link split filter's second pad and crop filter\n");
        return -1;
    }
    // crop filter to vflip filter
    ret = avfilter_link(crop_filter_ctx, 0, vflip_filter_ctx, 0);
    if (ret != 0) {
        printf("failed to link crop filter and vflip filter\n");
        return -1;
    }
    // vflip filter to overlay filtes'second pad
    ret = avfilter_link(vflip_filter_ctx, 0, overlay_filter_ctx, 1);
    if (ret != 0) {
        printf("failed to link vflip filter and overlay's second filter\n");
        return -1;
    }
    // overlay filter to sink filter
    ret = avfilter_link(overlay_filter_ctx, 0, buffer_sink_ctx, 0);
    if (ret != 0) {
        printf("failed to link overlay filter and sink filter\n");
        return -1;
    }

初始化graph

    // check filter graph
    ret = avfilter_graph_config(filter_graph, NULL);
    if (ret < 0) {
        printf("failed in filter graph\n");
        return -1;
    }

命令创建

初始化命令行

    char           filter_args[1024] = { 0 };
    snprintf(
        filter_args,
        sizeof(filter_args),
        "buffer=video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d[v0];"  // Parsed_buffer_0
        "[v0]split[main][tmp];"               // Parsed_split_1
        "[tmp]crop=iw:ih/2:0:0,vflip[flip];"  // Parsed_crop_2 Parsed_vflip_3
        "[main][flip]overlay=0:H/2[result];"  // Parsed_overlay_4
        "[result]buffersink",                 // Parsed_buffersink_5
        width,
        height,
        format,
        1,
        25,
        1,
        1);

利用命令行初始化graph

    AVFilterInOut *inputs            = NULL;
    AVFilterInOut *outputs           = NULL;
    int ret = avfilter_graph_parse2(filter_graph, filter_args, &inputs, &outputs);
    if (ret < 0) {
        printf("cannot parse graph\n");
        return ret;
    }
    ret = avfilter_graph_config(filter_graph, NULL);
    if (ret < 0) {
        printf("cannot config graph\n");
        return ret;
    }

获取输入buffer和输出buffersink

    mainsrc_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffer_0");
    if (!mainsrc_ctx) {
        printf("avfilter_graph_get_filter Parsed_buffer_0 failed\n");
        return -1;
    }
    resultsink_ctx =
        avfilter_graph_get_filter(filter_graph, "Parsed_buffersink_5");
    if (!resultsink_ctx) {
        printf("avfilter_graph_get_filter Parsed_buffer_5 failed\n");
        return -1;
    }

处理数据

向buffer中添加数据

        if (av_buffersrc_add_frame(mainsrc_ctx, frame_in) < 0) {
            printf("error while add frame\n");
            break;
        }

从buffersink中获取数据

        ret = av_buffersink_get_frame(resultsink_ctx, frame_out);
        if (ret < 0)
            break;

其他业务

        // output Y U V
        if (frame_out->format == AV_PIX_FMT_YUV420P) {
            for (int i = 0; i < frame_out->height; ++i)
                fwrite(frame_out->data[0] + frame_out->linesize[0] * i,
                       1,
                       frame_out->width,
                       outFile);
            for (int i = 0; i < frame_out->height / 2; ++i)
                fwrite(frame_out->data[1] + frame_out->linesize[1] * i,
                       1,
                       frame_out->width / 2,
                       outFile);
            for (int i = 0; i < frame_out->height / 2; ++i)
                fwrite(frame_out->data[2] + frame_out->linesize[2] * i,
                       1,
                       frame_out->width / 2,
                       outFile);
        }

标签:filter,buffer,graph,avfilter,ctx,ret,Filter,FilterGraph,FilterChain
From: https://www.cnblogs.com/faithlocus/p/17226106.html

相关文章

  • PebbleTemplates 自定义tag&filter&function 开发简单说明
    PebbleTemplates的扩展能力还是很强大的,开发起来也比较方便,以下是一个简单的说明,更加复杂的推荐查看官方源码学习filter开发参考代码此filter直接返回rongfenglian......
  • django-filter用法
    一.环境准备pipinstallDjango==2.2-ihttps://pypi.douban.com/simplepipinstalldjangorestframework==3.10-ihttps://pypi.douban.com/simplepipinstalldjan......
  • .NET Core 中的筛选器 Filter
    官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/controllers/filters?view=aspnetcore-5.0通过使用ASP.NETCore中的筛选器,可在请求处理管道中的特定阶段之......
  • java8 Optional使用 stream filter多级过滤
    java8Optional使用streamfilter多级过滤packagecom.example.core.mydemo.java8;publicclassMyModel{privateStringcouponCode;privateIntegeror......
  • Filter+Listener
    11.Filter(重点)Filter:过滤器,用来过滤网站的数据;处理中文乱码登录验证….Filter开发步骤:导包编写过滤器导包不要错;<?xmlversion="1.0"encoding="UTF-8"......
  • 【Filter pruning】Learning Efficient Convolutional Networks through Network Slim
    原始题目LearningEfficientConvolutionalNetworksthroughNetworkSlimming中文名称通过网络瘦身(Slimming)学习高效卷积网络发表时间2017年8月22日......
  • Day08-Filter&Listener笔记
    0.Servlet:属于一个接口,动态资源,如果浏览器想访问服务器中的动态资源,那么需要自定义类直接或者间接实现Servlet接口1)自定义类实现Servlet接口===自定义类中要实现Se......
  • filter过滤器、事务管理、listener监听器相关知识
    资料来源于:B站尚硅谷JavaWeb教程(全新技术栈,全程实战),本人才疏学浅,记录笔记以供日后回顾由于是多个视频内容混合在一起,因此只放了第一个链接视频链接知识点1.......
  • jquery遍历元素children、find、parent、parents、parentsUntil、next、prev、sibling
    ​​​​全栈工程师开发手册(作者:栾鹏)​​jquery系列教程2-DOM操作全解​​jquery遍历元素jquery元素的函数包括children、find、parent、parents、parentsUntil、next......
  • 一文快速回顾 Servlet、Filter、Listener
    什么是Servlet?前置知识:Web服务器:可以指硬件上的,也可以指软件上的。从硬件的角度来说,Web服务器指的就是一台存储了网络服务软件的计算机;从软件的角度来说,Web服务器指......