ffmpeg中filter_query_formats函数解析

ffmpeg中filter_query_formats主要起一个pix fmt引用指定的功能。
下下结论:
在这里插入图片描述

先看几个结构体定义:

//删除了一些与本次分析不必要的成员
struct AVFilterLink {AVFilterContext *src;       ///< source filterAVFilterPad *srcpad;        ///< output pad on the source filterAVFilterContext *dst;       ///< dest filterAVFilterPad *dstpad;        ///< input pad on the dest filterenum AVMediaType type;      ///< filter media type/* These parameters apply only to video */int w;                      ///< agreed upon image widthint h;                      ///< agreed upon image heightAVRational sample_aspect_ratio; ///< agreed upon sample aspect ratio/* These parameters apply only to audio */uint64_t channel_layout;    ///< channel layout of current buffer (see libavutil/channel_layout.h)int sample_rate;            ///< samples per secondint format;                 ///< agreed upon media format/****************************************************************** All fields below this line are not part of the public API. They* may not be used outside of libavfilter and can be changed and* removed at will.* New public fields should be added right above.******************************************************************//*** Lists of supported formats / etc. supported by the input filter.*/AVFilterFormatsConfig incfg;/*** Graph the filter belongs to.*/struct AVFilterGraph *graph;...
};

结构体:AVFilterFormatsConfig

typedef struct AVFilterFormatsConfig {/*** List of supported formats (pixel or sample).*/AVFilterFormats *formats;/*** Lists of supported sample rates, only for audio.*/AVFilterFormats  *samplerates;/*** Lists of supported channel layouts, only for audio.*/AVFilterChannelLayouts  *channel_layouts;} AVFilterFormatsConfig;

再来看函数:

static int filter_query_formats(AVFilterContext *ctx)
{int ret, i;AVFilterFormats *formats;AVFilterChannelLayouts *chlayouts;AVFilterFormats *samplerates;enum AVMediaType type = ctx->inputs  && ctx->inputs [0] ? ctx->inputs [0]->type :ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :AVMEDIA_TYPE_VIDEO;if ((ret = ctx->filter->query_formats(ctx)) < 0) {if (ret != AVERROR(EAGAIN))av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n",ctx->name, av_err2str(ret));return ret;}ret = filter_check_formats(ctx);if (ret < 0)return ret;for (i = 0; i < ctx->nb_inputs; i++)sanitize_channel_layouts(ctx, ctx->inputs[i]->outcfg.channel_layouts);for (i = 0; i < ctx->nb_outputs; i++)sanitize_channel_layouts(ctx, ctx->outputs[i]->incfg.channel_layouts);
//如果query_formats函数有,那么这里其实什么也不做formats = ff_all_formats(type);if ((ret = ff_set_common_formats(ctx, formats)) < 0)return ret;if (type == AVMEDIA_TYPE_AUDIO) {samplerates = ff_all_samplerates();if ((ret = ff_set_common_samplerates(ctx, samplerates)) < 0)return ret;chlayouts = ff_all_channel_layouts();if ((ret = ff_set_common_channel_layouts(ctx, chlayouts)) < 0)return ret;}return 0;
}

核心函数:ff_set_common_formats

int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
{SET_COMMON_FORMATS(ctx, formats,ff_formats_ref, ff_formats_unref);
}

看宏定义:

#define SET_COMMON_FORMATS(ctx, fmts, ref_fn, unref_fn)             \int count = 0, i;                                               \\if (!fmts)                                                      \return AVERROR(ENOMEM);                                     \\for (i = 0; i < ctx->nb_inputs; i++) {                          \if (ctx->inputs[i] && !ctx->inputs[i]->outcfg.fmts) {       \int ret = ref_fn(fmts, &ctx->inputs[i]->outcfg.fmts);   \if (ret < 0) {                                          \return ret;                                         \}                                                       \count++;                                                \}                                                           \}                                                               \for (i = 0; i < ctx->nb_outputs; i++) {                         \if (ctx->outputs[i] && !ctx->outputs[i]->incfg.fmts) {      \int ret = ref_fn(fmts, &ctx->outputs[i]->incfg.fmts);   \if (ret < 0) {                                          \return ret;                                         \}                                                       \count++;                                                \}                                                           \}                                                               \\if (!count) {                                                   \unref_fn(&fmts);                                            \}                                                               \\return 0;

接着看ref

int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
{FORMATS_REF(f, ref, ff_formats_unref);
}#define FORMATS_REF(f, ref, unref_fn)                                           \void *tmp;                                                                  \\if (!f)                                                                     \return AVERROR(ENOMEM);                                                 \\tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1);         \if (!tmp) {                                                                 \unref_fn(&f);                                                           \return AVERROR(ENOMEM);                                                 \}                                                                           \f->refs = tmp;                                                              \f->refs[f->refcount++] = ref;                                               \*ref = f;                                                                   \return 0

主要看关键的三行代码:

    f->refs = tmp;                                                              \f->refs[f->refcount++] = ref;                                               \*ref = f;  

这就是最开始图片指示的互相引用。

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

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

相关文章

PhpStudy靶场首页管理

PhpStudy靶场首页管理 一、源码一二、源码二三、源码三四、源码四 一、源码一 index.html <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>靶场访问首页</title><style>body {background-color: #f2f2f2;colo…

JavaDemo——使用jks的https

java使用https主要就是设置下sslContext&#xff0c;sslContext初始化需要密钥管理器和信任管理器&#xff0c;密钥管理器用于管理本地证书和私钥&#xff0c;信任管理器用于验证远程服务器的证书&#xff0c;这两种管理器都需要KeyStore初始化&#xff0c;两种管理器可以按需只…

Ubuntu 网络配置指导手册

一、前言 从Ubuntu 17.10 Artful开始&#xff0c;Netplan取代ifupdown成为默认的配置实用程序&#xff0c;网络管理改成 netplan 方式处理&#xff0c;不在再采用从/etc/network/interfaces 里固定 IP 的配置 &#xff0c;配置写在 /etc/netplan/01-network-manager-all.yaml 或…

【事业单位-语言理解1】中心理解02

【事业单位-语言理解1】中心理解02 1.中心理解1.1 并列关系1.2 主题词1.3程度词&#xff0c;表示强调 二、标题填入题&#xff08;优先考虑主题词&#xff09;三、词句理解题 1.中心理解 解题思路 1.1 并列关系 涉及时间顺序 注意选项不要逻辑不当 并列关系的时候&…

行云创新 CloudOS 助力上汽乘用车企业云原生IT架构变革

近日&#xff0c;在2023架构可持续未来峰会成都制造业分会场上&#xff0c;上海汽车集团股份有限公司乘用车公司基础架构部主管茹洋带来了议题为《云原生时代上汽乘用车企业IT架构变革和实践》的精彩演讲。他从云原生对于企业IT架构的意义、企业IT架构变革的必要性入手&#xf…

C程序环境及预处理

​​​​​文章目录 一、程序的翻译环境和执行环境 1.程序编译过程 2.编译内部原理 3.执行环境 二、程序运行前的预处理 1.预定义符号归纳 2.define定义标识符 3.define定义宏 4.define替换规则 5.宏和函数的对比 三、头文件被包含的方式 四、练习&#xff1a;写一…

Vue3状态管理库Pinia——核心概念(Store、State、Getter、Action)

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

Java将数据集合转换为PDF

这里写自定义目录标题 将数据集合转换为pdf引入包工具类测试代码导出效果 将数据集合转换为pdf 依赖itext7包将数据集合转换导出为PDF文件 引入包 <properties><itext.version>7.1.11</itext.version> </properties><dependency><groupId&…

什么是HTTP 500错误,怎么解决

目录 什么是HTTP 500 HTTP 500错误的常见原因&#xff1a; 如何修复HTTP 500 总结 什么是HTTP 500 错误 HTTP 500内部服务器错误是指在客户端发出请求后&#xff0c;服务器在处理请求过程中发生了未知的问题&#xff0c;导致服务器无法完成请求。HTTP 500错误是一个通用的服…

Spring-缓存初步认识

Spring-缓存 简单介绍 缓存是一种介于数据永久存储介质和数据应用之间的数据临时存储介质缓存有效提高读取速度&#xff0c;加速查询效率 spring使用缓存方式 添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring…

海康摄像头开发笔记(一):连接防爆摄像头、配置摄像头网段、设置rtsp码流、播放rtsp流、获取rtsp流、调优rtsp流播放延迟以及录像存储

文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/131679108 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…

每日一题——反转链表

题目 给定一个单链表的头结点pHead(该头节点是有值的&#xff0c;比如在下图&#xff0c;它的val是1)&#xff0c;长度为n&#xff0c;反转该链表后&#xff0c;返回新链表的表头。 数据范围&#xff1a;0≤n≤1000 要求&#xff1a;空间复杂度 O(1) &#xff0c;时间复杂度 O…

Python实战项目——旅游数据分析(四)

由于有之前的项目&#xff0c;所以今天我们直接开始&#xff0c;不做需求分析&#xff0c;还不会需求分析的可以看我之前的文章。Python实战项目——用户消费行为数据分析&#xff08;三&#xff09; 导入库 import numpy as np import pandas as pd import matplotlib.pyplo…

PHP后台登录功能单账号登录限制

PHP后台登录功能单账号登录限制 单账号登陆是什么第一步创建数据表第二步创建登录页面test2.html第三步创建登录提交test2.php第四步访问后台首页第五步演示 单账号登陆是什么 一个用户只能登录一个账号通常被称为单账号登录限制或单用户单账号限制。这意味着每个用户只能使用…

Linux 学习记录53(ARM篇)

Linux 学习记录53(ARM篇) 本文目录 Linux 学习记录53(ARM篇)一、内存读写指令1. 在C语言中读取内存2. 指令码及功能3. 格式4. 使用示例5. 寻址方式(1. 前索引方式(2. 后索引方式(3. 自动索引 6.批量寄存器操作指令(1. 操作码(2. 格式(3. 使用示例(4. 地址增长方式>1 ia后缀&…

========Java基础——小结1========

一、Java 两大版本 Java 主要分为两个版本: Java SE 和Java EE。 Java SE 全称Java Platform Standard Edition&#xff0c;是 Java 的标准版&#xff0c;主要用于桌面应用程序开发&#xff0c;它包含了 Java 语言基础、JDBC (Java 数据库连接)、I/O (输入/输出)、TCP/IP 网络…

股票基金入门知识

1.开盘价和收盘价如何产生 时间9:30-11:30 13:00-15:00 集合竞价时间段&#xff1a;9:15-9:25 以此产生开盘价 最后集中竞价时间段&#xff1a;深市14:57-15:00 &#xff0c;以此产生收盘价。 沪市则采用最后一分钟加权得出收盘价影响股价的因素 市场投资情绪&#xff0c;宏观…

Hadoop——DataGrip连接MySQL|Hive

1、下载 DataGrip下载&#xff1a;DataGrip: The Cross-Platform IDE for Databases & SQL by JetBrains 2、破解 破解链接&#xff1a;https://www.cnblogs.com/xiaohuhu/p/17218430.html 3、启动环境 启动Hadoop&#xff1a;到Hadoop的sbin目录下右键管理员身份运行…

【C++】list 模拟笔记

文章目录 list定义结点类&#xff08;list_node&#xff09;为什么封装迭代器为类 &#xff1f;库里面模板多参数的由来 &#xff1f;为什么普通迭代器不能隐式类型转换成const迭代器&#xff1f;迭代器位置指向及其返回值和整体代码 list list 和前面学习的 string 和 vector …

微信小程序使用ECharts的示例详解

目录 安装 ECharts 组件使用 ECharts 组件图表延迟加载 echarts-for-weixin 是 ECharts 官方维护的一个开源项目&#xff0c;提供了一个微信小程序组件&#xff08;Component&#xff09;&#xff0c;我们可以通过这个组件在微信小程序中使用 ECharts 绘制图表。 echarts-fo…