原由:
dts/pts定义 dts: decoding time stamp pts: present time stamp 在ISO/IEC13818-1中制定90k Hz 的时钟,如果编码帧频是30,那么时间戳间隔就该是90000 / 30 = 3000。 在FFMPEG中有三种时间单位:秒、微秒和dts/pts。从dts/pts转化为微秒公式: dts* AV_TIME_BASE/ denominator 其中AV_TIME_BASE为1,000,000,denominator为90,000。 拿到m3u8播放列表后,首先进行解析。HTTP Live Streaming标准草案可以从这里http://tools./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段的时长也为整数。seg->duration保存了当前段的时长,单位为秒。当前草案中还有EXT-X-DISCONTINUITY标签,它表征其后面的视频段文件和之前的不连续,这意味着文件格式、时间戳顺序、编码参数等的变化。但是很遗憾,当前FFMPEG仍然不支持,这意味着该标签出现后,后续的PES中携带的dts和pts将重新从零开始计数。 HLS上下文结构体
HLS上下文中存在当前的段序号,在HLS.c文件中,hls_read()函数根据判断得到当前段读取完毕后,将cur_seq_no加一,从而读取下一个TS段。在hls_read_packet()函数读取一个packet,该packet包含一帧可被解码的图像,或者一帧或多帧音频。 hls_read_packet源代码
这里c->seek_timestamp为标志位,它表征当前视频发生了SEEK事件,当发生SEEK事件后首先调用hls_read_seek()函数定位到应该读取的TS段,更新HLS上下文中的段序号。当读取到该段的packet,有两种判断。 在ffplay中,当外界发起seek请求后,将执行以下操作。
在第一个步骤中,将在HLS层进行seek操作,seek流程图如下图所示: 首先读取packet,判断是否有seek操作,没有则直接将该packet返回,送人后续的解码操作。如果是seek情况,则读取dts时间戳,如果dts没有值,则直接清除seek标志并返回packet(问题一)。如果dts时间戳有值,则将该值转化为微秒并与seek传入的时间进行比较,看是否大于seek时间,如果大于则表明读取的packet达到了seek要求(问题二),否则继续读packet。如果seek时间已经满足,则看该packet的flags是否是关键帧,如果是则返回该packet(问题三),否则继续读packet。
转载请注明出处:http://www.cnblogs.com/fpzeng/archive/2012/07/26/dts_pts.html
|
|
来自: 昵称12368912 > 《视频编码知识》