ffmpeg命令行是如何打开vf_scale滤镜的
前言
在ffmpeg命令行中,ffmpeg -i test -pix_fmt rgb24 test.rgb
,会自动打开ff_vf_scale
滤镜,本章主要追踪这个流程。
通过gdb可以发现其基本调用栈如下:
可以看到,query_formats()中创建的vf_scale滤镜,
这是ffmpeg滤镜框架中的操作,当avfilter进行query format的时候,如果发现前后两个filter的pixformat不一致的时候就会在中间插入一个vf_scale的滤镜。这就是标题的答案。
但是本章内容主要讨论ffmpeg工具里面是如何调用avfilter的,也就是从哪里开始创建,哪里开始销毁,以及中间是如何传递信息的。特别是当命令行中没有vf_scale的操作时,ffmpeg工具是否会打开filter?
为了分析上述问题,我们先用一定使用到vf_scale的命令:
ffmpeg -i test -pix_fmt rgb24 test.rgb
先找到调用avfilter的两个函数:
ret = av_buffersrc_add_frame_flags(ifilter->filter, frame, buffersrc_flags);
ret = av_buffersink_get_frame_flags(filter, filtered_frame,AV_BUFFERSINK_FLAG_NO_REQUEST);
ffmpeg.h中定义了有关filter的三个结构体:
typedef struct InputFilter {AVFilterContext *filter;struct InputStream *ist;struct FilterGraph *graph;uint8_t *name;enum AVMediaType type; // AVMEDIA_TYPE_SUBTITLE for sub2videoAVFifoBuffer *frame_queue;// parameters configured for this inputint format;int width, height;AVRational sample_aspect_ratio;int sample_rate;int channels;uint64_t channel_layout;AVBufferRef *hw_frames_ctx;int32_t *displaymatrix;int eof;
} InputFilter;typedef struct OutputFilter {AVFilterContext *filter;struct OutputStream *ost;struct FilterGraph *graph;uint8_t *name;/* temporary storage until stream maps are processed */AVFilterInOut *out_tmp;enum AVMediaType type;/* desired output stream properties */int width, height;AVRational frame_rate;int format;int sample_rate;uint64_t channel_layout;// those are only set if no format is specified and the encoder gives us multiple options// They point directly to the relevant lists of the encoder.const int *formats;const uint64_t *channel_layouts;const int *sample_rates;
} OutputFilter;typedef struct FilterGraph {int index;const char *graph_desc;AVFilterGraph *graph;int reconfiguration;// true when the filtergraph contains only meta filters// that do not modify the frame dataint is_meta;InputFilter **inputs;int nb_inputs;OutputFilter **outputs;int nb_outputs;
} FilterGraph;
我们通过上述线索寻找buffersrc和buffersink是在哪里创建的。
首先看buffersink,通过:
decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_t *duration_pts, int eof,int *decode_failed)decode(ist->dec_ctx, decoded_frame, got_output, pkt)send_frame_to_filters(ist, decoded_frame)ifilter_send_frame(ist->filters[i], decoded_frame, i < ist->nb_filters - 1)configure_filtergraph(fg)//reinitav_buffersrc_add_frame_flags(ifilter->filter, frame, buffersrc_flags)
通过上面结构可知其中的configure_filtergraph(fg)//reinit
是关键,在这里初始化整个avfilter。
在这里,我们回顾一下avfilter的关键调用流程:
char args[512];int ret = 0;const AVFilter *buffersrc = avfilter_get_by_name("buffer");const AVFilter *buffersink = avfilter_get_by_name("buffersink");AVFilterInOut *outputs = avfilter_inout_alloc();AVFilterInOut *inputs = avfilter_inout_alloc();AVRational time_base = fmt_ctx->streams[video_stream_index]->time_base;enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };filter_graph = avfilter_graph_alloc();if (!outputs || !inputs || !filter_graph) {ret = AVERROR(ENOMEM);goto end;}/* buffer video source: the decoded frames from the decoder will be inserted here. */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,time_base.num, time_base.den,dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",args, NULL, filter_graph);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");goto end;}/* buffer video sink: to terminate the filter chain. */ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",NULL, NULL, filter_graph);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");goto end;}ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");goto end;}outputs->name = av_strdup("in");outputs->filter_ctx = buffersrc_ctx;outputs->pad_idx = 0;outputs->next = NULL;/** The buffer sink input must be connected to the output pad of* the last filter described by filters_descr; since the last* filter output label is not specified, it is set to "out" by* default.*/inputs->name = av_strdup("out");inputs->filter_ctx = buffersink_ctx;inputs->pad_idx = 0;inputs->next = NULL;if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,&inputs, &outputs, NULL)) < 0)goto end;if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)goto end;...
回到ifilter_send_frame()
中来:
static int ifilter_send_frame(InputFilter *ifilter, AVFrame *frame, int keep_reference)
{FilterGraph *fg = ifilter->graph;AVFrameSideData *sd;int need_reinit, ret;int buffersrc_flags = AV_BUFFERSRC_FLAG_PUSH;if (keep_reference)buffersrc_flags |= AV_BUFFERSRC_FLAG_KEEP_REF;/* determine if the parameters for this input changed *///如果输入和frame中的format不一致,就会引起reinitneed_reinit = ifilter->format != frame->format;switch (ifilter->ist->st->codecpar->codec_type) {case AVMEDIA_TYPE_VIDEO:need_reinit |= ifilter->width != frame->width ||ifilter->height != frame->height;break;}if (!ifilter->ist->reinit_filters && fg->graph)need_reinit = 0;if (!!ifilter->hw_frames_ctx != !!frame->hw_frames_ctx ||(ifilter->hw_frames_ctx && ifilter->hw_frames_ctx->data != frame->hw_frames_ctx->data))need_reinit = 1;if (sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX)) {if (!ifilter->displaymatrix || memcmp(sd->data, ifilter->displaymatrix, sizeof(int32_t) * 9))need_reinit = 1;} else if (ifilter->displaymatrix)need_reinit = 1;if (need_reinit) {//ifilter从这里获取到w,h,pix等信息ret = ifilter_parameters_from_frame(ifilter, frame);if (ret < 0)return ret;}/* (re)init the graph if possible, otherwise buffer the frame and return */if (need_reinit || !fg->graph) {ret = configure_filtergraph(fg);if (ret < 0) {av_log(NULL, AV_LOG_ERROR, "Error reinitializing filters!\n");return ret;}}ret = av_buffersrc_add_frame_flags(ifilter->filter, frame, buffersrc_flags);if (ret < 0) {if (ret != AVERROR_EOF)av_log(NULL, AV_LOG_ERROR, "Error while filtering: %s\n", av_err2str(ret));return ret;}return 0;
}
继续回到onfigure_filtergraph(fg)
删除了与本题无关的代码:
int configure_filtergraph(FilterGraph *fg)
{AVFilterInOut *inputs, *outputs, *cur;//这里判断是否是simple,因为我们的命令行中没有avfilter,故此为trueint ret, i, simple = filtergraph_is_simple(fg);//int filtergraph_is_simple(FilterGraph *fg)//{return !fg->graph_desc;}//这里其实就是NULLconst char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :fg->graph_desc;cleanup_filtergraph(fg);//创建图if (!(fg->graph = avfilter_graph_alloc()))return AVERROR(ENOMEM);if (simple) {//获取到outputstreamOutputStream *ost = fg->outputs[0]->ost;char args[512];const AVDictionaryEntry *e = NULL;} else {fg->graph->nb_threads = filter_complex_nbthreads;}//这里在我们这里可以跳过,因为graph_desc为nullif ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)goto fail;//这里是配置buffersrc的地方for (cur = inputs, i = 0; cur; cur = cur->next, i++){if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0) {avfilter_inout_free(&inputs);avfilter_inout_free(&outputs);goto fail;}}avfilter_inout_free(&inputs);//这里是配置buffersink的地方for (cur = outputs, i = 0; cur; cur = cur->next, i++)configure_output_filter(fg, fg->outputs[i], cur);avfilter_inout_free(&outputs);if (!auto_conversion_filters)avfilter_graph_set_auto_convert(fg->graph, AVFILTER_AUTO_CONVERT_NONE);//avfilter的标准调用if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)goto fail;fg->is_meta = graph_is_meta(fg->graph);return 0;
}
接下来继续看如何配置input_filter的:
static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,AVFilterInOut *in)
{AVFilterContext *last_filter;//创建bufferconst AVFilter *buffer_filt = avfilter_get_by_name("buffer");const AVPixFmtDescriptor *desc;InputStream *ist = ifilter->ist;InputFile *f = input_files[ist->file_index];AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :ist->st->time_base;AVRational fr = ist->framerate;AVRational sar;AVBPrint args;char name[255];int ret, pad_idx = 0;int64_t tsoffset = 0;AVBufferSrcParameters *par = av_buffersrc_parameters_alloc();if (!par)return AVERROR(ENOMEM);memset(par, 0, sizeof(*par));par->format = AV_PIX_FMT_NONE;if (!fr.num)fr = av_guess_frame_rate(input_files[ist->file_index]->ctx, ist->st, NULL);sar = ifilter->sample_aspect_ratio;if(!sar.den)sar = (AVRational){0,1};av_bprint_init(&args, 0, AV_BPRINT_SIZE_AUTOMATIC);//这里是配置buffersrc的地方av_bprintf(&args,"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:""pixel_aspect=%d/%d",ifilter->width, ifilter->height, ifilter->format,tb.num, tb.den, sar.num, sar.den);if (fr.num && fr.den)av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den);snprintf(name, sizeof(name), "graph %d input from stream %d:%d", fg->index,ist->file_index, ist->st->index);//创建filterctxif ((ret = avfilter_graph_create_filter(&ifilter->filter, buffer_filt, name,args.str, NULL, fg->graph)) < 0)goto fail;par->hw_frames_ctx = ifilter->hw_frames_ctx;ret = av_buffersrc_parameters_set(ifilter->filter, par);if (ret < 0)goto fail;av_freep(&par);last_filter = ifilter->filter;desc = av_pix_fmt_desc_get(ifilter->format);av_assert0(desc);snprintf(name, sizeof(name), "trim_in_%d_%d",ist->file_index, ist->st->index);if (copy_ts) {tsoffset = f->start_time == AV_NOPTS_VALUE ? 0 : f->start_time;if (!start_at_zero && f->ctx->start_time != AV_NOPTS_VALUE)tsoffset += f->ctx->start_time;}//插入trimret = insert_trim(((f->start_time == AV_NOPTS_VALUE) || !f->accurate_seek) ?AV_NOPTS_VALUE : tsoffset, f->recording_time,&last_filter, &pad_idx, name);if (ret < 0)return ret;//链接if ((ret = avfilter_link(last_filter, 0, in->filter_ctx, in->pad_idx)) < 0)return ret;return 0;
fail:av_freep(&par);return ret;
}
下面是configure_output_filter
:
static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
{OutputStream *ost = ofilter->ost;OutputFile *of = output_files[ost->file_index];AVFilterContext *last_filter = out->filter_ctx;AVBPrint bprint;int pad_idx = out->pad_idx;int ret;const char *pix_fmts;char name[255];snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);//创建buffersinkret = avfilter_graph_create_filter(&ofilter->filter,avfilter_get_by_name("buffersink"),name, NULL, NULL, fg->graph);if (ret < 0)return ret;//这个scale完全就是尺寸的resizeif ((ofilter->width || ofilter->height) && ofilter->ost->autoscale) {char args[255];AVFilterContext *filter;const AVDictionaryEntry *e = NULL;//这里只有size的scale,并没有颜色空间的转换snprintf(args, sizeof(args), "%d:%d",ofilter->width, ofilter->height);while ((e = av_dict_get(ost->sws_dict, "", e,AV_DICT_IGNORE_SUFFIX))) {av_strlcatf(args, sizeof(args), ":%s=%s", e->key, e->value);}snprintf(name, sizeof(name), "scaler_out_%d_%d",ost->file_index, ost->index);if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),name, args, NULL, fg->graph)) < 0)return ret;if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)return ret;last_filter = filter;pad_idx = 0;}av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);//如果设置了输出的pix_fmt 那么就会在这里增加一个format的的avfilter//这个format其实什么也不做,就是指定一个中间format,用来在协商的时候//确定是否增加中间的csc swscaleif ((pix_fmts = choose_pix_fmts(ofilter, &bprint))) {AVFilterContext *filter;ret = avfilter_graph_create_filter(&filter,avfilter_get_by_name("format"),"format", pix_fmts, NULL, fg->graph);av_bprint_finalize(&bprint, NULL);if (ret < 0)return ret;if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)return ret;last_filter = filter;pad_idx = 0;}if (ost->frame_rate.num && 0) {AVFilterContext *fps;char args[255];snprintf(args, sizeof(args), "fps=%d/%d", ost->frame_rate.num,ost->frame_rate.den);snprintf(name, sizeof(name), "fps_out_%d_%d",ost->file_index, ost->index);ret = avfilter_graph_create_filter(&fps, avfilter_get_by_name("fps"),name, args, NULL, fg->graph);if (ret < 0)return ret;ret = avfilter_link(last_filter, pad_idx, fps, 0);if (ret < 0)return ret;last_filter = fps;pad_idx = 0;}snprintf(name, sizeof(name), "trim_out_%d_%d",ost->file_index, ost->index);ret = insert_trim(of->start_time, of->recording_time,&last_filter, &pad_idx, name);if (ret < 0)return ret;if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)return ret;return 0;
}
所以对于ffmpeg中的graph来说,依次为:
ff_vsrc_buffer->ff_vf_null->(scale resize)->ff_vf_format(命令行中由format的参数)->(fps )->(trim)->ff_buffersink。
中间括号内的是几个选择的avfilter。
协商format的时候最后会协商一个ff_vsrc_buffer的pix fomat.
最后用一个rawenc去将frame编码为pkt…
相关文章:

ffmpeg命令行是如何打开vf_scale滤镜的
前言 在ffmpeg命令行中,ffmpeg -i test -pix_fmt rgb24 test.rgb,会自动打开ff_vf_scale滤镜,本章主要追踪这个流程。 通过gdb可以发现其基本调用栈如下: 可以看到,query_formats()中创建的v…...

【Vue3】自动引入插件-`unplugin-auto-import`
Vue3自动引入插件-unplugin-auto-import,不必再手动 import 。 自动导入 api 按需为 Vite, Webpack, Rspack, Rollup 和 esbuild 。支持TypeScript。由unplugin驱动。 插件安装:unplugin-auto-import 配置vite.config.ts(配置完后需要重启…...

每日温度(力扣)单调栈 JAVA
给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。 示例 1: 输入: temperatur…...

博客项目(Spring Boot)
1.需求分析 注册功能(添加用户操纵)登录功能(查询操作)我的文章列表页(查询我的文章|文章修改|文章详情|文章删除)博客编辑页(添加文章操作)所有人博客列表(带分页功能)…...
修改Jenkins存储目录
注意:在Jenkins运行时是不能更改的. 请先将Jenkins停止运行。 1、windows环境下更改JENKINS的主目录 Windows环境中,Jenkins主目录默认在C:Documents and SettingsAAA.jenkins 。可以通过设置环境变量来修改,例如: JENKINS_HOME…...

数据结构【第4章】——栈与队列
队列是只允许在一端进行插入操作、而在另-端进行删除操作的线性表。 栈 栈与队列:栈是限定仅在表尾进行插入和删除操作的线性表。 我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)&…...
android webview 显示灰度网页
要在WebView中显示网页灰度显示,您可以通过以下步骤操作: 在您的布局文件中添加WebView组件: <WebViewandroid:id"id/webview"android:layout_width"match_parent"android:layout_height"match_parent" /…...
Linux操作系统的基础使用技能的训练大纲(超级详细版本适合于初学者)
RHCE红帽认证工程师课程对应考试课 程 纲 要 第一部分 网络基础 RH033RH302 Linux基础: 1) 在bashshell命令行模式下运行基本的Linux命令 2) 从命令行及GNOME界面启动应用程序 3) 使用及配置Xwindow系统及GNOME桌面环境 4) 使用GNOME GUI应用程序完成一般的工作 5) 了解Linu…...

【变形金刚02】注意机制以及BERT 和 GPT
一、说明 我已经解释了什么是注意力机制,以及与转换器相关的一些重要关键字和块,例如自我注意、查询、键和值以及多头注意力。在这一部分中,我将解释这些注意力块如何帮助创建转换器网络,注意、自我注意、多头注意、蒙面多头注意力…...

一个脚本 专治杂乱
背景 之前不是自己手动搞了一个COS嘛,直接复制粘贴图片,上传到后端的服务器,返回一个可访问的地址。我在哔哩哔哩上也分享过这样的一期视频。 今天偶尔上服务器一看,我靠,我的文件真的乱! 这还得了了&…...

springboot 基础
巩固基础,砥砺前行 。 只有不断重复,才能做到超越自己。 能坚持把简单的事情做到极致,也是不容易的。 SpringBoot JavaEE 简介 JavaEE的局限性: 1、过于复杂,JavaEE正对的是复杂的分布式企业应用,然而现实…...
web集群学习:基于nginx的反向代理和负载均衡
目录 一,反向代理 1,环境准备 2,配置代理服务器 3,在物理机上一管理员身份打开文本编辑器,编辑C:\Windows\System32\drivers\etc目录下的hosts文件 4,访问测试 5,查看日志,并记…...
编程小窍门: 一个简单的go mutex的小例子
本期小窍门用到了两个组件 mutex 这个类似其他语言的互斥锁waitGroup 这个类似其他语言的信号量或者java的栅栏锁 示例如下 func TestDoSomething04(t *testing.T) {total : 0var wg sync.WaitGroup{}var mut sync.Mutex{} for i : 0; i < 5000; i {go func() {wg.Ad…...

【工作记录】mysql中实现分组统计的三种方式
前言 实际工作中对范围分组统计的需求还是相对普遍的,本文记录下在mysql中通过函数和sql完成分组统计的实现过程。 数据及期望 比如我们获取到了豆瓣电影top250,现在想知道各个分数段的电影总数. 表数据如下: 期望结果: 实现方案 主要思路是根据s…...

马来西亚的区块链和NFT市场调研
马来西亚的区块链和NFT市场调研 基本介绍 参考: https://zh.wikipedia.org/wiki/%E9%A9%AC%E6%9D%A5%E8%A5%BF%E4%BA%9A zz制度:联邦议会制 语言文字: 马来语 民族: 69.4%原住民(土著),23.2%…...

[保研/考研机试] KY109 Zero-complexity Transposition 上海交通大学复试上机题 C++实现
描述: You are given a sequence of integer numbers. Zero-complexity transposition of the sequence is the reverse of this sequence. Your task is to write a program that prints zero-complexity transposition of the given sequence. 输入描述…...

Linux零基础快速入门到精通
一、操作系统概述 二、初始Linux Linux的诞生 Linux内核 Linux发行版 小结 三、虚拟机 认识虚拟机 虚拟化软件及安装 VMware Workstation 17 Pro安装教程https://blog.csdn.net/weixin_62332711/article/details/128695978 远程连接Linux系统 小结 扩展-虚拟机快照 …...

ARM02汇编指令
文章目录 一、keil软件介绍1.1 创建工程1.2 解析start.s文件(重点)1.3 乱码解决1.4 更换背景颜色1.5 C语言内存分布1.6 解析map.lds文件(重点)1.7 常见错误信息1.8 仿真 二、汇编三种符号2.1 汇编指令2.2 伪指令2.3 伪操作 三、汇编指令格式3.1 格式3.2 注意事项 四、数据操作指…...

从初学者到专家:Java方法的完整指南
目录 一.方法的概念及使用 1.1什么是方法 1.2方法的定义 1.3方法的调用 1.4实参和形参的关系 1.5没有返回值的方法 1.6方法的意义 二.方法重载 2.1方法重载的实现 2.2方法重载的意义 2.3方法签名 一.方法的概念及使用 1.1什么是方法 方法就是一个代码片段. 类似于 …...

【生成式AI】ProlificDreamer论文阅读
ProlificDreamer 论文阅读 Project指路:https://ml.cs.tsinghua.edu.cn/prolificdreamer/ 论文简介:截止2023/8/10,text-to-3D的baseline SOTA,提出了VSD优化方法 前置芝士:text-to-3D任务简介 text-to-3D Problem text-to-3D…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...

《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...