在ffmpeg中,进行反交错需要用到avfilter,即图像过滤器,ffmpeg中有很多过滤器,很强大,反交错的过滤器是yadif.

基本的过滤器使用流程是:

解码后的画面--->buffer过滤器---->其他过滤器---->buffersink过滤器--->处理完的画面

所有的过滤器形成了过滤器链,一定要的两个过滤器是buffer过滤器和buffersink过滤器,前者的作用是将解码后的画面加载到过滤器链中,后者的作用是将处理好的画面从过滤器链中读取出来.那么进行反交错的过滤器链应该是这样的: buffer过滤器--->yadif过滤器--->buffersink过滤器

过滤器相关的结构体:

  AVFilterGraph: 管理所有的过滤器图像

    AVFilterContext: 过滤器上下文

    AVFilter: 过滤器

下面来看如何创建过滤器链:

第一步,创建AVFilterGraph

AVFilterGraph *filter_graph=avfilter_graph_alloc();

第二步,获取要使用的过滤器:

AVFilter *filter_buffer=avfilter_get_by_name("buffer");

AVFilter *filter_yadif=avfilter_get_by_name("yadif");

AVFilter *filter_buffersink=avfilter_get_by_name("buffersink");

第三步,创建过滤器上下文,即AVFilterContext:

int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
                                 const char *name, const char *args, void *opaque,
                                 AVFilterGraph *graph_ctx);

参数说明:filt_ctx用来保存创建好的过滤器上下文,filt是过滤器,name是过滤器名称(在过滤器链中应该唯一),args是传给过滤器的参
数(每个过滤器不同,可以在相应的过滤器代码找到),opaque在代码中没有被使用,graph_ctx是过滤器图像管理指针.例:

AVFilterContext *filter_buffer_ctx,*filter_yadif_ctx,*filter_buffersink_ctx;

//创建buffer过滤器

snprintf(args, sizeof(args),
            "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
            dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
            dec_ctx->time_base.num, dec_ctx->time_base.den,
            dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
        avfilter_graph_create_filter(&filter_buffer_ctx, avfilter_get_by_name("buffer"), "in",
                                       args, NULL, filter_graph);

//创建yadif过滤器

avfilter_graph_create_filter(&filter_yadif_ctx, avfilter_get_by_name("yadif"), "yadif",
                                   "mode=send_frame:parity=auto:deint=interlaced", NULL, filter_graph);

//创建buffersink过滤器

enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };

avfilter_graph_create_filter(&filter_buffersink_ctx, avfilter_get_by_name("buffersink"), "out",
                                       NULL, NULL,filter_graph);

av_opt_set_int_list(filter_buffersink_ctx, "pix_fmts", pix_fmts,
                              AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);

第四步,连接过滤器

avfilter_link(filter_buffer_ctx, 0, filter_yadif_ctx, 0);

avfilter_link(filter_yadif_ctx, 0, filter_buffersink_ctx, 0);

第五步,检查所有配置是否正确:

if ((ret = avfilter_graph_config(player->filter_graph, NULL)) < 0){
            LOGE(0,"avfilter_graph_config:%d\n",ret);
            goto end;
        }

注意上面所有的函数都应该检查返回值,这里是略写,到这里如果没出错的话,过滤器链就创建好了.

如何使用过滤器链进行过滤,主要是使用两个函数:

//将解码后的frame推送给过滤器链

int av_buffersrc_add_frame_flags(AVFilterContext *buffer_src,
                                 AVFrame *frame, int flags);

//将处理完的frame拉取出来:

int av_buffersink_get_frame(AVFilterContext *ctx, AVFrame *frame);
    例如:

av_buffersrc_add_frame_flags(filter_buffer_ctx, orgin_frame, AV_BUFFERSRC_FLAG_KEEP_REF);

while(1){

ret = av_buffersink_get_frame(filter_buffersink_ctx, frame);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){
            break;
        }

display(frame);

};

反交错前的图像和反交错后的图像对比:

虽然比较模糊,但是横纹确实去掉了.

找了一下,发现ffmpeg中还有一个反交错的过滤器kerndeint,是GPL授权,使用时要配置打开GPL

传入参数thresh=0:map=0:order=1:sharp=0:twoway=0后,看来起比yadif要好一些,效果如下图:

ffmpeg还有一些deinterlace的过滤器,测试发现在过滤时间和画面质量方面,比较好的是pp/lb过滤器。

ffmeg过滤器介绍[转]的更多相关文章

  1. [干货]2017已来,最全面试总结——这些Android面试题你一定需要

        地址.http://blog.csdn.net/xhmj12/article/details/54730883 相关阅读: 吊炸天!74款APP完整源码! [干货精品,值得收藏]超全的一线互联 ...

  2. Git之(一)Git是什么[转]

    为什么使用Git 孔子曾经曰过的,名正则言顺 言顺则事成. 我们在学习一项新技术之前,弄清楚为什么要学它至关重要,至于为什么要学习Git,我用一段if-else语句告诉你原因: if(你相信我){ 我 ...

  3. [caffe]linux下安装caffe(无cuda)以及python接口

    昨天在mac上折腾了一天都没有安装成功,晚上在mac上装了一个ParallelDesktop虚拟机,然后装了linux,十分钟就安装好了,我也是醉了=.= 主要过程稍微记录一下: 1.安装BLAS s ...

  4. [Swift]基础

    [Swift]基础 一, 常用变量 var str = "Hello, playground" //变量 let str1="Hello xmj112288" ...

  5. [Ruby on Rails系列]4、专题:Rails应用的国际化[i18n]

    1. 什么是internationalization(i18n)? 国际化,英文简称i18n,按照维基百科的定义:国际化是指在设计软件,将软件与特定语言及地区脱钩的过程.当软件被移植到不同的语言及地区 ...

  6. [译]一个灵活的 Trello 敏捷工作流

    [译]一个灵活的 Trello 敏捷工作流 翻译自 An Agile Trello Workflow That Keeps Tasks Flexible Getting things done 可不只 ...

  7. iOS10收集IDFA,植入第三方广告[终结]--ADMob

    [PS: 前段时间,公司做ASO推广,需要在应用中收集IDFA值,跟广告平台做交互!于是有了这个需求--] 1.首先,考虑了一下情况(自己懒 -_-#),就直接在首页上写了一个Banner,循环加载广 ...

  8. Wireshark wireshake数据包分割及捕包过滤器介绍

    wireshake数据包分割及捕包过滤器介绍 by:授客 QQ:1033553122 wireshake自带工具editcap分割数据包 操作: 进入到目录,然后 editcap.exe -c < ...

  9. Java基础 之软引用、弱引用、虚引用 ·[转载]

    Java基础 之软引用.弱引用.虚引用 ·[转载] 2011-11-24 14:43:41 Java基础 之软引用.弱引用.虚引用 浏览(509)|评论(1)   交流分类:Java|笔记分类: Ja ...

随机推荐

  1. 【关于java多线程和socket通信的一些记录】---高并发/高负载/高可用/重入锁

    多线程:提高cpu的使用效率,多线程是指在同一程序中有多个顺序流在执行. 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程. 线程:同一类线 ...

  2. 微信小程地图片未加载成功的情况 Failed to load local image resource

    在开发小程序的时候,发现在加载图片时并没有异常,但是后台却报错了. 例如以下我的一段代码: <view class="useage2 "> <image src= ...

  3. linux下编译Boost库

    下载源码 boost_1_66_0.tar.gz 生成编译工具 # tar axf boost_1_66_0.tar.gz # cd boost_1_66_0 # yum install gcc gc ...

  4. [CentOS7] at, bash, cron, anacron

    声明:本文主要总结自:鸟哥的Linux私房菜-第十五章.例行性工作排程(crontab),如有侵权,请通知博主 at => /var/spool/at /etc/at.allow, /etc/a ...

  5. Elasticsearch+Logstash+Kibana搭建分布式日志平台

    一.前言 编译安装 1.ELK简介 下载相关安装包地址:https://www.elastic.co/cn/downloads ELK是Elasticsearch+Logstash+Kibana的简称 ...

  6. hdu2586(lca模板 / tarjan离线 + RMQ在线)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意: 给出一棵 n 个节点的带边权的树, 有 m 个形如 x y 的询问, 要求输出所有 x, ...

  7. 洛谷 P2024 [NOI2001]食物链 (并查集)

    嗯... 题目链接:https://www.luogu.org/problemnew/show/P2024 这道题和团伙这道题的思想比较类似,都是一个数组分成几个集合,但这道题的思路更加混乱,建议没做 ...

  8. day23作业详解

    1.题目 2.题目详解 点击查看详细内容 1. 1-1 封装 把功能封装到类中 class Message(object): def email(self):pass def msg(self):pa ...

  9. PAT甲级——1093 Count PAT's (逻辑类型的题目)

    本文同步发布在CSDN:https://blog.csdn.net/weixin_44385565/article/details/93389073 1093 Count PAT's (25 分)   ...

  10. 与Webpack最后的战斗

    今天用自己搭的脚手架做react项目,终于还是在图片加载的地方出错了.决定好好地看一次最新的官网.顺带写个完整的教程.