热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ffmpeg多个vf_FFmpeg添加自定义滤镜

FFmpeg已经内置了一百多种滤镜,可以对音视频实现很多特效处理。但是当我们想实现类似各短视频平台上的特殊效果时,FFmpeg内置滤镜就无能为力了&#x
c0b24550b5595ec62e8ccc7a44878db2.png

FFmpeg 已经内置了一百多种滤镜,可以对音视频实现很多特效处理。但是当我们想实现类似各短视频平台上的特殊效果时,FFmpeg 内置滤镜就无能为力了,这时我们需要为 FFmpeg 添加自定义的滤镜。

关于 FFmpeg 内置滤镜:ffmpeg-filters

FFmpeg添加自定义滤镜的模板

既然是自定义 FFmpeg 滤镜,那么我们就必须要按照 FFmpeg 规定的套路来实现。

先看一下示例模板:

typedef struct GLWaveContext{const AVClass *class;GLuint program; // 着色器程序GLuint frame_tex; // 纹理 IDGLuint pos_buf; // 顶点缓存GLint time;GLFWwindow *window;
} GLWaveContext;AVFILTER_DEFINE_CLASS(glwave);static av_cold int init(AVFilterContext *ctx)
{return glfwInit() ? 0 : -1;
}static av_cold void uninit(AVFilterContext *ctx)
{GLWaveContext *gs = ctx->priv;glDeleteTextures(1, &gs->frame_tex);glDeleteBuffers(1, &gs->pos_buf);glDeleteProgram(gs->program);glfwDestroyWindow(gs->window);
}static int query_formats(AVFilterContext *ctx)
{static const enum AVPixelFormat formats[] = {AV_PIX_FMT_RGB24,AV_PIX_FMT_NONE};return ff_set_common_formats(ctx, ff_make_format_list(formats));
}static const AVFilterPad glwave_inputs[] = {{.name = "default",.type = AVMEDIA_TYPE_VIDEO,.config_props = config_input,.filter_frame = glwave_filter_frame,.needs_writable = 1,},{ NULL }
};static const AVFilterPad glwave_outputs[] = {{.name = "default",.type = AVMEDIA_TYPE_VIDEO,},{ NULL }
};AVFilter ff_vf_glwave = {.name = "glwave",.description = NULL_IF_CONFIG_SMALL("Generic OpenGL shader filter"),.priv_size = sizeof(GLWaveContext),.init = init,.uninit = uninit,.query_formats = query_formats,.inputs = glwave_inputs,.outputs = glwave_outputs,.priv_class = &glwave_class,.flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
};

首先我们要 coding 一个 C 文件,因为 FFmpeg 源码为 C 。

AVFilter 结构:

.name 对外宣称的滤镜名称,和命令行要使用的 "-vf wave" 是一样的。

.priv_size 初始化 GLWaveContext,这个是 filter 的私有上下文,可以存放本地全局变量。

.init 如果 GLWaveContext 有什么内容需要初始化,就放在init,如果没有,可以删掉。

.uninit 同上 init 。

.query_formats 支持的 AVFrame 格式,按需添加,可以添加多个。

.inputs 交互桥梁,最重要的是 glwave_inputs 结构内的函数指针 filter_frame,我们可以在filter_frame 内获得需要处理的 AVFrame 。至于 config_input 则可以在其中构建好 shader 特效处理代码。

.outputs 用于配置输出的 frame 的大小。

总结

上面所述就是按照 FFmpeg 规则添加滤镜,最重要的还是为 filter_frame,但仅仅是提到我们可以在此函数指针内获得所需处理的 AVFrame。细心的朋友会发现 AVFilterLink,这部分内容需要理清 AVFilterGraph, AVFilterContext, AVFilterLink, AVFilterPad 之间错综复杂的关系,这里不做分析,旨在如何最快实现自定义滤镜



推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 【shell】网络处理:判断IP是否在网段、两个ip是否同网段、IP地址范围、网段包含关系
    本文介绍了使用shell脚本判断IP是否在同一网段、判断IP地址是否在某个范围内、计算IP地址范围、判断网段之间的包含关系的方法和原理。通过对IP和掩码进行与计算,可以判断两个IP是否在同一网段。同时,还提供了一段用于验证IP地址的正则表达式和判断特殊IP地址的方法。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
  • 本文总结了Java中日期格式化的常用方法,并给出了示例代码。通过使用SimpleDateFormat类和jstl fmt标签库,可以实现日期的格式化和显示。在页面中添加相应的标签库引用后,可以使用不同的日期格式化样式来显示当前年份和月份。该文提供了详细的代码示例和说明。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 解决github访问慢的问题的方法集锦
    本文总结了国内用户在访问github网站时可能遇到的加载慢的问题,并提供了解决方法,其中包括修改hosts文件来加速访问。 ... [详细]
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
author-avatar
少爷自控_592
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有