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

ops/2024/9/23 18:17:23/

引入

首先介绍一下基础名词

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.ppmy.cn/ops/114895.html

相关文章

IOS 24 实现歌单详情(UITableView)列表

歌单详情完整效果 歌单详情歌单列表效果 歌单详情列表页整体效果稍微有点复杂&#xff0c;我们进行分部实现&#xff0c;先实现歌单详情里面的歌单列表&#xff0c;使用UITableView来实现。UITableView的使用在之前的文章中多次使用&#xff0c;想来也比较熟悉了。不熟悉的可以…

Elasticsearch:一次生产集群 ES Watcher 失效的深度排查与分析 - 全过程剖析与解决方案

作者&#xff1a;尚雷&#xff0c;TechTalk 技术交流社区创办者 一次生产集群 ES Watcher 失效的深度排查与分析 全过程剖析与解决方案​​ 一、Elasticsearch Watcher 介绍 1.1 Watcher 概念概述 Watcher 是 Elasticsearch 提供的一项监控和告警服务&#xff0c;允许用户定义…

北京市朝阳区自闭症寄宿学校:为孩子提供优质照顾与学习环境

北京市朝阳区自闭症寄宿学校的愿景与广州星贝育园的卓越实践 在北京市朝阳区&#xff0c;乃至全国范围内&#xff0c;自闭症儿童的教育与照护一直是社会各界关注的焦点。家长们渴望为孩子找到一所能够提供优质照顾与学习环境的学校&#xff0c;让他们在爱与专业的滋养下茁壮成…

在excel中使用python?

是的&#xff01;excel中可以使用python了&#xff01; 在去年8月22日&#xff0c;微软通过官方博客发布将与anaconda展开合作&#xff0c;简而言之就是excel将支持python&#xff0c;可以在表格中直接利用python就行数据分析&#xff0c;可以在表格中直接运行python了。 如何…

浅谈C#之SynchronizationContext

一、基本介绍 SynchronizationContext是一个抽象类&#xff0c;它提供了一种机制&#xff0c;允许代码与创建它的线程同步。这在UI编程中非常有用&#xff0c;比如在Windows Forms或WPF应用程序中&#xff0c;你可能需要确保某些操作在UI线程上执行&#xff0c;以避免跨线程操作…

深度学习02-pytorch-03-张量的数值计算

张量&#xff08;Tensor&#xff09;是多维数组的通用化概念&#xff0c;它可以表示标量&#xff08;0维&#xff09;、向量&#xff08;1维&#xff09;、矩阵&#xff08;2维&#xff09;以及更高维度的数据。在深度学习和数值计算中&#xff0c;张量是基础数据结构&#xff…

Redis中Hash(哈希)类型的基本操作

文章目录 一、 哈希简介二、常用命令hsethgethexistshdelhkeyshvalshgetallhmgethlenhsetnxhincrbyhincrbyfloathstrlen 三、命令小结四、哈希内部编码方式五、典型应用场景六、 字符串&#xff0c;序列化&#xff0c;哈希对比 一、 哈希简介 几乎所有的主流编程语言都提供了哈…

【学习笔记】 AD24中元器件重叠系统不报错的解决方案(消除报错)

【学习笔记】 AD24中PCB设计元器件重叠后系统不报错的解决方案&#xff08;如何主动屏蔽报错&#xff09; 一、Component Clearance未开启使能的解决方案二、最小水平间距设置错误的解决方案三、未开启设计规则检查的解决方案四、设计规则检查中 “在线”和“批量”的含义五、为…