[ffmpeg] find 编码器
背景
整理 ffmpeg 中,如何通过名字或者 id 找到对应编码器的。
具体流程
搜索函数
avcodec_find_encoder // 通过 ID 搜索编码器
avcodec_find_encoder_by_name // 通过名字搜索编码器
源码分析
ffmpeg 中所有支持的编码器都会注册到 codec_list.c 文件中,保存在 codec_list 结构体中,既有编码器也有解码器,且该结构体最后一个是 NULL,这样方便 ffmpeg 内部的迭代算法使用。
static const FFCodec *codec_list[] = {&ff_a64multi_encoder,&ff_a64multi5_encoder,&ff_alias_pix_encoder,&ff_amv_encoder,...&ff_av1_decoder,NULL
};
搜索编码器用到的函数主要有这些,主要推测是一次遍历 codec_list 结构体,拿到结构体首先通过 av_codec_is_encoder 函数判断是不是编码器;然后在判断 id 和传入相同。 (avcodec_find_encoder_by_name 类似,只是最后一步是判断 name是否相等)
av_codec_iterate 写的方式很像 c++ 中的迭代器,index 不断加1,然后通过 codec_list 结构体最后的 NULL 作为结尾的判断。
// allcodecs.c 中
const AVCodec *avcodec_find_encoder(enum AVCodecID id)
{return find_codec(id, av_codec_is_encoder);
}
static const AVCodec *find_codec(enum AVCodecID id, int (*x)(const AVCodec *))
{const AVCodec *p, *experimental = NULL;void *i = 0;id = remap_deprecated_codec_id(id); //兼容代码,可先不管while ((p = av_codec_iterate(&i))) {if (!x(p))continue;if (p->id == id) {//兼容代码,可先不管if (p->capabilities & AV_CODEC_CAP_EXPERIMENTAL && !experimental) {experimental = p;} elsereturn p;}}return experimental;
}const AVCodec *av_codec_iterate(void **opaque)
{uintptr_t i = (uintptr_t)*opaque;const FFCodec *c = codec_list[i];//av_codec_init_static 只运行一次,兼容代码,可先不管ff_thread_once(&av_codec_static_init, av_codec_init_static);if (c) {*opaque = (void*)(i + 1);return &c->p;}return NULL;
}// 判断这个 avcodec 是不是编码器
int av_codec_is_encoder(const AVCodec *avcodec)
{const FFCodec *const codec = ffcodec(avcodec);return codec && (codec->cb_type == FF_CODEC_CB_TYPE_ENCODE ||codec->cb_type == FF_CODEC_CB_TYPE_ENCODE_SUB ||codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_PACKET);
}
具体例子
该结构体在 aacenc.c 文件中
主要是 FF_CODEC_ENCODE_CB,表示这个 codec 是编码器。
其他:.p.xx 这些是设置 AVCodec 结构体
const FFCodec ff_aac_encoder = {.p.name = "aac",CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),.p.type = AVMEDIA_TYPE_AUDIO,.p.id = AV_CODEC_ID_AAC,.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |AV_CODEC_CAP_SMALL_LAST_FRAME,.priv_data_size = sizeof(AACEncContext),.init = aac_encode_init,FF_CODEC_ENCODE_CB(aac_encode_frame),.close = aac_encode_end,.defaults = aac_encode_defaults,.p.supported_samplerates = ff_mpeg4audio_sample_rates,.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,.p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,AV_SAMPLE_FMT_NONE },.p.priv_class = &aacenc_class,
};#define CODEC_LONG_NAME(str) .p.long_name = str
#define FF_CODEC_ENCODE_CB(func) \.cb_type = FF_CODEC_CB_TYPE_ENCODE, \.cb.encode = (func)
细节推敲
为啥 AVCodec 可以强转为 FFCodec?
int av_codec_is_encoder(const AVCodec *avcodec)
{**const FFCodec *const codec = ffcodec(avcodec);**return codec && (codec->cb_type == FF_CODEC_CB_TYPE_ENCODE ||codec->cb_type == FF_CODEC_CB_TYPE_ENCODE_SUB ||codec->cb_type == FF_CODEC_CB_TYPE_RECEIVE_PACKET);
}
看了一下 FFCodec 中的结构定义,AVCodec p 是定义在FFCodec 最前面的,所以如果当前使用的 AVCodec 是用FFCodec 创建的,直接强转就能找到对应的 FFCodec 对象。如果 AVCodec 是独立创建的,强转肯定是有问题的。感觉这块写的有点 hardcode,不按 ffmpeg 约定俗成的一些规则写会有比较难查的bug。
typedef struct FFCodec {/*** The public AVCodec. See codec.h for it.*/AVCodec p;/*** Internal codec capabilities FF_CODEC_CAP_*.*/unsigned caps_internal:29;/*** This field determines the type of the codec (decoder/encoder)* and also the exact callback cb implemented by the codec.* cb_type uses enum FFCodecType values.*/unsigned cb_type:3;// .../*** List of supported codec_tags, terminated by FF_CODEC_TAGS_END.*/const uint32_t *codec_tags;
} FFCodec;
相关文章:
[ffmpeg] find 编码器
背景 整理 ffmpeg 中,如何通过名字或者 id 找到对应编码器的。 具体流程 搜索函数 avcodec_find_encoder // 通过 ID 搜索编码器 avcodec_find_encoder_by_name // 通过名字搜索编码器源码分析 ffmpeg 中所有支持的编码器都会注册到 codec_list.c 文件中&…...
Android CardView基础使用
目录 一、CardView 1.1 导入material库 1.2 属性 二、使用(效果) 2.1 圆角卡片效果 2.2 阴影卡片效果 2.3 背景 2.3.1 设置卡片背景(app:cardBackgroundColor) 2.3.2 内嵌布局,给布局设置背景色 2.4 进阶版 2.4.1 带透明度 2.4.2 无透明度 一、CardView 顾名…...
云原生Kubernetes系列 | init container初始化容器的作用
云原生Kubernetes系列 | init container初始化容器的作用 kubernetes 1.3版本引入了init container初始化容器特性。主要用于在启动应用容器(app container)前来启动一个或多个初始化容器,作为应用容器的一个基础。只有init container运行正常后,app container才会正常运行…...
汽车电子芯片介绍之Aurix TC系列
Infineon的AURIX TC系列芯片是专为汽车电子系统设计的,采用了32位TriCore处理器架构。该系列芯片具有高性能、低功耗和丰富的外设接口,适用于广泛的汽车电子应用。以下是AURIX TC系列芯片的主要特性: 1. 高性能处理器 AURIX TC芯片采用了高…...
Linux 设置程序开机自启动的方法
目录 前言开机自启动参考 前言 CentOS Linux release 7.9.2009 (Core) 开机自启动 shell> vim /etc/rc.d/rc.local添加开机后执行的命令 sh /xxx/xxx.sh参考 https://www.cnblogs.com/xlmeng1988/archive/2013/05/22/3092447.html...
java企业财务管理系统springboot+jsp
1、基本内容 (1)搭建基础环境,下载JDK、开发工具eclipse/idea。 (2)通过HTML/CSS/JS搭建前端框架。 (3)下载MySql数据库,设计数据库表,用于存储系统数据。 (4…...
【Windows】如何实现 Windows 上面的C盘默认文件夹的完美迁移
如何实现 Windows 上面的C盘默认文件夹的完美迁移 1. 遇到的问题 在我想迁移C盘的 下载 和 视频 文件夹的时候,遇到了这样的问题,在迁移之后,我显卡录像的视频还是保存到了C盘默认位置里,以及我迁移了 下载 之后下载的盘依然是在…...
kubernetes七层负载Ingress搭建(K8S1.23.5)
首先附上K8S版本及Ingress版本对照 Ingress介绍 NotePort:该方式的缺点是会占用很多集群机器的端口,当集群服务变多时,这个缺点就愈发的明显(srevice变多,需要的端口就需要多) LoadBalancer:该方式的缺点是每个servi…...
二维粒子群算法航线规划
GitHub - gabrielegilardi/PathPlanning: Implementation of particle swarm optimization (PSO) for path planning when the environment is known....
uniapp长按图片识别二维码
引用:https://blog.csdn.net/weixin_48596030/article/details/125405779 <image :src"url" mode"widthFix" click.self"previewImage" show-menu-by-longpress"true" style"width: 350rpx;"></image…...
智能优化算法应用:基于和声算法无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于和声算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于和声算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.和声算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…...
Gitee拉取代码报错You hasn‘t joined this enterprise! fatal unable to access
文章目录 一、问题二、解决2.1、进入**控制面板**2.2、进入**用户账户**2.3、进入**管理Windows凭据**2.4、**普通凭据**2.4.1、添加2.4.2、编辑 2.5、重新拉取|推送代码 三、最后 一、问题 Gitee拉取仓库代码的时候报错You hasnt joined this enterprise! fatal unable to ac…...
算法通关村第十六关-白银挑战滑动窗口经典题目
大家好我是苏麟 , 今天带来滑动窗口经典的一些题目 . 我们继续来研究一些热门的、高频的滑动窗口问题 大纲 最长子串专题无重复字符的最长子串 长度最小的子数组盛最多水的容器 最长子串专题 无重复字符的最长子串 描述 : 给定一个字符串 s ,请你找出其中不含有重…...
springBoot整合task
springBoot整合task 文章目录 springBoot整合task开开关设置任务,并设置执行周期定时任务的相关配置 开开关 设置任务,并设置执行周期 Component public class MyBean {Scheduled(cron "0/1 * * * * ?")public void print(){System.out.prin…...
逻辑漏洞测试靶场实验
任务一: 突破功能限制漏洞,要求突破查询按钮disabled限制,获取编号:110010的查询内容(弹框中的flag) 任务二:用户信息泄露漏洞,通过回显信息,以暴力破解法方式猜测系统中…...
【电机控制】PMSM无感foc控制(六)相电流检测及重构 — 双电阻采样、三电阻采样
0. 前言 目前,永磁同步电机的电流信号采样方法应用较多的是分流电阻采样,包括单电阻、双电阻以及三电阻采样法。其中,单电阻采样上一章节已经讲解,这章讲双电阻以及三电阻电流采样法。 1. 双电阻采样 1.1 双电阻采样原理 双电阻采…...
Boost:多进程间消息队列通信
Boost封装了消息队列,以便于多进程间传递消息: 1.创建消息队列: #include <boost/interprocess/ipc/message_queue.hpp> message_queue mq (create_only/open_only/create_or_open ,"message_queue" //消息队列的名字 ,100 …...
ELK配置记录
1. filebeat.yml配置 启动命令: ./filebeat -e -c filebeat.yml # 输入 filebeat.inputs: - type: logenabled: truepaths:- /soft/log/base.*#跨行日志正则,从有时间的开始,到下一个时间之前结束multiline.pattern: ^\[[0-9]{4}-[0-9]{2}…...
EtherCAT主站SOEM -- 7 -- SOEM之ethercatmain.h/c文件解析
EtherCAT主站SOEM -- 7 -- SOEM之ethercatmain.h/c文件解析 一 ethercatmain.h/c文件功能预览:1.1 ethercatmain里面的结构体1.2 ethercatmain里面的函数二 ethercatmain.h/c 文件的主要函数的作用:2.1 结构体介绍2.1.1 `ec_adaptert` 结构体:2.1.2 `ec_fmmut` 结构体:2.1.3 …...
Linux下Python调用C语言
一:Python调用C语言场景 1,已经写好的C语言代码,不容易用Python实现,想直接通过Python调用写好的C语言代码 2,C比Python快(只是从语言层面,不能绝对说C程序就是比Python快) 3&…...
Source Han Serif CN:7款免费开源字体如何重塑你的中文排版体验
Source Han Serif CN:7款免费开源字体如何重塑你的中文排版体验 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 在数字内容爆炸的时代,选择一款优秀的中文字体往…...
浏览器扩展开发实战:光标交互防火墙的设计与实现
1. 项目概述与核心价值最近在折腾浏览器插件开发,偶然在GitHub上看到了一个名为“Raidu Firewall Cursor Extension”的项目。光看这个名字,就让我这个对网络安全和效率工具都感兴趣的老码农眼前一亮。这玩意儿本质上是一个浏览器扩展,但它把…...
项目烂尾的魔咒:为什么你的物联网系统总是“上线即落后”?
在物联网行业有一个令人沮丧的“3-6-12”现象:3个月调研,6个月开发,12个月后项目烂尾或重构。 为什么投入巨资打造的智慧园区或工业互联系统,往往在验收通过的那一刻,就已经开始走向僵化?问题往往不出在硬…...
掌握CRC32校验码:从基础计算到高级逆向操作的完整指南
掌握CRC32校验码:从基础计算到高级逆向操作的完整指南 【免费下载链接】crc32 CRC32 tools: reverse, undo/rewind, and calculate hashes 项目地址: https://gitcode.com/gh_mirrors/cr/crc32 你是否曾遇到过需要验证文件完整性,却不知道如何下手…...
鲲鹏超节点系统应用创新竞争力
鲲鹏超节点通过灵衢互联,打破传统的服务器边界,实现以数据为中心的全互联架构,为AI infra而生,具备大带宽、低时延、统一编址、内存语义、内存借用、内存共享、对等互联等关键能力,灵衢软件全面开源开放,让…...
STM32CubeMX+STM32CubeIDE:STM32G030F6P6TR的免费开发生态入门
STM32G030F6P6TR:超值型Cortex-M0 MCU如何以最小封装实现64MHz性能突破在嵌入式系统设计中,“性价比”往往意味着在某些关键指标上的妥协——更小的封装通常伴随更低的主频或更少的外设。然而,STM32G0系列的推出打破了这一行业惯例。STM32G03…...
别再只刷Demo了!手把手教你用CCS给AWR1843毫米波雷达写自己的‘大脑’
从Demo玩家到雷达开发者:AWR1843毫米波雷达CCS深度开发实战 毫米波雷达技术正在智能驾驶、工业检测等领域掀起革命浪潮。作为TI明星产品,AWR1843凭借其高性价比和丰富功能成为众多开发者的首选。但大多数用户止步于运行官方Demo,未能真正释放…...
医疗影像分割新范式:MedSAM让医学AI触手可及
医疗影像分割新范式:MedSAM让医学AI触手可及 【免费下载链接】MedSAM Segment Anything in Medical Images 项目地址: https://gitcode.com/gh_mirrors/me/MedSAM 在医疗影像分析领域,精确的器官和病变分割一直是临床诊断和手术规划的核心挑战。传…...
避坑指南:组态王7.5报表脚本中那些容易出错的细节(日报月报年报)
组态王7.5报表脚本深度排错手册:从日报到年报的实战避坑指南 在工业自动化系统中,数据报表的准确性和稳定性直接关系到生产管理的可靠性。组态王7.5作为广泛使用的SCADA软件,其报表功能在实际应用中却常常因为脚本细节问题导致数据异常、文件…...
3分钟解决Windows软件运行问题:Visual C++运行库合集完全指南
3分钟解决Windows软件运行问题:Visual C运行库合集完全指南 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否经常遇到"缺少msvcp140.dll&q…...
