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

news2024/9/24 6:31:15

引入

首先介绍一下基础名词

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

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

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

typedef struct AVRational{
    int num; ///< Numerator
    int 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.coloradmin.cn/o/2159687.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyBatis - 动态SQL

前言 我们在某网站填写个人信息时&#xff0c;时常会遇到可以选填的空&#xff08;即可填&#xff0c;可不填&#xff09;&#xff0c;由于之前讲过的Java中的SQL语句都是固定的&#xff0c;且我们不可能对所有情况都写出与之对应的插入语句&#xff08;太过繁琐&#xff09;&…

虚幻引擎的三种输入模式和将控件显示到屏幕上

首先要知道一个概念 , HUD 和 Input 都是由 PlayerController 来控制的 而虚幻的Input控制模式有三种 Set Input Mode Game Only (设置输入模式仅限游戏): 视角会跟着鼠标旋转 , 就是正常游戏的模式 , 这也是游戏默认输入模式 Set Input Mode UI Only (设置输入模式仅限UI): …

【操作系统强化】王道强化一轮笔记

第一章 计算机系统概述 考点1 操作系统的概念、特征和功能 1. 2. 考点2 内核态与用户态 1. 2.用户态和内核态之间的切换本质上就是应用程序和操作系统对CPU控制器的切换 考点3 中断和异常 1. 2. 考点4 系统调用 1. 2. 3.C 考点5 操作系统引导 1. 2. ①磁盘的物理格式化&…

APP自动化中 ADB Monkey用法

一、monkey是干什么的&#xff1f; 我们可以使用monkey做手机端性能的压力测试&#xff0c;稳定性测试 二、monkey在使用的时候&#xff0c;他的运行特性 monkey默认配置下执行&#xff0c;会在手机中随机的点击或者轻触我们的手机中应用&#xff0c;不过这个时候&#xff0…

在Windows系统上安装的 flatbuffers C++ 库

步骤一 下载:https://github.com/google/flatbuffers git clone gitgithub.com:google/flatbuffers.git步骤二 打开安装目录,然后再打开该目录下的powershell, 新建build目录 cd build cmake ..步骤三 进入步骤二生成的build目录里面,点击FlatBuffers.sln,打开vs2019 补充…

信息安全工程师(13)网络攻击一般过程

前言 网络攻击的一般过程是一个复杂且系统化的行为&#xff0c;其目标往往在于未经授权地访问、破坏或窃取目标系统的信息。 一、侦查与信息收集阶段 开放源情报收集&#xff1a;攻击者首先会通过搜索引擎、社交媒体、论坛等公开渠道获取目标的基本信息&#xff0c;如姓名、地址…

【经验分享】电商api接口——各类商品数据一键获取

目前&#xff0c;双十一促销活动正在火爆预热进行中。大促期间&#xff0c;消费者常常会做攻略以防被坑&#xff0c;而活动期间&#xff0c;品牌商家方也需要有所行动&#xff0c;避免一些不必要的损失。 大促期间&#xff0c;商家前前后后的改价活动往往比较频繁&#xff0c;…

超分之SPIN

Lightweight image super-resolution with superpixel token interaction[C]利用超像素token交互实现轻量级图像超分辨率Zhang A, Ren W, Liu Y, et al.Proceedings of the IEEE/CVF International Conference on Computer Vision. 2023: 12728-12737. 文章目录 摘要1. 引言2. …

【开源免费】基于SpringBoot+Vue.JS体育馆管理系统(JAVA毕业设计)

本文项目编号 T 048 &#xff0c;文末自助获取源码 \color{red}{T048&#xff0c;文末自助获取源码} T048&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…

元器件数据手册识别工具

数据手册识别方案&#xff0c;目前有多家厂商实现了这个功能&#xff0c;分别采用不同的技术路线实现。 基于AI方法&#xff1a;使用大量的数据手册进行训练&#xff0c;训练后的将模型文件提供给客户&#xff0c;用户在程序中加载模型文件和数据手册得到手册里面的数据结果。 …

Python中requests模块(爬虫)基本使用

Python的requests模块是一个非常流行的HTTP库&#xff0c;用于发送HTTP/1.1请求。 一、模块导入 1、requests模块的下载&#xff1a; 使用包管理器下载&#xff0c;在cmd窗口&#xff0c;或者在项目的虚拟环境目录下&#xff1a; pip3 install -i https://pypi.tuna.tsingh…

JUC高并发编程1:JUC概述

1 什么是JUC 1.1 JUC简介 JUC就是 java.util .concurrent 工具包的简称。这是一个处理线程的工具包&#xff0c;JDK 1.5 开始出现的。 1.2 进程与线程 进程&#xff08;Process&#xff09;和线程&#xff08;Thread&#xff09;是操作系统中用于实现多任务处理的两种基本概…

Linux 基本指令的学习

01. ls 指令 语法 &#xff1a; ls [ 选项 ][ 目录或文件 ] 功能 &#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息。 常用选项&#xff1a; -a 列出目录下的所有文件&#xff0c;包括以 . 开头的隐含…

计算机二级C语言疑难

1.strcpy函数 在C语言中strcpy&#xff08;&#xff09;函数会将字符串2&#xff08;包括字符串结束字符/0&#xff09;的函数覆盖到字符串1&#xff0c;如果字符串1没有足够的空间容纳字符串会导致缓冲溢出的错误 例题&#xff1a;程序设计 规定输入的字符串中只包含字母和…

2.Spring-容器-注入

注册&#xff1a;将组件放入容器中&#xff1b; 注入&#xff1a;让容器按需进行操作&#xff1b; 一、Autowired&#xff1a;自动注入组件 原理&#xff1a;Spring调用容器的getBean 二、Qualifier 精确指定 精确指定&#xff1a;如果容器中组件存在多个&#xff0c;则使用…

在虚幻引擎中实现Camera Shake 相机抖动/震屏效果

在虚幻引擎游戏中创建相机抖动有时能让画面更加高级 , 比如 遇到大型的Boss , 出现一些炫酷的特效 加一些短而快的 Camera Shake 能达到很好的效果 , 为玩家提供沉浸感 创建Camera Shake 调整Shake参数 到第三人称或第一人称蓝图 调用Camera Shake Radius值越大 晃动越强

Nginx基础详解1(单体部署与集群部署、负载均衡、正反代理、nginx安装)

本阶段的任务 1.学会集群的操作概念 2.完成对Nginx的入门操作 3.使用Nginx实现集群和负载均衡 4.使用Nginx实现高可用的方案 目录 1.单体部署与集群部署 1.1单体部署的概念 1.2单体部署的优缺点 1.3集群部署的概念 1.4集群部署的优缺点 1.5集群部署需要注意的点 1.…

嵌入式linux方向细分工作岗位分析

大家好,今天主要给大家分享一下,linux方向细分的工作岗位有哪些?,为即将进入linux领域的开发者指明方向。 第一:总结分布 第二:Linux BSP工程师岗位 工作内容: 1、开发和维护Linux系统的板级支持包(BSP),包括启动加载程序、设备驱动、文件系统等。 2、负责解决硬件和软…

2003-2022年各省区域创新能力评价相关指标数据(报告年份2003-2022年)

2003-2022年各省区域创新能力相关指标数据&#xff08;报告年份2003-2022年&#xff09; 1、来源&#xff1a;2003-2022年中国区城创新能力评价报告 2、指标&#xff1a;综合值、知识创造综合指标、研究开发投人综合指标、专利综合指标、科研论文综合指标、知识获取综合指标、…

个人导航网站介绍和部署

前言&#xff1a; 大家好&#xff0c;我是神的孩子都在歌唱&#xff0c;这是我csdn的博客 , 这是我做的一个神唱导航网站项目&#xff0c;这是一个练习项目&#xff0c;所以还存在很多问题&#xff0c;目的是方便收集和查阅日常浏览的网站&#xff0c;代码完全开源github&#…