分类: 嵌入式
2013-02-22 11:53:41
此tag由XING公司推出的算法/规范,所以叫做XING。
对于大多数的VBR文件都加了此头,但并不全是。此头位于MPEG音频头后面的某个特定位置。包好了此XING头的第一个帧,其后的数据是空的,所以即使解码器没有考虑到此头,也可以正常处理此帧。对于Layer III的文件来说,比如常见的MP3,此VBR放在边信息(side information)之后。
下表是XING头的具体格式及含义:
位置 |
长度(字节) |
含义 |
示例 |
0 |
4 |
4个ASCII字符的VBR头 ID,要么是Xing,要么是Info,无NULL结尾(普通字符串都以NULL,即\0结尾) |
'Xing' |
4 |
4 |
存放一个标志,用于表示接下来存在哪些域/字段,各字段逻辑或的结果. 0x0001 - 存在总帧数(Frames)字段 0x0002 - 存在文件大小(Bytes)字段 0x0004 –存在TOC字段 0x0008 – 存在音频质量指示字段 |
0x0007 就表示下面存在 总帧数,文件大小总字节数,TOC表 |
8 |
4 |
总帧数(Frames),大端[可选] |
7344 |
8或12 |
4 |
文件总大小,单位字节,大端[可选] |
45000 |
8,12,16 |
100 |
TOC表,大端[可选] |
|
8或12, 16, 108, 112 ,116 |
4 |
音频质量指示,最差0,最好100,大端[可选] |
0 |
5 XING 头
虽然知道了XING头的具体含义,可以去根据具体的值,解析出对应的含义了,但是,由于
其是放在side information之后的,所以,要先定位,找到XING头,关于其位置,用如下公式计算:
XING头位置 = MPEG头位置 + MPEG帧头大小 + 边信息大小
= MPEG头位置 + 4 + 边信息大小 【公式4】
根据头的格式,Xing头里面必须包含ID和flag这两个段。其他字段都是可选的,是否包含,要看flag的值。有时候这个Xing头,CBR里面也有,此时,前面的ID的值就是Info,而不是Xing了。
据了解,目前此头信息,只有用Fraunhofer的编码器生成的MPEG音频文件,才会用到此头。其和Xing头不一样,其放在第一个MPEG头的后面,大小正好是32字节。其位置,长度和示例,都是以字节为单位。
下表是VBRi头的具体格式及含义,单位为字节:
位置 |
长度 |
含义 |
示例 |
0 |
4 |
4个ASCII字符的VBR头ID:“VBRI”无NULL结尾 |
“VBRI” |
4 |
2 |
版本ID,大端,类型:DWORD |
1 |
6 |
2 |
延迟,类型:float |
7344 |
8 |
2 |
音频质量指示 |
75 |
10 |
4 |
文件总大小,大端,类型:DWORD |
45000 |
14 |
4 |
总的帧数,大端,类型:DWORD |
7344 |
18 |
2 |
TOC表的表项数目,大端,类型:WORD |
100 |
20 |
2 |
TOC表项的缩放因子,大端,类型:DWORD |
1 |
22 |
2 |
单个TOC表项的大小,单位字节,最大为4,大端,类型:DWORD |
2 |
24 |
2 |
帧数/表项,大端,类型:WORD |
845 |
26 |
|
用于检索的TOC表,整型值,可以通过每个表项大小乘于表项个数得到此TOC表的总大小,大端 |
|
6 VBRI头
此处只是大概总结一下,具体解析出播放时间,需要哪些步骤。其对应的代码,可以去文章引用中的【1】,注册登录后,可以下载源代码,自己看,就知道了。
或者,可以去参考引用【2】中的Mplayer的VBR 的patch,里面写的更加简单,但是也更容易看明白。
如果文件开始没有ID3 V2的头信息,那么一般MPEG的帧头位置是0,当然,具体还是要根据帧头中的同步位(sync bit),共11位去定位找到帧头。
主要是根据帧头格式,解析出MPEG的版本,MPEG的Layer,以及采样率,比特率等信息,用于后面的解码和计算播放时长。
解析完MPEG头之后,按照如下步骤去判断是CBR还是VBR,并计算出播放时长:
根据:
XING头位置 = MPEG头位置 + 4 + 边信息大小 【公式4】
计算定位到XING头所在位置。上式中:
MPEG头位置:
如果没有ID3 V2这类的信息的话,那么MPEG头位置就是文件的最开始,即0的位置。
MPEG帧头大小:
固定的32 bit = 4字节,所以加4.
边信息大小:
对应Layer III,根据MPEG的版本,查下表可得,单位为字节:
|
MPEG 1 |
MPEG 2/2.5 (LSF) |
立体声,联合立体声,双声道 |
32 |
17 |
单声道 |
17 |
9 |
7 Layer III的边信息(side information)
VBR文件播放总时间 = 总的帧数 × 每一帧的采样个数÷ 比特率 【公式3】
计算出播放时间长度。
其中:
总的帧数(Number of Frames):
可以通过解析XING头,找出里面总帧数(Frames),这个字段,一般都是存在的。
每一帧的采样个数(Samples Per Frame):
根据前面解析MPEG,找到MPEG的版本,以及其实哪个Layer,然后根据表3.2.3 每帧的采样数,得到,每一帧有多少个采样。
比特率(Sampling Rate):
根据前面解析MPEG,找到4比特大小的比特率索引 ,然后根据表3.2.2 比特率(单位:Kbit/sec),得到此比特率大小。
如果找到,解析VBRI,然后和XING头算法类似,得到需要的值,再根据【公式3】计算出播放时间长度。
Xing和VBRI都无,则是CBR,然后就可以用【公式1】和【公式2】,计算出播放时间长度了。
其中【公式1】中所涉及到的:
每帧的采样数(Samples Per Frame):
同上,可根据MPEG头解析出来。
比特率(Bitrate):
同上,可根据MPEG头解析出来。
采样率(Sampling Rate):
根据MPEG头中解析出来的采样率索引,然后查表:表3.2.4 MPEG不同版本对应的采样率,即可。
填充大小(Padding Size):
根据MPEG帧头中的Padding位得知是0还是1。多数MP3,都没有padding,即为0.
计算出上面几个值后,可以根据:
帧大小 = ((每帧的采样数 ÷ 8 × 比特率) ÷ 采样率)+ 填充大小 【公式1】
计算出帧大小,然后再去计算:
文件大小(File Size):
这个自己计算就可以得到,我的理解是:
文件大小 = 总文件大小 – 头信息
这里的头信息,指的是ID3 V1或ID3 V2之类的头。
剩下的,总文件大小,这个不用多解释吧,就是整个读取出来的文件大小。
然后,就可以根据:
播放时间 = 文件大小 ÷ 比特率 × 8 【公式2】
计算出播放时间了。
|