浅谈音视频 pts dts基本概念及理解


Posted in 数码科技 onAugust 05, 2022

视频的播放过程可以简单理解为一帧一帧的画面按照时间顺序呈现出来的过程,就像在一个本子的每一页画上画,然后快速翻动的感觉。
但是在实际应用中,并不是每一帧都是完整的画面,因为如果每一帧画面都是完整的图片,那么一个视频的体积就会很大,这样对于网络传输或者视频数据存储来说成本太高,所以通常会对视频流中的一部分画面进行压缩(编码)处理。由于压缩处理的方式不同,视频中的画面帧就分为了不同的类别,其中包括:I 帧、P 帧、B 帧。

I、P、B 帧

I 帧、P 帧、B 帧的区别在于:

I 帧(Intra coded frames):I 帧图像采用帧内编码方式,即只利用了单帧图像内的空间相关性,而没有利用时间相关性。I 帧使用帧内压缩,不使用运动补偿,由于 I 帧不依赖其它帧,所以是随机存取的入点,同时是解码的基准帧。I 帧主要用于接收机的初始化和信道的获取,以及节目的切换和插入,I 帧图像的压缩倍数相对较低。I 帧图像是周期性出现在图像序列中的,出现频率可由编码器选择。
P 帧(Predicted frames):P 帧和 B 帧图像采用帧间编码方式,即同时利用了空间和时间上的相关性。P 帧图像只采用前向时间预测,可以提高压缩效率和图像质量。P 帧图像中可以包含帧内编码的部分,即 P 帧中的每一个宏块可以是前向预测,也可以是帧内编码。
B 帧(Bi-directional predicted frames):B 帧图像采用双向时间预测,可以大大提高压缩倍数。值得注意的是,由于 B 帧图像采用了未来帧作为参考,因此 MPEG-2 编码码流中图像帧的传输顺序和显示顺序是不同的。
也就是说,一个 I 帧可以不依赖其他帧就解码出一幅完整的图像,而 P 帧、B 帧不行。P 帧需要依赖视频流中排在它前面的帧才能解码出图像。B 帧则需要依赖视频流中排在它前面或后面的帧才能解码出图像。

这就带来一个问题:在视频流中,先到来的 B 帧无法立即解码,需要等待它依赖的后面的 I、P 帧先解码完成,这样一来播放时间与解码时间不一致了,顺序打乱了,那这些帧该如何播放呢?这时就需要我们来了解另外两个概念:DTS 和 PTS(详见下边说明)。

两个I frame之间形成一个GOP,在x264中同时可以通过参数来设定bf的大小,即:I 和p或者两个P之间B的数量。

通过上述基本可以说明如果有B frame 存在的情况下一个GOP的最后一个frame一定是P.

看x264代码,感觉GOP 就是IDR帧到另一个IDR帧之间 就是一个GOP.在视频编码序列中,GOP即Group of picture(图像组),指两个I帧之间的距离,Reference(参考周期)指两个P帧之间的距离(如下图)。一个I帧所占用的字节数大于一个P帧,一个P帧所占用的字节数大于一个B帧(如下图所示)。

所以在码率不变的前提下,GOP值越大,P、B帧的数量会越多,平均每个I、P、B帧所占用的字节数就越多,也就更容易获取较好的图像质量;Reference越大,B帧的数量越多,同理也更容易获得较好的图像质量。

需要说明的是,通过提高GOP值来提高图像质量是有限度的,在遇到场景切换的情况时,H.264编码器会自动强制插入一个I帧,此时实际的GOP值被缩短了。另一方面,在一个GOP中,P、B帧是由I帧预测得到的,当I帧的图像质量比较差时,会影响到一个GOP中后续P、B帧的图像质量,直到下一个GOP开始才有可能得以恢复,所以GOP值也不宜设置过大。

同时,由于P、B帧的复杂度大于I帧,所以过多的P、B帧会影响编码效率,使编码效率降低。另外,过长的GOP还会影响Seek操作的响应速度,由于P、B帧是由前面的I或P帧预测得到的,所以Seek操作需要直接定位,解码某一个P或B帧时,需要先解码得到本GOP内的I帧及之前的N个预测帧才可以,GOP值越长,需要解码的预测帧就越多,seek响应的时间也越长。

DTS、PTS 的概念

DTS、PTS 的概念如下所述:

DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
需要注意的是:虽然 DTS、PTS 是用于指导播放端的行为,但它们是在编码的时候由编码器生成的。

当视频流中没有 B 帧时,通常 DTS 和 PTS 的顺序是一致的。但如果有 B 帧时,就回到了我们前面说的问题:解码顺序和播放顺序不一致了。

比如一个视频中,帧的显示顺序是:I B B P,现在我们需要在解码 B 帧时知道 P 帧中信息,因此这几帧在视频流中的顺序可能是:I P B B,这时候就体现出每帧都有 DTS 和 PTS 的作用了。DTS 告诉我们该按什么顺序解码这几帧图像,PTS 告诉我们该按什么顺序显示这几帧图像。顺序大概如下:

PTS:   480   640  560  520  600  800  720  680  760  960 ...
DTS:   400   440  480  520  560  600  640  680  720  760 ...
Stream: I     P    B    B    B    P    B    B    B    P  ...
播放序: 1     5    3    2    4    9    7    6    8   10  ...               
PTS >= DTS

音视频的同步

上面说了视频帧、DTS、PTS 相关的概念。我们都知道在一个媒体流中,除了视频以外,通常还包括音频。音频的播放,也有 DTS、PTS 的概念,但是音频没有类似视频中 B 帧,不需要双向预测,所以音频帧的 DTS、PTS 顺序是一致的。

音频视频混合在一起播放,就呈现了我们常常看到的广义的视频。在音视频一起播放的时候,我们通常需要面临一个问题:怎么去同步它们,以免出现画不对声的情况。

要实现音视频同步,通常需要选择一个参考时钟,参考时钟上的时间是线性递增的,编码音视频流时依据参考时钟上的时间给每帧数据打上时间戳。在播放时,读取数据帧上的时间戳,同时参考当前参考时钟上的时间来安排播放。这里的说的时间戳就是我们前面说的 PTS。实践中,我们可以选择:同步视频到音频、同步音频到视频、同步音频和视频到外部时钟。

PTS和DTS的时间基

PST和DTS的单位是什么?

为了回答这个问题,先引入FFmpeg中时间基的概念,也就是time_base。它也是用来度量时间的。
如果把1秒分为25等份,你可以理解就是一把尺,那么每一格表示的就是1/25秒。此时的time_base={1,25}
如果你是把1秒分成90000份,每一个刻度就是1/90000秒,此时的time_base={1,90000}。
所谓时间基表示的就是每个刻度是多少秒
pts的值就是占多少个时间刻度(占多少个格子)。它的单位不是秒,而是时间刻度。只有pts加上time_base两者同时在一起,才能表达出时间是多少。
好比我只告诉你,某物体的长度占某一把尺上的20个刻度。但是我不告诉你,这把尺总共是多少厘米的,你就没办法计算每个刻度是多少厘米,你也就无法知道物体的长度。
pts=20个刻度
time_base={1,10} 每一个刻度是1/10厘米
所以物体的长度=ptstime_base=201/10 厘米

在ffmpeg中。av_q2d(time_base)=每个刻度是多少秒
此时你应该不难理解 pts*av_q2d(time_base)才是帧的显示时间戳。

下面理解时间基的转换,为什么要有时间基转换。
首先,不同的封装格式,timebase是不一样的。另外,整个转码过程,不同的数据状态对应的时间基也不一致。拿mpegts封装格式25fps来说(只说视频,音频大致一样,但也略有不同)。非压缩时候的数据(即YUV或者其它),在ffmpeg中对应的结构体为AVFrame,它的时间基为AVCodecContext 的time_base ,AVRational{1,25}。
压缩后的数据(对应的结构体为AVPacket)对应的时间基为AVStream的time_base,AVRational{1,90000}。
因为数据状态不同,时间基不一样,所以我们必须转换,在1/25时间刻度下占10格,在1/90000下是占多少格。这就是pts的转换。

根据pts来计算一桢在整个视频中的时间位置:
timestamp(秒) = pts * av_q2d(st->time_base)

duration和pts单位一样,duration表示当前帧的持续时间占多少格。或者理解是两帧的间隔时间是占多少格。一定要理解单位。
pts:格子数
av_q2d(st->time_base): 秒/格

计算视频长度:
time(秒) = st->duration * av_q2d(st->time_base)

ffmpeg内部的时间与标准的时间转换方法:
ffmpeg内部的时间戳 = AV_TIME_BASE * time(秒)
AV_TIME_BASE_Q=1/AV_TIME_BASE

av_rescale_q(int64_t a, AVRational bq, AVRational cq)函数
这个函数的作用是计算a*bq / cq来把时间戳从一个时间基调整到另外一个时间基。在进行时间基转换的时候,应该首先这个函数,因为它可以避免溢出的情况发生。
函数表示在bq下的占a个格子,在cq下是多少。

关于音频pts的计算:
音频sample_rate:samples per second,即采样率,表示每秒采集多少采样点。
比如44100HZ,就是一秒采集44100个sample.
即每个sample的时间是1/44100秒

一个音频帧的AVFrame有nb_samples个sample,所以一个AVFrame耗时是nb_samples*(1/44100)秒
即标准时间下duration_s=nb_samples*(1/44100)秒,
转换成AVStream时间基下
duration=duration_s / av_q2d(st->time_base)
基于st->time_base的num值一般等于采样率,所以duration=nb_samples.
pts=nduration=nnb_samples

到此这篇关于浅谈音视频 pts dts基本概念及理解的文章就介绍到这了,更多相关音视频 pts dts内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

数码科技 相关文章推荐
电脑硬件及电脑配置知识大全
Mar 17 数码科技
2021年最新CPU天梯图
Mar 04 数码科技
iPhone13再次曝光
Apr 15 数码科技
iPhone13 Pro外观确定,升级4800万镜头,4月20日发新品
Apr 15 数码科技
2007年老电脑安装win11会怎么样? 网友实测win11在老电脑运行良好
Nov 21 数码科技
Win11任务栏太宽了怎么办?一招解决Win11任务栏太宽问题
Nov 21 数码科技
Win11怎么启动任务管理器?Win11启动任务管理器的几种方法
Nov 23 数码科技
未发现nvidia显卡怎么办?Win11系统中未检测到nvidia显卡解决教程
Apr 08 数码科技
vmware虚拟机打不开vmx文件怎么办 ?vmware虚拟机vmx文件打开方法
Apr 08 数码科技
如何设置多台电脑共享打印机?多台电脑共享打印机的方法
Apr 08 数码科技
海康机器人重磅发布全新算法开发平台VM4.2
Apr 21 数码科技
苹果macOS 13开发者预览版Beta 8发布 正式版10月发布
Sep 23 数码科技
Win11远程连接不上怎么办?Win11远程桌面用不了的解决方法
Aug 05 #数码科技
win10识别不了U盘怎么办 win10系统读取U盘失败的解决办法
Aug 05 #数码科技
windows10声卡驱动怎么安装?win10声卡驱动安装操作步骤教程
Aug 05 #数码科技
win11怎么消除图标小盾牌?win11消除图标小盾牌解决方法
Aug 05 #数码科技
win10输入法不见了只能打出字母怎么解决?
Aug 05 #数码科技
win11开机发生死循环重启怎么办?win11开机发生死循环重启解决方法
Aug 05 #数码科技
win10蓝屏0xc0000001安全模式进不了怎么办?win10出现0xc0000001的解决方法
Aug 05 #数码科技
You might like
php中数据的批量导入(csv文件)
2006/10/09 PHP
php 高性能书写
2010/12/11 PHP
php加密解密函数authcode的用法详细解析
2013/10/28 PHP
php程序内部post数据的方法
2015/03/31 PHP
Yii2中DropDownList简单用法示例
2016/07/18 PHP
thinkPHP5框架分页样式类完整示例
2018/09/01 PHP
javascript cookie操作类的实现代码小结附使用方法
2010/06/02 Javascript
点弹代码 点击页面任何位置都可以弹出页面效果代码
2012/09/17 Javascript
extjs 04_grid 单击事件新发现
2012/11/27 Javascript
Javascript 赋值机制详解
2014/11/23 Javascript
node.js中的fs.statSync方法使用说明
2014/12/16 Javascript
javascript继承的六大模式小结
2015/04/13 Javascript
详细解密jsonp跨域请求
2015/04/15 Javascript
JavaScript 数组中最大最小值
2016/06/05 Javascript
js querySelector() 使用方法
2016/12/21 Javascript
ng-options和ng-checked在表单中的高级运用(推荐)
2017/01/21 Javascript
从零开始学习Node.js系列教程五:服务器监听方法示例
2017/04/13 Javascript
Angular模板表单校验方法详解
2017/08/11 Javascript
vue+vuex+axios实现登录、注册页权限拦截
2018/03/09 Javascript
vue 多入口文件搭建 vue多页面搭建的实例讲解
2018/03/12 Javascript
通过jquery.cookie.js实现记住用户名、密码登录功能
2018/06/20 jQuery
vue iview的菜单组件Mune 点击不高亮的解决方案
2019/11/01 Javascript
python判断端口是否打开的实现代码
2013/02/10 Python
用Python操作字符串之rindex()方法的使用
2015/05/19 Python
解决pip install xxx报错SyntaxError: invalid syntax的问题
2018/11/30 Python
基于Python实现体育彩票选号器功能代码实例
2020/09/16 Python
欧缇丽美国官网:Caudalie美国
2016/12/31 全球购物
在Ajax应用中信息是如何在浏览器和服务器之间传递的
2016/05/31 面试题
集团公司总经理岗位职责
2013/12/20 职场文书
双十佳事迹材料
2014/01/29 职场文书
《理想的风筝》教学反思
2014/04/11 职场文书
法人任命书范本
2014/06/04 职场文书
作文评语怎么写
2014/12/25 职场文书
杨善洲电影观后感
2015/06/04 职场文书
postgresql无序uuid性能测试及对数据库的影响
2021/06/11 PostgreSQL
关于对TypeScript泛型参数的默认值理解
2022/07/15 Javascript