时间戳是容器层的基础概念,很多人还搞不清楚 PCR,PTS,DTS 到底什么关系,对于刚入门的朋友来说,确认让人感到迷惑。
搞清楚三者的区别,本质上就一句话:PCR 是时钟,PTS,DTS 是时刻。是不是已经顿悟了?
这三个的全称为:
PCR: 系统参考时钟
PTS: 显示时间
DTS: 解码时间
PCR 是 TS 流中才有的概念。设想在定义规范的时候,假如只需要支持纯视频,那就不需要使用时间戳了,解码器只要按固定帧率播放就可以。当需要把音视频数据合并在一起,控制av同步就是一个问题。时间戳机制被引入用以解决av同步问题。
假设a,b两人约定某个时刻去做某事,则需要一个前提,他们两人的手表必须是同步的,比如都是使用北京时间对时的,如果他们的表不准 ,比北京时间差了几个小时,就会有人迟到,要做的事情被耽误。pcr就是北京时间,编码器将自己的系统时钟采样,以pcr形式放入ts,解码器使用pcr同步自己的系统时钟,保证编码器和解码器的时钟同步。
dts,收到的数据何时解码,现在的解码器已经基本不关心他,收到数据立即解码。只使用pts
pts控制画面何时显示,音频何时播放。
三者之间的大小关系:
1
2
3
PCR < DTS < PTS
假设现在中午12点,正常情况下,画面总是在未来某个时刻显示,所以pts总是大于方式的系统时间,如果pts要求为上午9点显示,解码器就认为这个画面迟到了。如果要求晚上7点显示,就会造成解码器缓冲溢出。解码器不知到这些画面如何播放,丢弃缓冲或其它异常处理,用户看到的效果都会不流畅,因为本该显示的画面耽搁了太久。所以pts与pcr总是会有合理的间隔值。时间戳的正确性直接决定播出效果。
一些不规范pc播放器并不关心pcr,使用视频或音频pts作为参考时间,对于pcr有错的ts,他们是可以正常播的。机顶盒也可以采用相同机制,绝大部分机顶盒都是以pcr作为参考时间的。
没有相关文章.
(以上转自 easyice.cn ,请勿用于任何商业用途)
(以下转自https://blog.csdn.net/xiaojun111111/article/details/40623711)
对于PTS_DTS_flags的重设
此字段在PES头语法中,标识PTS与DTS在PES分组首部的出现情况,当出于某种需求要对此标志位进行修改,例如由‘3’ 修改为‘2’,即删除DTS,但仅仅修改了这个标志位并没有达到“删除DTS”的目的。虽然VLC等播放器可以正常解码且不报任何错误,在一些严格的解码器上,会无法识别新生成的数据。例如elecard分析软件会报告“无法检测流”,ipad播放会说“无法播放此影片”
这是因为忽略了一个问题,在PTS语法中,前4个bit要求与 PTS_DTS_flags 取值相同。因此,在修改 PTS_DTS_flags 的之后,PTS语法前4bit也要做相应的修改。这样目前已知的解码器就可以正常工作
H264码流生成快进文件关键技术
对于快进/快退文件的生成,行业内一般以VLC正常播放作为鉴定标准,要使自己抽帧生成的码流在VLC播放正常,不仅仅是抽取关键帧就OK,抽帧
只是第一步,总结来说,需要以下举措:
1.抽取关键帧
这个过程中,需要抽取完整的关键帧,在264码流中,码流层次没有帧的概念,帧由若干slice组成,如果编码器编码过程采用
了分片,那么你需要将属于同一帧的slice都拿出来。一般来说,应用与广电行业的264编码器不采取分片,一个帧就是一个片。
例外情况是,当码流编码为隔行视频,一个帧被编码为两个片,每个片是一个场。隔行视频中,I片后经常紧跟一个p片,他们
具有相同的frame_num,这时你需要将p片也拿出来,否则i帧是不完整的
2.PTS, DTS PCR时间戳调整
最好的效果是调整到没有PCR精度错误,间隔错误,以及PTS错误,不过若做简单一些,保证PCR精度正确就可以。前提是PTS
变化间隔不要过大,否则影响播放效果流畅程度。
3.frame_num调整
仅当码流中关键帧为I帧时需要调整,IDR帧则不必。frame_num被解码器用于控制解码顺序,我不清楚为什么
IDR帧的frame_num总为0而I帧却不是,事实是,frame_num的不连续造成vlc播放时认为过多的迟到帧,所以
需要把它调整连续
对于VLC来说,经过上述调整就可以流畅播放,而其他如mplayer类会瞬间播完,因为这类播放器按fps播放,对此你
需在码流中填充零动作P帧,以维持帧率恒定
对时间戳循环到头的处理:
ts流中的三个时间戳,pts(33bit),dts(33bit),pcr(42bit)
当时间戳增加到语法无法容纳时,产生时间戳循环,时间线开始变小,循环点计算方式是:将要设置的值减去时间
戳最大值,将差值写入语法结构。编码器设置时钟,以及解码器自己的系统时钟在达到最大值后,都根据此方式计算,
不会产生时钟的不连续。
PCR能表示多长时间
PCR最大值是多少,多长时间会循环一次,这是个非常简单的问题,但一直以来我们对他的认识是错误的,我们认为是两天多
先说正确的应该是多少,根据:
PCR(i) = PCR_base(i)*300 + PCR_ext(i)
PCR_base 33 位,最大值:0x1FFFFFFFF
PCR_ext 9 位,根据定义,取值 0-299
因此PCR最大值为:0x1FFFFFFFF*300 + 299
可表示的小时数:(0x1FFFFFFFF*300 + 299) / 27000000 / 3600 约为 26.5 小时
以前认为是两天多,大概是这样算的,PCR一共42位,把2的42次方作为PCR最大值,算出来大约是1.8天