FFmpeg5.0源码阅读——av_interleaved_write_frame

chatgpt/2023/9/26 14:13:26

  摘要:本文主要详细描述FFmpeg中封装时写packet到媒体文件的函数av_interleaved_write_frame的实现。
  关键字av_interleaved_write_frame
  读者须知:读者需要熟悉ffmpeg的基本使用。

1 基本调用流程

  av_interleaved_write_frame的基本调用流程图如下。
在这里插入图片描述

  首先就是根据输入数据是否为空选择调用的函数,如果为空就会调用interleaved_write_packet刷新数据,否则调用write_packets_common写数据。
  write_packets_common中,check_packet检查输入的数据和期望写入的媒体流是否能够对上。prepare_input_packet对输入数据进行修正,如果pts和dts其中之一为NOPTS则设置为对方的值,以及如果设置了is_intra_only则每一帧都会设置标志位AV_PKT_FLAG_KEY。而check_bitstream就是调用s->oformat->check_bitstream检查流是否符合对应的格式。最后才是调用write_packet_common进行写数据。如果有设置filter的话就调用write_packets_from_bsfs处理。

  write_packet_common会根据输入的参数是否需要交织存储来调用具体的函数写packet。非交织的情况下就会调用write_packet,该函数内部实际调用的s->oformat->write_packets->oformat->write_uncoded_frame写文件,后者处理裸流。
  interleaved_write_packet内,如果AVOuputFormat设置了对应的函数指针则直接调用s->oformat->interleave_packet写文件,否则就用FFmpeg提供的ff_interleave_packet_per_dts。我们重点看下这个函数实现。

2 ff_interleave_packet_per_dts

  音视频交织就是,将音频数据和视频数据存储到文件时,按照几帧音频几帧视频的方式存储,这样在处理流数据时就不会发生频繁的seek导致一些性能问题。音视频交织的视频对于网络播放也比较友好。
在这里插入图片描述

  ff_interleave_packet_per_dts只是针对当前的两个流的packet的时间戳进行比较避免在文件存储过程中距离太远导致解封转时要频繁seek文件。最终封装文件写入到磁盘还是需要write_packet。该函数首先将送入的pkt插入到缓存队列中,然后在从当前缓存队列中选出一帧返回调用write_packet进行写入。
  在看ff_interleave_add_packet函数的实现之前,我们先简单看下帧比较函数interleave_compare_dts的实现,该函数用来比较两个packet的dts。如果非音频流就是调用的av_compare_ts进行比较,否则会根据当前音频流是否有preload去除preload的偏移:

int preload  = st ->codecpar->codec_type == AVMEDIA_TYPE_AUDIO;
int preload2 = st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO;
if (preload != preload2) {int64_t ts, ts2;preload  *= s->audio_preload;preload2 *= s->audio_preload;//preload不同时需要减掉preload的偏移ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - preload;ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - preload2;if (ts == ts2) {ts  = ((uint64_t)pkt ->dts*st ->time_base.num*AV_TIME_BASE - (uint64_t)preload *st ->time_base.den)*st2->time_base.den- ((uint64_t)next->dts*st2->time_base.num*AV_TIME_BASE - (uint64_t)preload2*st2->time_base.den)*st ->time_base.den;ts2 = 0;}comp = (ts2 > ts) - (ts2 < ts);
}

  重点就是下面的代码,从当前buffer中找到当前帧的插入位置然后插入到packet的链表中。

if (st->internal->last_in_packet_buffer) {next_point = &(st->internal->last_in_packet_buffer->next);
} else {next_point = &s->internal->packet_buffer;
}
//省略部分代码.......
if (*next_point) {if (chunked && !(pkt->flags & CHUNK_START))goto next_non_null;if (compare(s, &s->internal->packet_buffer_end->pkt, pkt)) {while (   *next_point&& ((chunked && !((*next_point)->pkt.flags&CHUNK_START))|| !compare(s, &(*next_point)->pkt, pkt)))next_point = &(*next_point)->next;if (*next_point)goto next_non_null;} else {next_point = &(s->internal->packet_buffer_end->next);}
}

  插入成功后回到ff_interleave_packet_per_dts中,从当前的packet链表的头结点拿到一阵返回给write_packet写入。

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

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

IT服务管理学习笔记<一>

### IT服务管理知识整理 ITSM 的核心思想是&#xff0c;IT 组织&#xff0c;不管它是企业内部的还是外部的&#xff0c;都是 IT 服务提供者&#xff0c;其 主要工作就是提供低成本、高质量的 IT 服务。 ITSM 的核心思想是&#xff0c;IT 组织&#xff0c;不管它是企业内部的还…

leetCode刷题记录3-面试经典150题

文章目录 不要摆&#xff0c;没事干就刷题&#xff0c;只有好处&#xff0c;没有坏处&#xff0c;实在不行&#xff0c;看看竞赛题面试经典 150 题80. 删除有序数组中的重复项 II189. 轮转数组122. 买卖股票的最佳时机 II 不要摆&#xff0c;没事干就刷题&#xff0c;只有好处&…

【学习笔记】[集训队互测 2018] 完美的队列

有点难&#x1f605; 考虑暴力做法的本质&#x1f914; 发现瓶颈在于找到所有的作用区间&#xff0c;观察性质发现作用的区间和之前队列中有多少元素是无关的 用分块优化之&#xff08;类似于 大步小步&#xff09;&#xff0c;可以做到 O ( n n log ⁡ n ) O(n\sqrt{n}\log…

27 用linprog、fmincon求 解线性规划问题(matlab程序)

1.简述 ① linprog函数&#xff1a; 求解线性规划问题&#xff0c;求目标函数的最小值&#xff0c; [x,y] linprog(c,A,b,Aeq,beq,lb,ub) 求最大值时&#xff0c;c加上负号&#xff1a;-c ② intlinprog函数&#xff1a; 求解混合整数线性规划问题&#xff0c; [x,y] intl…

剑指 Offer 38. 字符串的排列 / LeetCode 47. 全排列 II(回溯法)

题目&#xff1a; 链接&#xff1a;剑指 Offer 38. 字符串的排列 难度&#xff1a;中等 输入一个字符串&#xff0c;打印出该字符串中字符的所有排列。 你可以以任意顺序返回这个字符串数组&#xff0c;但里面不能有重复元素。 示例: 输入&#xff1a;s “abc” 输出&…

主成分分析PCA算法

Principal Components Analysis 这个协方差矩阵是一个nXn的&#xff0c;且是对称矩阵&#xff0c;就会有n个特征值λ和特征向量v&#xff0c;每个特征向量也是n维的。第一行特征向量v对应特征值λ1 。 D(yk)&#xff1a;表示主成分yk的方差。方差越大&#xff0c;说明携带的信…

python collections 中的 ChainMap 类

ChainMap chainMap 属于Python collections 模块下的一个子类&#xff0c;作用是将多个字典&#xff0c;组织成一个字典。当查询时&#xff0c;会按照构造时传入的字典的顺序进行查询。它比使用这些字典创建一个新字典要快。 简单示例 # 导入ChainMap模块 from collections …

ODIN_1靶机详解

ODIN_1靶机复盘 下载地址&#xff1a;https: //download.vulnhub.com/odin/odin.ova 靶场很简单&#xff0c;一会儿就打完了。 靶场说明里提醒说加一个dns解析。 我们在/etc/hosts加一条解析 就能正常打开网站了&#xff0c;要么网站打开css是乱的。 这里看到结尾就猜测肯定…
推荐文章