FFMPEG中PTS与DTS有关概念陈述:
概念
PTS:(Presentation Time Stamp)PTS主要用于度量解码后的视频帧什么时候被显示出来。
DTS:(Decode Time Stamp)DTS主要是标识读入内存中的数据流在什么时候开始送入解码器中进行解码。
pts反映当前帧什么时候开始显示,dts反映数据流什么时候开始解码。
要让一帧数据秒第N秒开始显示。那么它的pts到底是多少?
FFmpeg中时间基的,也就是time_base。是用来度量时间的,而每个阶段的时间基有是不同的。
如果把1秒分为60等份,那么每一等份表示的就是1/60秒。此时的time_base={1,60}。
如果你是把1秒分成90000份,每一等份就是1/90000 S,此时的time_base={1,90000}。
如果比作一把尺,所谓时间基表示的就是每个刻度是多少秒?
pts的值就是占多少个时间刻度(占多少个格子)其单位显然不是秒,而是时间刻度。只有pts加上time_base两者同时在一起,才
能表达出时间是多少。
在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下是多少。
总结
BUG产生的原因往往是概念的不清晰。PTS 与DTS在播放器等开发过程中十分重要;在推拉流、音视频同步过程都会用到;如果是使用ffmpeg开发,在PC或者LINUX上开发,时间基转换有相关demo进行参考;如果是在HI3519或者RK35XX等平台开发过程中,想用硬件的编码或解码,在结合ffmpeg封装或者解封装过程时要注意相关时间基的转换,PTS、DTS的传递。