avformat_seek_file函数介绍
在做音视频数据分析的时候,经常会遇到这样的需求,每隔5分钟抽取一帧数据进行分析。
在做播放器开发的时候,也会遇到这种情况,就是拖动进度条跳转到某个位置进行播放。
如果直接用 av_read_frame()
不断读数据,读到第 5 分钟的 AVPacket
才开始处理,其他读出来的 AVPacket
丢弃,这样做会带来非常大的磁盘IO。
其实上面两种场景,都可以用同一个函数解决,那就是 avformat_seek_file()
,这个函数类似于 Linux
的 lseek()
,设置文件的读取位置。
只不过 avformat_seek_file()
是用于音视频文件的。
avformat_seek_file()
函数的定义如下:
int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
参数解释如下:
1,AVFormatContext *s
,已经打开的容器示例。
2,int stream_index
,流索引,但是只有在 flags
包含 AVSEEK_FLAG_FRAME
的时候才是 设置某个流的读取位置。其他情况都只是把这个流的 time_base (时间基)作为参考。
3,int64_t min_ts
,跳转到的最小的时间,但是这个变量不一定是时间单位,也有可能是字节单位,也可能是帧数单位(第几帧)。
4,int64_t ts
,要跳转到的读取位置,单位同上。
5,int64_t max_ts
,跳转到的最大的时间,单位同上,通常填 INT64_MAX
即可。
6,int flags
,跳转的方式,有 4 个 flags
,如下:
AVSEEK_FLAG_BYTE
,按字节大小进行跳转。AVSEEK_FLAG_FRAME
,按帧数大小进行跳转。AVSEEK_FLAG_ANY
,可以跳转到非关键帧的读取位置,但是解码会出现马赛克。AVSEEK_FLAG_BACKWARD
,往ts
的后面找关键帧,默认是往ts
的前面找关键帧。
avformat_seek_file()
函数默认是把文件的读取位置,设置到离 ts
参数最近的关键帧的地方。
而且默认情况,是容器里面所有流的读取位置都会被设置,包括 音频流,视频流,字幕流。
只要流的 discard
属性小于 AVDISCARD_ALL
就会被设置。
AVStream.discard < AVDISCARD_ALL
min_ts
跟 max_ts
变量有一些设置的技巧。
如果是快进的时候,min_ts
可以设置得比 当前位置 大一点,例如加 2。 而 max_ts
可以填 INT64_MAX
min_ts = 当前位置 + 2
max_ts = INT64_MAX
+2
是为了防止某些情况,avformat_seek_file()
会把读取位置往后挪一点。
如果是后退的时候,min_ts
可以填 INT64_MIN,max_ts
可以设置得比 当前位置 小一点,例如减 2。
min_ts = INT64_MIN
max_ts = 当前位置 - 2
-2
是为了防止某些情况,avformat_seek_file()
会把读取位置往前挪一点。
当 flags
为 0 的时候,默认情况,是按时间来 seek
的,而时间基是根据 stream_index
来确定的。
如果 stream_index
为 -1
,那 ts
的时间基就是 AV_TIME_BASE
,
如果stream_index
不等于 -1
,那 ts
的时间基就是 stream_index
对应的流的时间基。
这种情况,avformat_seek_file()
会导致容器里面所有流的读取位置都发生跳转,包括音频流,视频流,字幕流。
当 flags
包含 AVSEEK_FLAG_BYTE
,ts
参数就是字节大小,代表 avformat_seek_file()
会把读取位置设置到第几个字节。用 av_read_frame()
读出来的 pkt
里面有一个字段 pos
,代表当前读取的字节位置。可以用pkt->pos
辅助设置 ts
参数,
AVSEEK_FLAG_BYTE
是否是对所有流都生效,我后面测试一下再补充。
当 flags
包含 AVSEEK_FLAG_FRAME
,ts
参数就是帧数大小,代表 avformat_seek_file()
会把读取位置设置到第几帧。这时候 stream_index
可以指定只设置某个流的读取位置,如果 stream_index
为 -1
,代表设置所有的流。
当 flags
包含 AVSEEK_FLAG_ANY
,那就代表 seek
可以跳转到非关键帧的位置,但是非关键帧解码会出现马赛克。如果不设置 AVSEEK_FLAG_ANY
, 默认是跳转到离 ts
最近的关键帧的位置的。
当 flags
包含 AVSEEK_FLAG_BACKWARD
,代表 avformat_seek_file()
在查找里 ts
最近的关键帧的时候,会往 ts
的后面找,默认是往 ts
的前面找关键帧。
提醒:AVSEEK_FLAG_BYTE
,AVSEEK_FLAG_FRAME
,AVSEEK_FLAG_ANY
这 3 种方式,有些封装格式是不支持的。
下面通过一个例子来演示 avformat_seek_file()
函数的用法。代码下载地址:GitHb,编译环境是 Qt 5.15.2 跟 MSVC2019_64bit 。
运行结果如下:
可以看到,跳转之后,后面 av_read_frame()
读取到的 AVPacket
的 pts
跟 pos
都有很大的偏移了。
avformat_seek_file()
函数介绍完毕。
扩展知识:avformat_seek_file()
对应的旧版函数是 av_seek_frame()
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:
Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习
avformat_seek_file函数介绍相关推荐
- python3 转码的函数_python基础3之文件操作、字符编码解码、函数介绍
内容概要: 一.文件操作 二.字符编码解码 三.函数介绍 一.文件操作 文件操作流程: 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 基本操作: 1 #/usr/bin/e ...
- C语言中的scanf()函数介绍
1.scanf函数:读取从键盘输入的数据 在C语言中,有多个函数可以从键盘获得用户输入: scanf():和 printf() 类似,scanf() 可以输入多种类型的数据 getchar().get ...
- 延时函数介绍和呼吸灯的实现
文章目录 延时函数介绍 呼吸灯原理 杨桃32学习笔记,本文图片文字皆为转述 延时函数介绍 分为delay_s秒,delay_ms毫秒,delay_us微秒延时,最大参数不能超过65535. 呼吸灯原理 ...
- ×××S 2012 参照函数 -- 介绍
×××S 2012 参照函数 -- 介绍 在×××S中,一张报表内可以同时包含多个数据集,但是一个数据区域就仅限于一个数据集,如果希望同时参考多个数据集,查找函数就能轻松办到,其概念类似JOIN是通过 ...
- 【 MATLAB 】rem 函数介绍
rem函数和mod函数很相似,二者认真看一个,另一个看一下区别即可. mod函数介绍:[ MATLAB ]mod 函数介绍 rem Remainder after division Syntax r ...
- 【 MATLAB 】filter 函数介绍 之 Filter Data in Sections
[ MATLAB ]filter 函数介绍(一维数字滤波器) 在上篇博文中,里面有一个例子,就是过滤部分中的数据,这个部分中的数据的意思是如果有一个向量需要过滤,我们可以把它分为几段,然后分段过滤. ...
- swift1.2语言函数和闭包函数介绍
swift1.2语言函数和闭包函数介绍 在编程中,随着处理问题的越来越复杂,代码量飞速增加.其中,大量的代码往往相互重复或者近似重复.如果不采有效方式加以解决,代码将很难维护. swift1.2语言函 ...
- php函数介绍,PHP函数介绍_PHP教程
PHP函数介绍 基本使用: 函数定义形式: function 函数名(形参1,形参2,...) { //函数体(代码块): } 函数调用形式: 本质上就是使用一个名字来达到执行其中函数中的的作用.通常 ...
- Json模块dumps、loads、dump、load函数介绍
转自:http://blog.csdn.net/mr_evanchen/article/details/77879967 Json模块dumps.loads.dump.load函数介绍 1.json. ...
- Numpy中np.mashgri() 函数介绍及2种应用场景
@[toc](Numpy中np.mashgri() 函数介绍及2种应用场景 文章目录:) 近期在好几个地方都看到meshgrid的使用,虽然之前也注意到meshgrid的用法. 但总觉得印象不深刻,不 ...
最新文章
- html 文字倒映效果,HTML图片CSS滤镜—倒影效果
- 洛谷.4252.[NOI2006]聪明的导游(提答 直径 随机化)
- 有点贵但卖光了!这款旗舰要火了吗...
- 从某软件引发的深思总结
- 手机怎么安装py thon_Python属性装饰器– Py​​thon @property
- [Ubuntu] change mouse scrolling between standard and natural
- Unity渐进式GPU烘焙找不到显卡
- nginx代理服务器
- 天正暖通2013版安装包附带注册机下载
- Something's wrong--perhaps a missing \item. \end{thebibliography}
- 减去百分之二是怎么用计算机算,百分比换算公式(常见的百分率计算公式)
- 去哪下载python项目_Python 项目实践二(下载数据)第三篇
- VIO_FUSION
- 详解EBS接口开发之采购订单导入(转载)
- java ftp 被动模式_ftp 主动模式与被动模式
- JavaScript直接通过id获取对象
- android 游戏内存,如何「偷」Android 的内存?
- 分布式搜索引擎的研究
- 07 工程结构及依赖关系
- Java程序员面试常见面试题,你了解多少?初步整理简化版