相关文章:
视频解码研究之PTS(1)TS格式和FLV格式
视频解码研究之PTS(2)Mp4格式,AVI格式和MKV格式
MKV格式的PTS解析代码
FLV格式的解复用和PTS分析代码
关于其他格式的PTS请看:
视频解码研究之PTS(1)TS格式和FLV格式
接着上一篇文章分析:
3.MP4格式
Mp4文件格式的基本单位是atom(或称box)。
Mp4格式中涉及到PTS信息的atom包括:stts,ctts和elst。
先介绍stts,格式如下:
Stts存储着一系列的参数对(sample_count, sample_time_delta)。每一个参数对给出了具相同时间间隔的连续的sample的个数和这些sample的时间间隔值。如下式所示将所有的时间间隔相加,可以得到该track的时间总长。
duration = (sample_count1 * sample_time_delta1 + ... + sample_countN * sample_time_deltaN ) / timescale
对某mp4码流(文件名un.mp4)进行分析,可以得到只包含一个参数对,sample_count= 31063, sample_time_delta = 1001.时间单位是该文件的timescale。已知timescale= 1/24000,可以得到每帧图像(一个视频sanple包含一帧未解码的图像)的持续时间是1001*1/24000 =0.041783秒。即帧率为23.977.
这个参数对的表示,此mp4文件共有31063个视频sample,每个视频sample持续时间都是相同的。
Elst atom中存储着关于流的起始时间(start_time)的信息,结合stts中的内容就可以计算DTS。
对于文件中的第n个sample来说:
DTS = sample_time_delta * n – start_time
比如un.mp4中elst存储的start_time为2002,则第1个sample的DTS等于-2002,第2个sample的DTS等于-1001,第3个sample的DTS为0,…
如果mp4文件包含的视频流含有b帧,则需要ctts atom,Ctts atom的结构如下图所示:
Ctts存储的一系列的参数对(数量为entry count),(sample_count, sample_offset)。一个参数对表示sample_count个的sample的PTS和DTS之间的差为sample_offset。
所以,对于没有b帧的mp4文件:
PTS = DTS
对于有b帧的mp4文件:
PTS = DTS + sample_offset
通过程序解析文件un.mp4得到的结果打印在屏幕上,结果和ffmpeg的计算结果相同:
首先,AVI格式中是没有时间戳信息的。
这样的话,AVI格式的每1帧图像的DTS只能通过帧率来计算,而在有b帧的情况下PTS是无法得到。
如上图,帧率信息在AVI文件中‘avih’结构和表示视频的结构‘strh’中都能得到:
‘avih’中MicroSecPerFrame = 41708,每帧的时长为41708微秒。
‘strh’中sacle/rate = 104271/2500000 =0.0411708秒。
所以第n个sample的DTS:
DTS= n*104271/2500000(单位:秒)
如果以sacle/rate为单位,则
DTS= n;
5.MKV格式
Mkv格式的大体结构如下图所示,其中音视频数据存储在Clusters数据段中。
Clusters数据段的结构如图所示:
Clusters数据段包含多个cluster,每一个cluster都有一个timecode(图中红线标示),我们称作Cluster’s timecode,本文中简称CTC。Cluster中包含多个BlockGroup,每一个BlockGroup又包含多个Block。Block的结构如下图:
对于视频来说,一个Block包含一帧图像的数据。每一个Block也有一个time code,称作Block’s timecode,本文中简称BTC。BTC是当前的block相对于所处的cluster的CTC的缩进值。
所以绝对时间码(Absolute Timecode),本文简称ATC应该等于BTC加上CTC。
编写程序对某MKV文件进行解析计算,得到前数个block的ATC如下图所示:
ATC和ffmpeg输出的pts相同,所以对于mkv来说,ATC就是视频每一帧的pts。另,可分析此mkv文件,得到文件中timecode的单位是毫秒。