【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

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

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

相关文章

C : 线性规划例题求解

Submit Page TestData Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 93 Solved: 49 Description 求解下述线性规划模型的最优值min &#xfffd;1&#xfffd;1&#xfffd;2&#xfffd;2&#xfffd;3&#xfffd;3&#xfffd;.&#xfffd;. &…

【SkiaSharp绘图13】SKCanvas方法详解(二)填充颜色、封装对象、高性能绘制、点(集)(多段)线、圆角矩形、Surface、沿路径绘制文字

文章目录 SKCanvas方法DrawColor 填充颜色DrawDrawable 绘制封装对象DrawImage 高性能绘制图像SKBitmap与SKImage对比DrawPicture 绘制图像SKPicture DrawPoint / DrawPoints 绘制点DrawRoundRect/DrawRoundRectDifference绘制圆角矩形DrawSurface 绘制SurfaceDrawTextOnPath沿…

Android - 利用 jitpack 免费发布闭源 aar

一、简述 目前(Android/java) library 的主要发布仓库有 MavenCentral 和 jitpack,我之前也对这两种仓库的发布流程做了详细介绍: 发布至 MavenCentral: https://juejin.cn/post/6953598441817636900发布至 jitpack: https://juejin.cn/post/7040733114506674183#heading-…

C# 入门—实现 Hello, World!

目录 一、.net 平台与.NET Framework框架 .NET Framework的构成 CLR&#xff1a;公共语言运行库 FCL&#xff1a;框架类库 WinForms ASP.NET ADO.NET WPF WCF WF LINQ Entity Framework Parallel LINQ 二、.net 能干什么 .net 两种交互模式 .net 能干什么 .net …

优化模型验证30:多车场车辆路径问题模型及Gurobipy验证

目录 1 数学模型 1.1 用到的符号集合 1.2 模型公式 2 模型验证代码 2.1 Gurobipy代码 2.2 结果可视化 多车场车辆路径问题的定义:大型的物流公司拥有多个车场,而每个车场都有若干车辆用于配送,决策者需要根据客户的所在位置,将客户分配到合适的车场和车辆中。 1 数学模…

c++静态成员变量和静态成员函数

1&#xff09;C入门级小知识&#xff0c;分享给将要学习或者正在学习C开发的同学。 2&#xff09;内容属于原创&#xff0c;若转载&#xff0c;请说明出处。 3&#xff09;提供相关问题有偿答疑和支持。 我们可以使用 static 关键字来把类成员定义为静态的。当我们声明类的成…

华为云鲲鹏架构docker部署2048小游戏

华为云鲲鹏架构docker部署2048小游戏 1. 鲲鹏架构ESC2. 配置docker3. 上传2048镜像4. 删除容器,镜像 1. 鲲鹏架构ESC 2. 配置docker 安装dockeryum -y install docker开机启动 systemctl enable docker启动docker服务 systemctl start docker查询docker的运行版本 docker -v3…

注意力机制之ECA-Net:Efficient Channel Attention for Deep Convolutional Neural Network

论文link&#xff1a;link code&#xff1a;code 1.摘要 近年来&#xff0c;通道注意机制被证明在改善深层卷积神经网络&#xff08;CNN&#xff09;的性能方面提供了巨大的潜力。然而现有的大多数方法都致力于开发更复杂的注意模块以获得更好的性能&#xff0c;这不可避免地增…

1.linux操作系统CPU负载

目录 概述CPU平均负载查看平均负载结束 概述 CPU 使用率 和CPU 平均使用率。 CPU平均负载 单位时间内系统处于 [可运行状态] 和 [不可中断状态] 的平均进程数&#xff0c;就是平均活跃进程数&#xff0c;和CPU使用率并没有直接关系 可运行状态 正在使用CPU或者正等待CPU的进…

从头开始构建一个小规模的文生视频模型

OpenAI 的 Sora、Stability AI 的 Stable Video Diffusion 以及许多其他已经发布或未来将出现的文本生成视频模型&#xff0c;是继大语言模型 (LLM) 之后 2024 年最流行的 AI 趋势之一。 在这篇博客中&#xff0c;作者将展示如何将从头开始构建一个小规模的文本生成视频模型&a…

C# 实现websocket双向通信

&#x1f388;个人主页&#xff1a;靓仔很忙i &#x1f4bb;B 站主页&#xff1a;&#x1f449;B站&#x1f448; &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C# &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff…

AWT的菜单组件

AWT的菜单组件 前言一、菜单组件的介绍常见的菜单相关组件常见菜单相关组件集成体系图菜单相关组件使用小要点 二、AWT菜单组件的代码示例示例一示例二实现思路 前言 推荐一个网站给想要了解或者学习人工智能知识的读者&#xff0c;这个网站里内容讲解通俗易懂且风趣幽默&…

如何使用sr2t将你的安全扫描报告转换为表格格式

关于sr2t sr2t是一款针对安全扫描报告的格式转换工具&#xff0c;全称为“Scanning reports to tabular”&#xff0c;该工具可以获取扫描工具的输出文件&#xff0c;并将文件数据转换为表格格式&#xff0c;例如CSV、XLSX或文本表格等&#xff0c;能够为广大研究人员提供一个…

MySQL详细介绍:开源关系数据库管理系统的魅力

学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把手教你开发炫酷的vbs脚本制作(完善中……&#xff09; 4、牛逼哄哄的 IDEA编程利器技巧(编写中……&#xff09; 5、面经吐血整理的 面试技…

理解GPT2:无监督学习的多任务语言模型

目录 一、背景与动机 二、卖点与创新 三、几个问题 四、具体是如何做的 1、更多、优质的数据&#xff0c;更大的模型 2、大数据量&#xff0c;大模型使得zero-shot成为可能 3、使用prompt做下游任务 五、一些资料 一、背景与动机 基于 Transformer 解码器的 GPT-1 证明…

容器技术-docker4

一、docker资源限制 在使用 docker 运行容器时&#xff0c;一台主机上可能会运行几百个容器&#xff0c;这些容器虽然互相隔离&#xff0c;但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制&#xff0c;那么容器之间会互相影响&#xff0c;小的来说…

【Spring】DAO 和 Repository 的区别

DAO 和 Repository 的区别 1.概述2.DAO 模式2.1 User2.2 UserDao2.3 UserDaoImpl 3.Repository 模式3.1 UserRepository3.2 UserRepositoryImpl 4.具有多个 DAO 的 Repository 模式4.1 Tweet4.2 TweetDao 和 TweetDaoImpl4.3 增强 User 域4.4 UserRepositoryImpl 5.比较两种模式…

【机器学习】机器学习的重要技术——生成对抗网络:理论、算法与实践

引言 生成对抗网络&#xff08;Generative Adversarial Networks, GANs&#xff09;由Ian Goodfellow等人在2014年提出&#xff0c;通过生成器和判别器两个神经网络的对抗训练&#xff0c;成功实现了高质量数据的生成。GANs在图像生成、数据增强、风格迁移等领域取得了显著成果…

详细分析Springmvc中的@ModelAttribute基本知识(附Demo)

目录 前言1. 注解用法1.1 方法参数1.2 方法1.3 类 2. 注解场景2.1 表单参数2.2 AJAX请求2.3 文件上传 3. 实战4. 总结 前言 将请求参数绑定到模型对象上&#xff0c;或者在请求处理之前添加模型属性 可以在方法参数、方法或者类上使用 一般适用这几种场景&#xff1a; 表单…

ros笔记01--初次体验ros2

ros笔记01--初次体验ros2 介绍安装ros2测试验证ros2说明 介绍 机器人操作系统(ROS)是一组用于构建机器人应用程序的软件库和工具。从驱动程序和最先进的算法到强大的开发者工具&#xff0c;ROS拥有我们下一个机器人项目所需的开源工具。 当前ros已经应用到各类机器人项目开发中…