ffmpeg-aresample_swr_opts的解析
ffmpeg option的解析
ffmpeg -y -i /home/hui/2ch-16k.wav -filter_size 16 -phase_shift 6 -ar 48000 out.wav
 
其中-filter_size 16,-phase_shift 6是被当做option解析的,会进入opt_default函数,因为这两个参数是swresample的,所以对应代码是:
#if CONFIG_SWRESAMPLEif (!consumed && (o=opt_find(&swr_class, opt, NULL, 0,AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {av_dict_set(&swr_opts, opt, arg, FLAGS);consumed = 1;}
#endif
 
解析后会把这两个option设置到swr_opts上。
然后进入configure_filtergraph函数,会将这个option设置到aresample_swr_opts:
while ((e = av_dict_get(ost->swr_opts, "", e,AV_DICT_IGNORE_SUFFIX))) {av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
}
if (strlen(args))args[strlen(args)-1] = 0;
av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
 
然后在avfiltergraph的query_formats函数中,创建convert filter的时候将option传进去:
snprintf(inst_name, sizeof(inst_name), "auto_%s_%d",neg->conversion_filter, converter_count++);
opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph);
ret = avfilter_graph_create_filter(&convert, filter, inst_name, opts, NULL, graph);
 
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dDoU3L6W-1690516720789)(.images/image-20230609154650936.png)]
其中,graph参数中,可以看到aresample_swr_opts就是"filter_size=16:phase_shift=6"。
aresample_swr_opts为什么不能通过命令行设置?
ffmpeg -i chengdu-44100.wav "aresample_swr_opts=filter_size=16:phase_shift=6" -ar 48000 chengdu-48000-ff.wav
 
📣 ffmpeg命令行不支持参数aresample_swr_opts。
AVFilterGraph::aresample_swr_opts在graph解析的时候不能当做filter的option解析:
-  
graph load的时候解析graph文本的过程,option来自filter的option,
aresample_swr_opts是AVFilterGraph的option,而AVFilterGraph不在filter的list中,所以graph文本中不支持aresample_swr_opts。 -  
aresample_swr_opts如前面所述,在ffmpeg命令行,支持如下写法:ffmpeg -y -i test.wav -filter_size 16 -phase_shift 6 -ar 48000 out.wav其中filter_size和phase_shift会在解析的时候读取swr class的option,匹配成功后,拼接成swr_opts字符串,最后将swr_opts设置到
graph->aresample_swr_opts上。avfiltergraph中协商如果convert_needed大于0,就会创建对应的swresample,将swr_opts中的option作为swresample的option参数传入。 
ffmpeg help命令的解析
当用户在命令行中输入ffmpeg -h或ffmpeg -help时,show_help_default函数会被调用,输出帮助信息。该函数还可以在其他情况下被调用,例如当用户输入无效的命令行选项时,或者当用户输入ffmpeg -h <选项>时,显示特定选项的帮助信息。
ffmpeg --help full
 
如果是help full,会有这样的调用层次,并且show_avoptions和show_advanced都被赋值为1:
show_help
- show_help_default- show_help_options
 
在show_help_options中:
    if (opt && *opt) {if (!strcmp(opt, "long"))show_advanced = 1;else if (!strcmp(opt, "full"))show_advanced = show_avoptions = 1;elseav_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);}
 
show_avoptions的分支中:
    if (show_avoptions) {int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;show_help_children(avcodec_get_class(), flags);show_help_children(avformat_get_class(), flags);
#if CONFIG_SWSCALEshow_help_children(sws_get_class(), flags);
#endif
#if CONFIG_SWRESAMPLEshow_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM);
#endifshow_help_children(avfilter_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM);show_help_children(av_bsf_get_class(), AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_BSF_PARAM);}
 
这里,会遍历avcodec,avformat,sws,swr,avfilter,av_bsf的class,将其children class对应的option全部显示出来。
最后的实现
在avfilter里面类似cmdutils.c里面的逻辑,添加对swr的处理:
+#include "libswresample/swresample.h"#define FF_INTERNAL_FIELDS 1#include "framequeue.h"
@@ -951,6 +952,10 @@ static int process_options(AVFilterContext *ctx, AVDictionary **options,char *av_uninit(parsed_key), *av_uninit(value);const char *key;int offset= -1;
+#if CONFIG_SWRESAMPLE
+    char swr_opts[256] = { 0 };
+    const AVClass *swr_class = swr_get_class();
+#endifif (!args)return 0;
@@ -995,24 +1000,31 @@ static int process_options(AVFilterContext *ctx, AVDictionary **options,av_free(parsed_key);return ret;}
-        } else {
-            o = av_opt_find(ctx->priv, key, NULL, 0,
-                            AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
-            if (!o) {
-                av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
-                av_free(value);
-                av_free(parsed_key);
-                return AVERROR_OPTION_NOT_FOUND;
-            }
+        } else if (o = av_opt_find(ctx->priv, key, NULL, 0,
+                            AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) {av_dict_set(options, key, value,(o->type == AV_OPT_TYPE_FLAGS &&(value[0] == '-' || value[0] == '+')) ? AV_DICT_APPEND : 0);
+#if CONFIG_SWRESAMPLE
+        } else if (o = av_opt_find(&swr_class, key, NULL, 0, 0)) {
+            av_strlcatf(swr_opts, sizeof(swr_opts), "%s=%s:", key, value);
+#endif
+        } else {
+            av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
+            av_free(value);
+            av_free(parsed_key);
+            return AVERROR_OPTION_NOT_FOUND;}av_free(value);av_free(parsed_key);}+    if (strlen(swr_opts)) {
+        swr_opts[strlen(swr_opts) - 1] = 0;
+        av_opt_set(ctx->graph, "aresample_swr_opts", swr_opts, 0);
+    }
+
 
这样,在graph中配置上filter_size=16:phase_shift=6,然后,load graph的时候并不会在avfiltergraph里面进行解析,播放的时候,调用avfilter_graph_reconfig,调用栈如下:
query_formats(AVFilterGraph * graph, void * log_ctx) (ffmpeg/libavfilter/avfiltergraph.c:747)
graph_config_formats(AVFilterGraph * graph, void * log_ctx) (ffmpeg/libavfilter/avfiltergraph.c:1373)
avfilter_graph_reconfig(AVFilterGraph * graphctx, void * log_ctx) (ffmpeg/libavfilter/avfiltergraph.c:1519)
movie_async_activate(AVFilterContext * ctx) (ffmpeg/libavfilter/src_movie_async.c:1254)
ff_filter_activate(AVFilterContext * filter) (ffmpeg/libavfilter/avfilter.c:1565)
ff_filter_graph_run_all(AVFilterGraph * graph) (ffmpeg/libavfilter/avfiltergraph.c:1718)
 
进入query_formats之后,获取opts,就是前面在graph中配置的opts:
opts = FF_FIELD_AT(char *, neg->conversion_opts_offset, *graph);
if (link->type == AVMEDIA_TYPE_AUDIO) {snprintf(inst_opts, sizeof(inst_opts), "converter=%d:%s", convert_needed, opts ? opts : "");opts = inst_opts;
}
snprintf(inst_name, sizeof(inst_name), "auto_%s", neg->conversion_filter);
ret = avfilter_graph_create_filter(&convert, filter, inst_name, opts, NULL, graph);
if (ret < 0)return ret;
if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)return ret;
 
最后创建filter的时候,就会将这些options设置到fitler上。
相关文章:
ffmpeg-aresample_swr_opts的解析
ffmpeg option的解析 ffmpeg -y -i /home/hui/2ch-16k.wav -filter_size 16 -phase_shift 6 -ar 48000 out.wav其中-filter_size 16,-phase_shift 6是被当做option解析的,会进入opt_default函数,因为这两个参数是swresample的,所…...
PX4从放弃到精通(二十九):传感器冗余机制
文章目录 前言一、parametersUpdate二、imuPoll三、 put四、 confidence五、 get_best 前言 PX4 1.13.2 一个人可以走的更快,一群人才能走的更远,可加文章底部微信名片 代码的位置如下 PX4冗余机制主要通过传感读数错误计数和传感器的优先级进行选优 …...
vue 设置数组
手写获取数据 <el-form-item label"缴纳方"><el-select v-model"form.invoiceCategoryName" placeholder"请选择缴纳方"><el-optionv-for"item in kplmList":key"item.value":label"item.label":v…...
9.NIO非阻塞式网络通信入门
highlight: arduino-light Selector 示意图和特点说明 一个 I/O 线程可以并发处理 N 个客户端连接和读写操作,这从根本上解决了传统同步阻塞 I/O 一连接一线程模型。架构的性能、弹性伸缩能力和可靠性都得到了极大的提升。 服务端流程 1、当客户端连接服务端时&…...
QT基于TCP协议实现数据传输以及波形绘制
这个玩意我做了两个,一个是安卓app,一个是Windows程序。代码并非全部都是由我从无到有实现,只是实现了我想要的功能。多亏了巨人的肩膀,开源万岁!!! 我把程序放到GitHub上,需要的可…...
苹果safari浏览器播放不了video标签视频
今天遇到了个神奇的问题,视频文件在pc端和安卓手机上播放都没问题,但是在ios上就是播放不了,大概代码如下: 前端代码: <video id"video" width"350" height"500" controls><s…...
【粒子群算法和蝴蝶算法组合】粒子群混沌混合蝴蝶优化算法研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Java设计模式之单例模式详解(懒汉式和饿汉式)
在开发工作中,有些类只需要存在一个实例,这时就可以使用单例模式。Java中的单例模式是一种常见的设计模式,它确保一个类只有一个实例,并提供全局访问点。下面来介绍一下两种常见的单例模式:懒汉式和饿汉式。 一、懒汉式…...
软件测试基本知识
安全测试 安全防护策略?(漏洞扫描、入侵检查、安全日志、隔离防护) 安全日志:用于记录非法用户的登录名称、操作时间及内容等信息,以便发现问题并提出解决措施;安全日志仅记录相关信息,不对非…...
Vue项目中强制刷新页面的方法
我们在动态切换组件的过程中,导航栏和底栏不动,动态切换中间区域的情况,在首页可以进行跳转任意组件,在组件与组件之间不能相互跳转,路由发生了变化,但是页面未改变,这时我们就需要强制刷新页面…...
文件按关键字分组-切割-染色-写入excel
1. 背景 针对下面的文件data.csv,首先根据fid进行排序,然后分组,使相同fid的记录放到同一个excel文件中,并对每列重复的数据元素染上红色。 fid,user_id -1000078398032092029,230410010036537520 -1000078398032092029,23042301…...
爬虫的基本原理:爬虫概述及爬取过程
前言 随着互联网的不断发展和普及,我们的生活越来越离不开网络。而网络世界中有着海量的信息和数据,这些信息和数据对于我们的工作和生活都有很大的帮助。但是,如何高效地获取这些数据呢?这时候,爬虫这个工具就派上用…...
cocos2D插件转3D插件
cocos2D插件转3D插件 use strict;/*** 3d插件api映射,兼容2d插件* */let fs require("fs");let path require("path");let baseDir ;const prsPath (Editor.Project && Editor.Project.path ? Editor.Project.path : Editor.remote.projectP…...
[Angular] 主从表结构,从表记录在主表固定栏位上呈现
Background 主从表结构,有时为了方便数据呈现,在UI上不显示从表资料,那么需要动态把从表的资料加载到主表的固定栏位上。 例如:主表是人员信息,从表是银行卡信息,一个人在同一家银行可能有多张银行卡&…...
Kotlin Multiplatform 创建多平台分发库
目标:通过本教程学习如何使用 Kotlin Multiplatform Library 创建多平台分发库(iOS,安卓)。 创建一个项目 1、本教程使用的是Android Studio创建 2、选择 新建工程,选择 Kotlin Multiplatform Library 3、点击next 输入需要创建的项目名称以…...
[SQL挖掘机] - union/union all 使用注意事项
因为当使用union和union all操作符时,有一些注意事项需要考虑: 1. 列数和数据类型匹配: 要使用union或union all合并结果集,两个或多个查询的 select 语句必须返回相同数量和类型的列。确保每个查询返回相同的列数,并…...
php 单例模式
1,单例模式,属于创建设计模式,简单来说就是一个类只能有一个实例化对象,并提供一个当前类的全局唯一可访问入口; 2,例子 <?phpclass Singleton {private static $instance null;// 禁止被实例化priva…...
【数据结构】实验二:顺序表
实验二 顺序表 一、实验目的与要求 1)熟悉顺序表的类型定义; 2)熟悉顺序表的基本操作; 3)灵活应用顺序表解决具体应用问题。 二、实验内容 1)在一个整数序列a1,a2,…,an中,若存在一个数&…...
【高级数据结构】线段树
目录 最大数(单点修改,区间查询) 线段树1(区间修改,区间查询) 最大数(单点修改,区间查询) 洛谷:最大数https://www.luogu.com.cn/problem/P1198 题目描述 …...
qt简易闹钟
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);ui->stopBtn->setDisabled(true);this->setFixedSize(this->size()); //设置固定大小this->s…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...
