FFplay音频滤镜分析

news2024/11/18 17:22:49

音频流的 滤镜是通过 configure_audio_filters() 函数来创建的,因为 ffplay 为了代码的通用性,即便命令行参数不使用滤镜,AVFrame 也会过一遍 空滤镜做下样子。

configure_audio_filters() 函数的流程图如下:

configure_audio_filters() 函数的定义如下:

static int configure_audio_filters(VideoState *is, const char *afilters, int force_output_format){....}

下面讲解一下这个函数的参数。

VideoState *is ,是 ffplay 播放器的全局管理器。

char *afilters,是滤镜字符串,例如 下面的命令:

ffplay -af "atempo=2.0" -i juren-5s.mp4

"atempo=2.0" 这个字符串就会赋值给 afilters

int force_output_format ,代表是否强制把 buffersink 出口滤镜的音频帧采样等信息 设置为 跟 is->audio_tgt 一样。

之前说过 is->audio_tgt 是音响硬件设备打开的信息。is->audio_tgt最终要传递给 SDL 的音频格式。所有的采样率,声道数等等最后都要转成 is->audio_tgt


下面来分析一下configure_audio_filters() 函数里面的重点代码,如下:

这个函数一开始就定义了 一些只有 2 个元素的数组,这其实是 ffmpeg 项目传递参数的方式,传递一个数组进去函数,主要有两种方式。

1, 传递数组的大小。就是有多少个元素。

2, 传递数组的结尾,只要读到结尾元素 (-1),就算结束了。

ffmpeg 大部分函数采用的是第二种方式。


然后他会调 avfilter_graph_free() 释放滤镜容器(FilterGraph),有些同学可能会疑惑,is->agraph 一开始不是 NULL 吗? 为什么需要释放?

is->agraph 一开始确实是 NULL,但是 configure_audio_filters() 这个函数可能会调用第二次,第二次的时候 is->agraph 就不是 NULL了。

configure_audio_filters() 第一次调用是在 stream_component_open() 里面,如下:

第二次调用是在 audio_thread() 里面,如下:

第二次调用 configure_audio_filters() 是因为实际解码出来的 AVFrame 的采样率,声道等,跟容器里面记录的不一致,之前 is->audio_filter_src 是直接从容器,封装层取的数据。封装层记录的音频采样率等,可能是错的,需要以实际解码出来的 AVFrame 为准。

而且,注意,第二次的时候,force_output_format 参数会置为 1,这样会强制 buffersink 出口滤镜的采样信息等 设置为 is->audio_tgt 一样。

其实configure_audio_filters() 必然会调第二次的,因为 is->auddec.pkt_serial != last_serial 这个条件肯定是真。

【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~

  


接着就是设置 滤镜使用的线程数量,0 为自动选择线程数量,如下:

is->agraph->nb_threads = filter_nbthreads;

第三个重点是,设置重采样选项(aresample_swr_opts),如下:

什么样的命令行参数才是重采样选项的,在 libswresample/options.c 里面可以找到,如下:

举个例子,如下:

ffpaly -ich 1 -i juren-5s.mp4

ich 1 就会被解析拷贝进去 ffplay.c 里面的 swr_opts 变量里面。

这里还用到了一个新的函数 av_opt_set(),这个函数其实不只可以设置滤镜的属性字段,还可以设置大多数数据结构的属性字段,例如解码器,封装器 等等,只要内部有 AVClass 的数据结构,都能用 av_opt_set() 来设置属性。


接下来的重点是设置入口跟出口滤镜,如下:

出口滤镜还设置了 sample_fmtsAV_SAMPLE_FMT_S16,这是 ffpaly 播放器自己的特性,就是说无论MP4文件里面的音频格式是怎样的,他都会转成 AV_SAMPLE_FMT_S16 格式丢给 SDL 播放,而且它在用 SDL_OpenAudioDevice 打开音频设备的时候,就是用的 S16 格式,这是写死的


force_output_format 的逻辑主要是 强制 buffersink 出口滤镜的采样信息等 设置为跟 is->audio_tgt 一样。audio_tgt 是 SDL 接受音频帧的最终格式。

第一次调用 configure_audio_filters() 函数,force_output_format 为 0,不会跑进去这块逻辑。


最后就是调 configure_filtergraph() 函数来链接入口跟出口滤镜,同时创建滤镜容器(FilterGraph),如下:

上图最重要的是,入口滤镜 跟 出口滤镜 被赋值到全局管理器 is 了。后面只要把解码器输出的 AVFrame 往入口滤镜丢,然后往出口滤镜读就行了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/70131.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HCIA OSI参考模型

一、前言 OSI七层模型是我们耳熟能详的,其实没有太多可以说的地方,我这里就按自己的理解做一下汇总。 二、OSI 七层模型 OSI七层模型是由“国际标准化组织”制定的“参考”模型。 1、物理层 实际上就是对网线、光纤等“连接”介质进行规定&#xff…

初学者必看的3D建模避坑技巧,高效3D制作

近来,随着3D技术的进步被认为任何对 3D 建模主题感兴趣的人打开了机会之门。现在,只要您拥有一台计算机和良好的空间分析技能,您就可以通过时间和持续练习来完善您的 3D 雕刻方式。 也就是说,该领域的许多初学者往往会犯建模错误&…

信号傅里叶变换后频谱刻度设置问题-附Matlab代码

一、概述 时域信号经FFT变换后得到了频谱,在绘制频谱图时还必须设置正确的频率刻度,这样才能从图中得到正确的结果。 二、实例分析 有一余弦信号,信号频率为30Hz,采样频率128Hz,信号长128,原始信号如下图…

【JavaScript+自然语言处理+HTML+CSS】实现Web端的智能聊天问答客服实战(附源码 超详细必看)

需要源码请点赞关注收藏后评论区留言私信~~~ 智能客服的部署方式比较多样化,可以作为组件嵌入到其他应用程序,也可以部署到定制网站,下面分别介绍如何新创建智能客服应用,从而使其能够集成为网站功能的一部分,以及如何…

给你讲明白MySQL的乐观锁和悲观锁

乐观锁与悲观锁是一种广义上的概念。不管是 Java 语言,也或者是其他语言以及数据库都有这类概念对应的实际应用。想要学习乐观锁和悲观锁就要学习他们的基本知识,那么下面我们来学习一下。 锁 生活中:锁在我们身边无处不在,比如我…

PMO项目经理必备的简洁解决问题方案和报告模板

项目经理虽然有责无权,他的权力更多来源于汇报的权力和影响力,作为项目经理和PMO难免经常会进行报告或者是提供方案建议,能够最短时间的讲明白问题和建议才会更多的获得机会,那么如何才能简明扼要的把你的方案和报告说清楚呢&…

基于jsp+mysql+ssm基金信息管理系统-计算机毕业设计

项目介绍 本基金信息管理系统主要包括系统基金信息管理模块、用户管理模块、基金收藏管理、登录模块、和退出模块等多个模块,系统采用了jsp的mvc框架,SSM(springMvcspringMybatis)框架进行开发,本系统是独立的运行,不依附于其他系统,可移植,…

图扑软件数字孪生污水处理厂

随着人工智能、大数据、云计算、物联网和5G等新技术不断融入水务行业的各个环节,智慧水务已逐渐成为传统水务领域转型升级的重要方向。 图扑软件依托自主研发的 HT for Web 产品,并结合视频融合、BIM、5G、物联网、云计算及大数据等先进技术,…

IIS反向代理 设置IIS跨域访问

概念说明 浏览器的同源策略限制了对某些资源的跨域访问,其目的是保障用户数据安全,但同时也阻止了部分合理的跨域请求。为了绕过同源策略的限制,人们提出了多种跨域访问方案。 解决步骤 打开IIS,选中当前站点 -》右侧找到HTTP响…

手写js-防抖,节流

防抖 debounce 函数所做的事情就是,在用户停止某个操作一段时间之后才执行相应的监听函数,而不是在用户操作的过程当中,浏览器触发多少次事件,就执行多少次监听函数。 以最后一次操作为准开始计时器 应用场景: 登录、发短信等按钮…

JAVA SCRIPT设计模式--结构型--设计模式之Bridge桥接模式(7)

JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代…

Linux 之七 内核架构、API/ABI 介绍、文件层次结构、Kernel 源码文件

Linux 内核最早是在 1991 年由芬兰大学生林纳斯托瓦兹为自己的个人电脑开发的,并在 GNU 通用公共许可证第 2 版(也包含了其他兼容许可证)之下发布的一种开源的类 Unix 操作系统宏内核。 注意,我们通常说的 Linux 系统是 Linux Ker…

FineReport数据图表制作教程-密码控件

1. 概述 1.1 版本 报表服务器版本 功能变更 11.0 -- 1.2 应用场景 1.2.1 填报控件 填报报表中可以通过该控件输入密码信息,录入密码,如下图所示: 1.2.2 参数控件 参数面板处可以通过该控件输入密码信息,键入查询参数&#…

WebRTC GCC 拥塞控制算法(TFB-GCC)

目录 一. 前言 二. TFB-GCC原理 1. 接收端记录并反馈收包情况 (1)transport-wide sequence nunmber (2)RTCP RTPFB TW 报文 2. 发送端结合包接收反馈情况进行带宽预估拥塞控制 (1)基于延时梯度的带宽…

新手必看!jenkins邮件发送配置,一教就会!

最近刚学习jenkins,在配置邮件发送的时候,踩了很多坑,各种百度查询,调试了大半天,终于成功解决 !特此记录! 遇到最让我头痛的问题,就是明明控制台显示邮件发送成功,但是…

【STM32笔记】HAL库低功耗模式配置(ADC唤醒无法使用的解决方案)

【STM32笔记】HAL库低功耗模式配置(ADC唤醒无法使用的解决方案) 理论转载: leung-manwah.blog.csdn.net/article/details/114675725 一、低功耗模式简介 系统提供了多个低功耗模式,可在 CPU 不需要运行时(例如等待外…

Python实现PSO粒子群优化循环神经网络LSTM分类模型项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 PSO是粒子群优化算法(Particle Swarm Optimization)的英文缩写,是一…

配置别名 配置alias

Linux: ~/.bashrc MAC bash 的配置文件是 ~/.bash_profile zsh的配置文件是~/.zsh 查看一下你的shell类型 terminal->performance->shells open with 方案是 1. 创建新的文件存放alias cd ~ vi .myalias edit .myalias esc :wq保存 2. add config to ~/.zshrc …

Java数据结构与Java算法学习Day09---并查集(简略笔记记录)

目录 并查集的功能: 1.1并查集结构 136 1.2并查集API设计 137 1.3并查集代码的实现 137 1.3.1UF(int N)构造方法实现 1.3.2并查集代码测试 138 1.4并查集应用案例 139 1.5UF_Tree算法优化 139 1.5.1UF_tree API设计 1.5.2优化后的…

git基本操作

目录 1 git命令与状态 1.1 常用git命令 1.2 不那么常用的git命令 1.3 常见状态 2 一些概念 2.1 版本控制 2.2 git简介 2.3 开源许可协议 3 常见git操作 3.1 下载git 3.2 安装git 3.3 配置用户信息 3.4 初始化仓库 3.5 查看git仓库状态 3.6 将文件…