DTS和PTS的分析(FFMPEG、HLS相关)

来在研究HLS(HTTP Live Streaming),以实现android上播放m3u8文件。由于TS段的切分不统一,每个视频网站给出的m3u8 playlists总有差别,在时间戳显示上有差异,所以对DTS和PTS进行了研究。

DTS和PTS是音视频同步的关键技术,同时也是丢帧策略密切相关。


dts/pts定义 dts: decoding time stamp pts: present time stamp 

在ISO/IEC13818-1中制定90k Hz 的时钟,如果编码帧频是30,那么时间戳间隔就该是90000 / 30 = 3000。 在FFMPEG中有三种时间单位:秒、微秒和dts/pts。从dts/pts转化为微秒公式:



其中AV_TIME_BASE为1,000,000,denominator为90,000。 拿到m3u8播放列表后,首先进行解析。HTTP Live Streaming标准草案可以从这里http://tools.ietf.org/html/draft-pantos-http-live-streaming-08查看。 解析代码在ffmpeg/libavformat/hls.c中
 parse_playlist函数

解析播放列表的问题
  

当解析到#EXT-X-TARGETDURATION标签时,后面紧跟着的是TS段的最大时长,当前没有什么用。#EXTINF标签后紧跟的是当前TS段的时长,当EXT-X-VERSION标签大于等于3时,TS段的时长可以为小数,当前(2012-07-26)的FFMPEG代码还不支持EXT-X-VERSION标签的判断,TS段的时长也为整数。保存了当前段的时长,单位为秒。
  

当前草案中还有EXT-X-DISCONTINUITY标签,它表征其后面的视频段文件和之前的不连续,这意味着文件格式、时间戳顺序、编码参数等的变化。但是很遗憾,当前FFMPEG仍然不支持,这意味着该标签出现后,后续的PES中携带的dts和pts将重新从零开始计数。


 seek_timestamp为标志位,它表征当前视频发生了SEEK事件,当发生SEEK事件后首先调用hls_read_seek()函数定位到应该读取的TS段,更新HLS上下文中的段序号。当读取到该段的packet,有两种判断。 在ffplay中,当外界发起seek请求后,将执行以下操作。

 

 

调用avformat_seek_file(),完成文件的seek定位
  

清空解码前packet队列(音频、视频、字幕)

 

调用avcodec_flush_buffers(),清空解码buffer和相关状态

 

在第一个步骤中,将在HLS层进行seek操作,seek流程图如下图所示:

http://image55.360doc.com/DownloadImg/2012/09/1315/26808238_1.png
http://image55.360doc.com/DownloadImg/2012/09/1315/26808238_1.png

首先读取packet,判断是否有seek操作,没有则直接将该packet返回,送人后续的解码操作。如果是seek情况,则读取dts时间戳,如果dts没有值,则直接清除seek标志并返回packet(问题一)。如果dts时间戳有值,则将该值转化为微秒并与seek传入的时间进行比较,看是否大于seek时间,如果大于则表明读取的packet达到了seek要求(问题二),否则继续读packet。如果seek时间已经满足,则看该packet的flags是否是关键帧,如果是则返回该packet(问题三),否则继续读packet。

该流程很简单,但是带来了三个问题。分别解释

 

问题一,如果dts没有值,返回回去后,解码状态全部进行了reset,则送入的第一帧信息应该为关键帧,否则该帧需要参考其他帧,产生花屏。

 

问题二,如果dts时间戳有误,将出现dts转化为微秒后永远小于seek传入时间问题,则永远无法返回packet,导致seek僵死。

 

问题三,判断packet是否为关键帧,忽略了该packet是否为视频,如果该packet为音频并且flag AV_PKT_FLAG_KEY的结果为真,则将返回该packet并清空seek标准。后续读到的视频也有非关键帧的可能,从而导致花屏。








  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值