当前位置: 首页 > news >正文

【FFmpeg】avformat_alloc_output_context2函数

【FFmpeg】avformat_alloc_output_context2函数

  • 1.avformat_alloc_output_context2
    • 1.1 初始化AVFormatContext(avformat_alloc_context)
    • 1.2 格式猜测(av_guess_format)
      • 1.2.1 遍历可用的fmt(av_muxer_iterate)
      • 1.2.2 name匹配检查(av_match_name)
      • 1.2.3 扩展匹配检查(av_match_ext)
  • 2.小结

参考:
FFmpeg源代码简单分析:avformat_alloc_output_context2()

示例工程:
【FFmpeg】调用ffmpeg库实现264软编
【FFmpeg】调用ffmpeg库实现264软解
【FFmpeg】调用ffmpeg库进行RTMP推流和拉流
【FFmpeg】调用ffmpeg库进行SDL2解码后渲染

流程分析:
【FFmpeg】编码链路上主要函数的简单分析
【FFmpeg】解码链路上主要函数的简单分析

结构体分析:
【FFmpeg】AVCodec结构体
【FFmpeg】AVCodecContext结构体
【FFmpeg】AVStream结构体
【FFmpeg】AVFormatContext结构体
【FFmpeg】AVIOContext结构体
【FFmpeg】AVPacket结构体

函数分析:
【FFmpeg】avformat_open_input函数
【FFmpeg】avformat_find_stream_info函数

avformat_alloc_output_context2内函数调用关系如下
在这里插入图片描述

1.avformat_alloc_output_context2

函数的主要功能是分配一个输出的context,利用输入的format和filename来确定output format,主要工作流程为:
(1)初始化AVFormatContext(avformat_alloc_context)
(2)如果没有指定输出format,需要根据输入信息来猜测一个format(av_guess_format)
(3)根据输出的format,来对AVFormatContext中的priv_data初始化

int avformat_alloc_output_context2(AVFormatContext **avctx, const AVOutputFormat *oformat,const char *format, const char *filename)
{AVFormatContext *s = avformat_alloc_context();int ret = 0;*avctx = NULL;if (!s)goto nomem;// 没有指定输出formatif (!oformat) {// 但是指定了格式名称,例如rtp,flv,udp等,则进行输出format的猜测if (format) {oformat = av_guess_format(format, NULL, NULL);if (!oformat) {av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not known.\n", format);ret = AVERROR(EINVAL);goto error;}} else {	// 也没有指定格式名称,使用filename进行输出format的猜测oformat = av_guess_format(NULL, filename, NULL);if (!oformat) {ret = AVERROR(EINVAL);av_log(s, AV_LOG_ERROR,"Unable to choose an output format for '%s'; ""use a standard extension for the filename or specify ""the format manually.\n", filename);goto error;}}}// 根据确定的输出format,对AVFormatContext中priv_data信息进行初始化s->oformat = oformat;if (ffofmt(s->oformat)->priv_data_size > 0) {s->priv_data = av_mallocz(ffofmt(s->oformat)->priv_data_size);if (!s->priv_data)goto nomem;if (s->oformat->priv_class) {*(const AVClass**)s->priv_data= s->oformat->priv_class;av_opt_set_defaults(s->priv_data);}} elses->priv_data = NULL;if (filename) {if (!(s->url = av_strdup(filename)))goto nomem;}*avctx = s;return 0;
nomem:av_log(s, AV_LOG_ERROR, "Out of memory\n");ret = AVERROR(ENOMEM);
error:avformat_free_context(s);return ret;
}

1.1 初始化AVFormatContext(avformat_alloc_context)

函数用于初始化AVFormatContext结构体

AVFormatContext *avformat_alloc_context(void)
{FFFormatContext *const si = av_mallocz(sizeof(*si));AVFormatContext *s;if (!si)return NULL;s = &si->pub;// 初始化函数指针s->av_class = &av_format_context_class;s->io_open  = io_open_default;s->io_close2= io_close2_default;av_opt_set_defaults(s);// 分配packet的空间si->pkt = av_packet_alloc();si->parse_pkt = av_packet_alloc();if (!si->pkt || !si->parse_pkt) {avformat_free_context(s);return NULL;}#if FF_API_LAVF_SHORTESTsi->shortest_end = AV_NOPTS_VALUE;
#endifreturn s;
}

1.2 格式猜测(av_guess_format)

该函数用于猜测一个format,类型为AVOutputFormat,

const AVOutputFormat *av_guess_format(const char *short_name, const char *filename,const char *mime_type)
{const AVOutputFormat *fmt = NULL;const AVOutputFormat *fmt_found = NULL;void *i = 0;int score_max, score;/* specific test for image sequences */// 用于图像序列的特定测试
#if CONFIG_IMAGE2_MUXERif (!short_name && filename &&av_filename_number_test(filename) &&ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) {return av_guess_format("image2", NULL, NULL);}
#endif/* Find the proper file type. */// 寻找合适的文件类型score_max = 0;// 遍历每个可用的fmtwhile ((fmt = av_muxer_iterate(&i))) {score = 0;// 如果当前封装格式匹配,则置信度增加100if (fmt->name && short_name && av_match_name(short_name, fmt->name))score += 100;// 如果fmt的mime类型与mime_type匹配,则置信度增加10if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))score += 10;if (filename && fmt->extensions &&av_match_ext(filename, fmt->extensions)) {// 如果扩展名匹配,则置信度增加5score += 5;}if (score > score_max) {score_max = score;fmt_found = fmt;}}return fmt_found;
}

其中,fmt中name、mime_type和extension的定义如下(以FLV格式为例)。在新版本FFmpeg中,FLV级别封装的格式不再是AVOutputFormat而是FFOutputFormat,但是FFOutputFormat之中的信息可以转换成AVOutputFormat,下面的.p就是AVOutputFormat的指针。对于FLV格式而言,name=“flv”,mime_type=“video/x-flv”,extensions=“flv”

const FFOutputFormat ff_flv_muxer = {.p.name         = "flv",.p.long_name    = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),.p.mime_type    = "video/x-flv",.p.extensions   = "flv",.priv_data_size = sizeof(FLVContext),.p.audio_codec  = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_ADPCM_SWF,.p.video_codec  = AV_CODEC_ID_FLV1,.init           = flv_init,.write_header   = flv_write_header,.write_packet   = flv_write_packet,.write_trailer  = flv_write_trailer,.deinit         = flv_deinit,.check_bitstream= flv_check_bitstream,.p.codec_tag    = (const AVCodecTag* const []) {flv_video_codec_ids, flv_audio_codec_ids, 0},.p.flags        = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |AVFMT_TS_NONSTRICT,.p.priv_class   = &flv_muxer_class,
};

1.2.1 遍历可用的fmt(av_muxer_iterate)

const AVOutputFormat *av_muxer_iterate(void **opaque)
{static const uintptr_t size = sizeof(muxer_list)/sizeof(muxer_list[0]) - 1;uintptr_t i = (uintptr_t)*opaque;const FFOutputFormat *f = NULL;uintptr_t tmp;// 从muxer的list中获取一个fmt,list当中有180个muxerif (i < size) {f = muxer_list[i];} else if (tmp = atomic_load_explicit(&outdev_list_intptr, memory_order_relaxed)) {const FFOutputFormat *const *outdev_list = (const FFOutputFormat *const *)tmp;f = outdev_list[i - size];}// 如果找到了fmt,i = i + 1if (f) {*opaque = (void*)(i + 1);return &f->p;}return NULL;
}

1.2.2 name匹配检查(av_match_name)

/*** Match instances of a name in a comma-separated list of names.* List entries are checked from the start to the end of the names list,* the first match ends further processing. If an entry prefixed with '-'* matches, then 0 is returned. The "ALL" list entry is considered to* match all names.** @param name  Name to look for.* @param names List of names.* @return 1 on match, 0 otherwise.*/
// 在逗号分隔的名称列表中匹配名称的实例(字符串匹配)
// 从名字列表的开始到结束检查列表条目,第一个匹配结束进一步处理。
//		如果匹配前缀为'-'的条目,则返回0。“ALL”列表项被认为匹配所有名称
int av_match_name(const char *name, const char *names)
{const char *p;size_t len, namelen;if (!name || !names)return 0;namelen = strlen(name);while (*names) {int negate = '-' == *names;p = strchr(names, ','); // 因为有多个,分隔的字号if (!p)p = names + strlen(names);names += negate;len = FFMAX(p - names, namelen);if (!av_strncasecmp(name, names, len) || !strncmp("ALL", names, FFMAX(3, p - names)))return !negate;names = p + (*p == ',');}return 0;
}

1.2.3 扩展匹配检查(av_match_ext)

函数会提取出扩展名,然后调用av_match_name进行扩展名的匹配

/*** @file* Format register and lookup*/int av_match_ext(const char *filename, const char *extensions)
{const char *ext;if (!filename)return 0;ext = strrchr(filename, '.');if (ext)return av_match_name(ext + 1, extensions);return 0;
}

2.小结

avformat_alloc_output_context2函数是FFmpeg使用过程中重要的函数,它创建了输出的AVFormatContext,能够用于数据的输出,需要注意的是,新版本的FFmpeg中对上层格式的封装不再使用AVOutputFormat而是使用FFOutputFormat,将AVOutputFormat封装到了FFOutputFormat之中

CSDN : https://blog.csdn.net/weixin_42877471
Github : https://github.com/DoFulangChen

相关文章:

【FFmpeg】avformat_alloc_output_context2函数

【FFmpeg】avformat_alloc_output_context2函数 1.avformat_alloc_output_context21.1 初始化AVFormatContext&#xff08;avformat_alloc_context&#xff09;1.2 格式猜测&#xff08;av_guess_format&#xff09;1.2.1 遍历可用的fmt&#xff08;av_muxer_iterate&#xff0…...

Flask 缓存和信号

Flask-Caching Flask-Caching 是 Flask 的一个扩展&#xff0c;它为 Flask 应用提供了缓存支持。缓存是一种优化技术&#xff0c;可以存储那些费时且不经常改变的运算结果&#xff0c;从而加快应用的响应速度。 一、初始化配置 安装 Flask-Caching 扩展&#xff1a; pip3 i…...

基于weixin小程序农场驿站系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;农场资讯管理&#xff0c;用户管理&#xff0c;卖家管理&#xff0c;用户分享管理&#xff0c;分享类型管理&#xff0c;商品信息管理&#xff0c;商品类型管理 开发系统&#xff1a;Windows 架构模式…...

JAVA将List转成Tree树形结构数据和深度优先遍历

引言&#xff1a; 在日常开发中&#xff0c;我们经常会遇到需要将数据库中返回的数据转成树形结构的数据返回&#xff0c;或者需要对转为树结构后的数据绑定层级关系再返回&#xff0c;比如需要统计当前节点下有多少个节点等&#xff0c;因此我们需要封装一个ListToTree的工具类…...

设计模式——开闭、单一职责及里氏替换原则

设计原则是指导软件设计和开发的一系列原则&#xff0c;它们帮助开发者创建出易于维护、扩展和理解的代码。以下是你提到的几个关键设计原则的简要说明&#xff1a; 开闭原则&#xff08;Open/Closed Principle, OCP&#xff09;&#xff1a; 开闭原则由Bertrand Meyer提出&am…...

代码随想录算法训练营第59天:动态[1]

代码随想录算法训练营第59天&#xff1a;动态 两个字符串的删除操作 力扣题目链接(opens new window) 给定两个单词 word1 和 word2&#xff0c;找到使得 word1 和 word2 相同所需的最小步数&#xff0c;每步可以删除任意一个字符串中的一个字符。 示例&#xff1a; 输入: …...

jvm性能监控常用工具

在java的/bin目录下有许多java自带的工具。 我们常用的有 基础工具 jar:创建和管理jar文件 java&#xff1a;java运行工具&#xff0c;用于运行class文件或jar文件 javac&#xff1a;java的编译器 javadoc&#xff1a;java的API文档生成工具 性能监控和故障处理 jps jstat…...

ISP IC/FPGA设计-第一部分-SC130GS摄像头分析-IIC通信(1)

1.摄像头模组 SC130GS通过一个引脚&#xff08;SPI_I2C_MODE&#xff09;选择使用IIC或SPI配置接口&#xff0c;通过查看摄像头模组的原理图&#xff0c;可知是使用IIC接口&#xff1b; 通过手册可知IIC设备地址通过一个引脚控制&#xff0c;查看摄像头模组的原理图&#xff…...

HTTP协议头中X-Forwarded-For是能做什么?

X-Forwarded-For和相关几个头部的理解 $remote_addr 是nginx与客户端进行TCP连接过程中&#xff0c;获得的客户端真实地址. Remote Address 无法伪造&#xff0c;因为建立 TCP 连接需要三次握手&#xff0c;如果伪造了源 IP&#xff0c;无法建立 TCP 连接&#xff0c;更不会有后…...

Linux高并发服务器开发(八)Socket和TCP

文章目录 1 IPV4套接字结构体2 TCP客户端函数 3 TCP服务器流程函数代码粘包 4 三次握手5 四次挥手6 滑动窗口 1 IPV4套接字结构体 2 TCP客户端 特点&#xff1a;出错重传 每次发送数据对方都会回ACK&#xff0c;可靠 tcp是打电话的模型&#xff0c;建立连接 使用连接 关闭连接…...

力扣第220题“存在重复元素 III”

在本篇文章中&#xff0c;我们将详细解读力扣第220题“存在重复元素 III”。通过学习本篇文章&#xff0c;读者将掌握如何使用桶排序和滑动窗口来解决这一问题&#xff0c;并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释&#xff0c;以便于理解。 问题描述…...

Qt实战项目——贪吃蛇

一、项目介绍 本项目是一个使用Qt框架开发的经典贪吃蛇游戏&#xff0c;旨在通过简单易懂的游戏机制和精美的用户界面&#xff0c;为玩家提供娱乐和编程学习的机会。 游戏展示 二、主要功能 2.1 游戏界面 游戏主要是由三个界面构成&#xff0c;分别是游戏大厅、难度选择和游戏…...

Windows 10,11 Server 2022 Install Docker-Desktop

docker 前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 docker-compose Compose 是用于定义和运行…...

C++中的RAII(资源获取即初始化)原则

C中的RAII&#xff08;Resource Acquisition Is Initialization&#xff0c;资源获取即初始化&#xff09;原则是一种管理资源、避免资源泄漏的惯用法。RAII是C之父Bjarne Stroustrup提出的设计理念&#xff0c;其核心思想是将资源的获取&#xff08;如动态内存分配、文件句柄、…...

【机器学习】Whisper:开源语音转文本(speech-to-text)大模型实战

目录 一、引言 二、Whisper 模型原理 2.1 模型架构 2.2 语音处理 2.3 文本处理 三、Whisper 模型实战 3.1 环境安装 3.2 模型下载 3.3 模型推理 3.4 完整代码 3.5 模型部署 四、总结 一、引言 上一篇对​​​​​​​ChatTTS文本转语音模型原理和实战进行了讲解&a…...

ubuntu22.04 编译安装openssl C++ library

#--------------------------------------------------------------------------- # openssl C library # https://www.openssl.org/source/index.html #--------------------------------------------------------------------------- cd /opt/download # 下载openssl-3.0.13…...

百度Agent初体验(制作步骤+感想)

现在AI Agent很火&#xff0c;最近注册了一个百度Agent体验了一下&#xff0c;并做了个小实验&#xff0c;拿它和零一万物&#xff08;Yi Large&#xff09;和文心一言&#xff08;ERNIE-4.0-8K-latest&#xff09;阅读了相同的一篇网页资讯&#xff0c;输出资讯摘要&#xff0…...

7-491 3名同学5门课程成绩,输出最好成绩及所在的行和列(二维数组作为函数的参数)

编程:数组存储3名同学5门课程成绩 输出最好成绩及所在的行和列 要求&#xff1a;将输入、查找和打印的功能编写成函数 并将二维数组通过指针参数传递的方式由主函数传递到子函数中 输入格式: 每行输入一个同学的5门课的成绩&#xff0c;每个成绩之间空一格&#xff0c;见输入…...

OpenCloudOS开源的操作系统

OpenCloudOS 是一款开源的操作系统&#xff0c;致力于提供高性能、稳定和安全的操作系统环境&#xff0c;以满足现代计算和应用程序的需求。它结合了现代操作系统设计的最新技术和实践&#xff0c;为开发者和企业提供了一个强大的平台。本文将详细介绍 OpenCloudOS 的背景、特性…...

排序题目:多数元素 II

文章目录 题目标题和出处难度题目描述要求示例数据范围进阶 前言解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 解法三思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;多数元素 II 出处&#xff1a;229. 多数元素 II 难度 3 级 题目描述 …...

终极指南:Muzic数据增强技术PDAugment如何通过音高和时长调整提升模型性能

终极指南&#xff1a;Muzic数据增强技术PDAugment如何通过音高和时长调整提升模型性能 【免费下载链接】muzic 这是一个微软研究院开发的音乐生成AI项目。适合对音乐、音频处理以及AI应用感兴趣的开发者、学生和研究者。特点是使用深度学习技术生成音乐&#xff0c;具有较高的创…...

如何高效获取Twitter社交数据:学术研究的实战指南

如何高效获取Twitter社交数据&#xff1a;学术研究的实战指南 【免费下载链接】getting-started-with-the-twitter-api-v2-for-academic-research A course on getting started with the Twitter API v2 for academic research 项目地址: https://gitcode.com/gh_mirrors/ge/…...

如何永久保存微信聊天记录?免费开源工具WeChatMsg完整指南

如何永久保存微信聊天记录&#xff1f;免费开源工具WeChatMsg完整指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/W…...

Windows性能优化:任务管理器深度使用指南

Windows性能优化&#xff1a;任务管理器深度使用指南Windows系统运行缓慢、卡顿&#xff1f;系统自带的任务管理器是诊断和解决性能瓶颈的强大工具。本文将带你深度挖掘Windows任务管理器的各项功能&#xff0c;重点介绍如何利用它进行进程管理、性能监控、启动项优化等操作&am…...

菊水PBZ40可编程电源RS232C通信协议实战指南

1. 认识菊水PBZ40可编程电源 如果你正在实验室里捣鼓自动化测试系统&#xff0c;大概率会遇到需要精确控制电源输出的场景。菊水PBZ40就是这样一款专业选手&#xff0c;它不仅能提供稳定的直流输出&#xff0c;还能模拟各种交流波形信号。我第一次接触这台设备时&#xff0c;就…...

IDC行业专家交流纪要

Q&#xff1a;字节 2026 年 IDC 招标的总需求、国内需求、当前招标进度分别是怎样的&#xff1f;此次招标呈现出怎样的特点&#xff0c;背后又有哪些原因&#xff1f;A&#xff1a;字节跳动 2026 年 IDC 招标整体规划总需求约 1.8GW&#xff0c;剔除海外需求削减的部分后&#…...

Java 25记录模式深度实战:手把手带你用模式匹配解构嵌套记录,效率提升47%(JVM实测数据)

第一章&#xff1a;Java 25记录模式的演进脉络与核心突破记录模式&#xff08;Record Patterns&#xff09;作为 Java 21 首次以预览特性引入、并在 Java 22 进一步增强、最终于 Java 25 正式成为标准特性的关键语言机制&#xff0c;标志着 Java 在模式匹配演进道路上完成从“解…...

如何借助内网穿透工具实现WinSCP跨系统远程文件管理的稳定连接

1. 为什么需要内网穿透实现WinSCP远程文件管理 作为开发者或运维人员&#xff0c;我经常需要在Windows和Linux服务器之间传输文件。最初我尝试用U盘或网盘中转&#xff0c;但效率太低&#xff1b;后来改用WinSCP直连局域网&#xff0c;又遇到跨地域办公的难题。直到发现内网穿透…...

从BiomixQA到黄帝内经:聊聊2024年那些‘小而美’的垂直医学问答数据集

2024医学垂直问答数据集全景&#xff1a;从BiomixQA到黄帝内经的实战选型指南 当ChatGPT在通用领域大放异彩时&#xff0c;医学AI的战场正悄然转向那些"小而美"的垂直数据集。不同于通用语料的粗放式训练&#xff0c;专业医学问答需要精确到细胞级的语义理解——一个…...

Cursor试用限制终极解决方案:一篇文章彻底解决你的AI编程困境

Cursor试用限制终极解决方案&#xff1a;一篇文章彻底解决你的AI编程困境 【免费下载链接】go-cursor-help 解决Cursor在免费订阅期间出现以下提示的问题: Youve reached your trial request limit. / Too many free trial accounts used on this machine. Please upgrade to p…...