求各种音频视频格式的解码与编码算法 ( 积分: 30 )

  • 主题发起人 linuxping
  • 开始时间
L

linuxping

Unregistered / Unconfirmed
GUEST, unregistred user!
音频视频mp3,MP4,WMA,rm解码与编码算法
 
很好,我来顶一下,可我不懂哦。。。
 
我有mp3编码解码算法~~~
贴出来了~~
抛砖引玉~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2.1. Mp3文件格式
MP3文件以一帧为一个编码单元,各帧编码数据是独立的。为了清晰而准确地描述mp3文件格式,下面采用位流语法描述,这种语法格式与c语言近似,易于理解,且描述清晰。其中粗体表示码流中的数据项,bslbf代表位串,即“Bit string, left bit first ”,uimsbf代表无符号整数,即”unsinged integer, most significant bit first”,数字表示该数据项所占的比特数。
2.1.1. Audio Sequence
audio sequence()
{
while (true)
{
frame()
}
}
2.1.2. Audio Frame
frame()
{
header()
error_check()
audio_data()
ancillary_data()
}
2.1.3. Header
header()
{
syncword 12 bslbf
ID 1 bslbf
layer 2 bslbf
protection_bit 1 bslbf
bitrate_index 4 bslbf
sampling_frequency 2 bslbf
padding_bit 1 bslbf
private_bit 1 bslbf
mode 2 bslbf
mode_extension 2 bslbf
copyright 1 bslbf
original/home 1 bslbf
emphasis 2 bslbf
}
2.1.4. Error Check
error_check()
{
if (protection_bit==0)
crc_check 16 rpchof
}
2.1.5. Audio data , Layer III
audio_data()
{
main_data_begin
9 uimsbf
if(mode==single_channel) private_bits 5 bslbf
else
private_bits 3 bslbf
for(ch=0;ch<nch;ch++)
for(scfsi_band=0;scfsi_band<4;scfsi_band++)
scfsi[ch][scfsi_band] 1 bslbf
for(gr=0;gr<2;gr++)
for(ch=0;ch<nch;ch++){
part2_3_length[gr][ch] 12 uimsbf
big_values[gr][ch] 9 uimsbf
global_gain[gr][ch] 8 uimsbf
scalefac_compress[gr][ch] 4 bslbf
window_switching_flag[gr][ch] 1 bslbf
if(window_switching_flag[gr][ch]){
block_type[gr][ch] 2 bslbf
mixed_block_flag[gr][ch] 1 uimsbf
for(region=0;region<2;region++)
table_select[gr][ch][region] 5 bslbf
for(window=0;window<3;window++)
subblock_gain[gr][ch][window] 3 uimsbf
}
else
{
for(region=0;region<3;region++)
table_select[gr][ch][region] 5 bslbf
region0_count[gr][ch] 4 bslbf
region1_count[gr][ch] 3 bslbf
}
preflag[gr][ch] 1 bslbf
scalefac_scale[gr][ch] 1 bslbf
count1table_select[gr][ch] 1 bslbf
}
main_data
}
2.1.6. Main_data
main_data()
{
for(gr=0;gr<2;gr++)
for(ch=0;ch<nch;ch++){
if((window_switching_flag[gr][ch]==1)&amp;&amp;(block_type[gr][ch]==2)){
if(mixed_block_flag[gr][ch]){
for(sfb=0;sfb<8;sfb++)
scalefac_l[gr][ch][sfb] 0..4 uimsbf
for(sfb=3;sfb<12;sfb++)
for(window=0;window<3;window++)
scalefac_s[gr][ch][sfb][window] 0..4 uimsbf
}
else
{
for(sfb=0;sfb<12;sfb++)
for(window=0;window<3;window++)
scalefac_s[gr][ch][sfb][window] 0..4 uimsbf
}
}
else
{
if((scfsi[ch][0]==0||(gr==0))
for(sfb=0;sfb<6;sfb++)
scalefac_l[gr][ch][sfb] 0..4 uimsbf
if((scfsi[ch][1]==0||(gr==0))
for(sfb=6;sfb<11;sfb++)
scalefac_l[gr][ch][sfb] 0..4 uimsbf
if((scfsi[ch][2]==0||(gr==0))
for(sfb=11;sfb<16;sfb++)
scalefac_l[gr][ch][sfb] 0..3 uimsbf
if((scfsi[ch][3]==0||(gr==0))
for(sfb=16;sfb<21;sfb++)
scalefac_l[gr][ch][sfb] 0..3 uimsbf
}
Huffmancodebits()
}
for(b=0;b<no_of_ancillary_bits;b++)
ancillary_bit 1 bslbf
}
2.1.7. Huffmancodebits
Huffmancodebits(){
for(l=0;l<big_values*2;l+=2){
hcod[|x|][|y|] 0..19 bslbf
if(|x|==15&amp;&amp;linbits>0) linbitsx 1..13 uimsbf
if(x!=0)signx 1 bslbf
if(|y|==15&amp;&amp;linbits>0) linbitsy 1..13 uimsbf
if(y!=0) signy 1 bslbf
is[l]=x
is[l+1]=y
}
for(;l<big_values*2+count1*4;l+=4){
hcod[|v|][|w|][|x|][|y|] 1..6 bslbf
if(v!=0) signv 1 bslbf
if(w!=0) signw 1 bslbf
if(x!=0) signx 1 bslbf
if(y!=0) signy 1 bslbf
is[l]=v
is[l+1]=w
is[l+2]=x
is[l+3]=y
}
for(;l<576;l++)
is[l]=0
}
2.1.8. Ancillary data
ancillary_data(){
if((layer==1||layer==2))
for(b=0;b<no_of_ancillary_bits;b++)
ancillary_bit 1 bslbf
}
2.2. 数据项的含义
2.2.1. Header
&amp;#61656; Syncword
同步头,表示一帧数据的开始,共12位,全1即0XFFF。
表格 2 1 Layer
Layer
'11' Layer I
'10' Layer II
'01' Layer III
'00' reserved
表格 2 2 Bitrate_index
bitrate specified (kBit/s)
bitrate_index Layer I Layer II Layer III
'0000' free free free
'0001' 32 32 32
'0010' 64 48 40
'0011' 96 56 48
'0100' 128 64 56
'0101' 160 80 64
'0110' 192 96 80
'0111' 224 112 96
'1000' 256 128 112
'1001' 288 160 128
'1010' 320 192 160
'1011' 352 224 192
'1100' 384 256 224
'1101' 416 320 256
'1110' 448 384 320
'1111' forbidden forbidden forbidden
&amp;#61656; ID
算法标识位,“1”表示MPEG音频,“0”保留。
&amp;#61656; Layer
用来说明是哪一层编码,如表格 2 1 Layer所示。
&amp;#61656; Protection_bit
用来表明冗余信息是否被加到音频流中,以进行错误检测和错误隐蔽。“1”表示未增加,“0”表示增加。
&amp;#61656; Bitrate_index
用来指示该帧的bitrate,如表格 2 2 Bitrate_index所示。
&amp;#61656; Sampling_frequency
用来指示采样频率,如表格 2 3 Sampling_frequency所示。
表格 2 3 Sampling_frequency
sampling_frequency frequency specified (kHz)
'00' 44.1
'01' 48
'10' 32
'11' reserved
&amp;#61656; Padding_bit
如果该位为1,那么帧中包含一个额外槽,用于把平均位率调节到采样频率,否则该位必须为0。在采样频率为44.1kHz时,填补是必要的,在自由格式中也可能需要填补。
&amp;#61656; Private_bit
留做私用,没有定义。
&amp;#61656; Mode
定义通道模式,如表格 2 4 Mode所示。
表格 2 4 Mode
mode mode specified
'00' stereo
'01' joint_stereo (intensity_stereo and/or ms_stereo)
'10' dual_channel
'11' single_channel
&amp;#61656; Mode_extension
用来标识采用了哪一种joint_stereo,具体对应的频带范围隐含在算法中,如表格 2 5 Mode_extension所示。
表格 2 5 Mode_extension
mode_extension
'00' subbands 4-31 in intensity_stereo, bound==4
'01' subbands 8-31 in intensity_stereo, bound==8
'10' subbands 12-31 in intensity_stereo, bound==12
'11' subbands 16-31 in intensity_stereo, bound==16
&amp;#61656; Copyright
表明版权用,“1”表示有版权,“0”表示没有版权。
Original/copy :表明原版还是复制,“1”表示原版,“0”表示复制。
Emphasis :表明加重音类型,如表格 2 6 Emphasis所示。
表格 2 6 Emphasis
emphasis emphasis specified
'00' none
'01' 50/15 microseconds
'10' reserved
'11' CCITT J.17
 
2.2.2. Error Check
CRC 校验的基本思想是利用线性编码理论,在发送端根据要传送的k 位二进制码序列,以一定的规则产生一个校验用的监督码(既CRC 码)r 位,并附在信息后边,构成一个新的二进制码序列数共(k+r)位,最后发送出去。在接收端,则根据信息码和CRC码之间所遵循的规则进行检验,以确定传送中是否出错。在MP3协议中采用了CRC-16生成CRC码,其生成多项式如下:

2.2.3. Side information
Side information 指的是在audio_data中main_data之前的一部分信息。这部分提供了解码中一些辅助的信息,用来帮助整个解码过程。为了帮助理解这一部分数据项的含义,会在下面大致阐述mp3解码所用的基本概念。
&amp;#61656; Main_data_begin
表示一帧数据main data的开始位置。它表示main data相对于该帧同步头的负偏移。这里涉及到一个bit reservoir的技术,它改变了每帧的可用比特数为常数的限制,而是围绕一个长时间的平均值(目标比特率)变化。因为MP3的编码方式是采用Huffman编码,所以编码后每一帧的数据长度是不一样的,可能有的大于目标比特率为每一帧分配的空间,有的可能小于这个空间,所以为了增加空间利用率,当前帧未使用完的空间可以保存起来留给后面需要的帧使用,因此每一帧的main data开始位置可能在它的header和side information之前,而main_data_begin
就是用来指示这个开始位置的,这种技术就叫做bit reservoir。
&amp;#61656; Private_bits
留做私用。
&amp;#61656; Scfsi、scalefac_compress
参考2.3.4 缩放因子(scalefactor)
&amp;#61656; Part_2_3_length
表示main data中scalefactor和huffman数据所占用的比特数。
&amp;#61656; Global_gain
全局量化步长。
&amp;#61656; Window_switching_flag、block_type和mixed_block_flag
参考2.3.5 节的长短块切换
&amp;#61656; Table_select、big_values、count1_table_select、region0_count和region1_count
参考2.3.2 Huffman码表的选择
&amp;#61656; Subblock_gain
短窗块量化时所用的增益偏移量。
&amp;#61656; Preflag和scalefac_scale
在反量化过程中对压缩数据还原时用到的变量。
2.3. Mp3解码算法所用的基本概念
2.3.1. 子带和缩放因子频带
压缩之后的mp3数据是以一桢为单位的,每一桢分为两节(granule),这两节在编解码时相对独立,从每一节中可以解码出576个pcm数据,两节可解出1152个pcm数据。从二进制101……码流中得到我们所需要的信息的第一步就是huffman解码,huffuman编码信息存放在每一节中的Huffmancodebits( )中,通过huffman解码可以得到576个值,这576个值在不同节类型(参考2.3.5 节的长短块切换)下有不同的含义,下面分情况描述:
&amp;#61557; 该节为长块
这576个值代表576条频率线上的值,它们是时域中576个pcm值经过时频变换的结果。这576条频率线从低到高分为32个子带,每个子带包含18条频率线。解出来的这576个值是整数,需要进行反量化变成浮点数,反量化的过程并不是一条频率线为单位进行的,而是若干条频率线为单位进行的,这若干条频率线组成了频带(band),叫做缩放因子频带(scalefactor band),顾名思义,在一个缩放因子频带内的频率线在反量化时共用缩放因子。在44.1khz的采样率下,缩放因子频带的划分如所示:
表格 2 7 长块的缩放因子频带划分
scalefactor band width of band index of start index of end
0 4 0 3
1 4 4 7
2 4 8 11
3 4 12 15
4 4 16 19
5 4 20 23
6 6 24 29
7 6 30 35
8 8 36 43
9 8 44 51
10 10 52 61
11 12 62 73
12 16 74 89
13 20 90 109
14 24 110 133
15 28 134 161
16 34 162 195
17 42 196 237
18 50 238 287
19 54 288 341
20 76 342 417

其中,频率线418至575不需要归属于某一个scalefactor band, 因为属于这一个频带的频率线在进行反量化时,系统提供默认的反量化因子。
&amp;#61557; 该节为短块
这576个值代表192条频率线上的值,这192条频率线从低到高分为32个子带,每个子带包含6条频率线。每一条频率线上有三个值,分别属于三个窗(window0、window1和window2)。这192条频率线被划分为若干缩放因子频带,在44.1khz情况下,划分方式如下:
表格 2 8 短块的缩放因子频带划分
scalefactor band width of band index of start index of end
0 4 0 3
1 4 4 7
2 4 8 11
3 4 12 15
4 6 16 21
5 8 22 29
6 10 30 39
7 12 40 51
8 14 52 65
9 18 66 83
10 22 84 105
11 30 106 135

其中,频率线136至192不需要归属于某一个scalefactor band, 因为属于这一个频带的频率线在进行反量化时,系统提供默认的反量化因子。按先后顺序解出来的这576个值先是按缩放因子频带从低到高排列,在每一个缩放因子频带内,按window0,window1,window2排列,在每一个window中,频率线从低到高排列。
&amp;#61557; 该节是混合块
在这种情况下,按先后顺序解出来的576个值分为两部分,第一部分(前36个值)是长块部分,故它们代表36条频率线,这36条频率线(参考表格 2 7 长块的缩放因子频带划分)划分为8个缩放因子频带;第二部分(后540个值)是短块部分,它们代表180个频率线,每个频率线上有三个值,分别属于window0、window1和window2,这180个频率线(参考表格 2 8 短块的缩放因子频带划分)划分为9个缩放因子频带(scalefactor band3&amp;#61664;scalefactor band11)。
综合上述三种情况,这576值排列方式如下所示:

图 2 1不同情况下huffman解码得到的576个值的含义
2.3.2. Huffman码表的选择
从Huffmancodebits( )中解码得到576个值的过程不是一个简单的查表过程,这涉及到换表的过程。在解码时,当从一个缩放因子频带过渡到另一个缩放因子频带时,huffman码表可能需要改变。Huffman解码得到的576个值分为三个部分,如下所示:

图 2 2 bigvalues和count1的含义
在大值区(xxx),得到的值较大,一共有bigvalues*2个值,每两个值一起编码;在小值区(---),值只能为-1,0,+1,一共有count1*4个值,每四个值一起编码;在零值区(000)值为零,不需要编码。
在不同区域编码时,用到的huffman表是不一样的。
&amp;#61557; 在大值区编码时,为了进一步提高编码效率,大值区又分为三个区域:region0、region1和region2,在不同区域用不同的huffman表编码。region的划分是以缩放因子频带为单位划分的。在side information中,region0_count[gr][ch]和region1_count[gr][ch]提供了划分信息。region0_count+1表示在region0区的缩放因子频带的个数,region1_count+1表示在region1区的缩放因子频带的个数。需要说明的是,如果是短块或者混合块中的短块部分,一个缩放因子频带被计数三次,例如,对于短块来说,region0_count为8意味着region1从scalefactor band 3开始。Region2区的长度在side information中并没有给出,但是根据big_values[gr][ch]、region0_count和region1_count可以计算出来。在得到大值区region的划分之后,就可以根据table_select[gr][ch][region]来选择在每个区域所用的huffman码表,一共有32个huffman码表可供选择,在mp3官方协议错误!未找到引用源。AnnexB Table 3-B.7中给出了这32个表。
&amp;#61557; 在小值区,所用huffman表的选择信息由count1table_select[gr][ch]提供。需要说明的是,小值区的长度是count1*4,虽然在side information中并没有count1,但解码程序知道在耗尽part2_3_length[gr][ch]长度的码流之后就可以判断已经达到了小值区的末尾。

2.3.3. huffman码表的特点
大值区的huffuman表一个入口项可得到两个值,小值区的huffman表一个入口项可得到四个值。大值区的huffman表有一个参数为linbits(见2.1.7)。当linbit为0时,该huffman表只能用来编码小于等于15的数。当linbit不为0时,该huffman表可用来编码值大于15的数,当用这样的huffman码表编码时,在hcod[|x|][|y|]之后的码流中有linbit位,这长度为linbit的位串表示无符号整数,它与x(或者y)相加后表示x(或者y)真正的编码值。
2.3.4. 缩放因子(scalefactor)
如前所述,一个缩放因子频带内的频率线在反量化时共用缩放因子,在码流中,缩放因子被编码于main_data中(见2.1.6)。要解码得到缩放因子,首先需要知道该缩放因子所占的比特数,在side information中scale_compress[gr][ch]提供了这样的信息,首先需要查找如下表格:
表格 2 9 scale_compress
scale_compress slen1 slen2
0 0 0
1 0 1
2 0 2
3 0 3
4 3 0
5 1 1
6 1 2
7 1 3
8 2 1
9 2 2
10 2 3
11 3 1
12 3 2
13 3 3
14 4 2
15 4 3
下面针对不同的节(块)类型说明slen1和slen2的含义。
&amp;#61557; 该节为长块
slen1表示缩放因子频带0到10所用缩放因子的长度;slen2表示缩放因子频带11到20所用缩放因子的长度。
&amp;#61557; 该节为短块
slen1表示缩放因子频带0到5所用缩放因子的长度;slen2表示缩放因子频带6到11所用缩放因子的长度。
&amp;#61557; 该节为混合块
在这种情况下,长块部分(sfb0到sfb7)和短块部分(sfb3到sfb5)所用的缩放因子的长度相同,为slen1;短块部分(sfb6到sfb11)所用的缩放因子长度相同,为slen2。
为了进一步地减少mp3码流的大小,节1(granule1)有时会共用节0(granule 0)的缩放因子信息,是否共用由字段scfsi[scfsi_band]来决定,如下所示:
表格 2 10 scfsi
scfsi[scfsi_band]
0 scalefactors are transmitted for each granule
1 scalefactors transmitted for granule 0 are also valid for granule 1
表格 2 11 scfsi_band
scfsi_band scalefactor bands (see Annex B,Table3-B.8)
0 0,1,2,3,4,5
1 6,7,8,9,10
2 11…15
3 16…20
只有granule1的长块才可以共用前一节的缩放因子信息,对于短块来说,scfsi为0。知道缩放因子的共用就不难理解在2.1.6(Main_data)中位流的组织形式。
2.3.5. 节的长短块切换
节的类型由block_type来定义,如果window_switching_flag未置位,那么block_type的值为0。如果window_switching_flag置位,那么block_type由字段block_type[gr][ch]给出,如下所示:
表格 2 12 block_type
block_type[gr]
0 reserved
1 start block
2 3 short windows
3 end block
当block_type为0、1、3时,该节属于长块。当block_type为2时,如果mixed_block_flag[gr][ch]为0,则该节为短块;mixed_block_flag[gr][ch]为1,则该节为混合块。长块和短块在解码时算法有较大区别。
2.4. mp3解码具体流程
MP3解码的流程如下所示,解码的主要过程包括Preprocessing、Huffman decoding、Requantization、Reordering、Stereo decoding、Alias reduction、IMDCT、Frequency inversion、Synthesis filter bank,最后输出原始的PCM数据。

图 2 3 解码流程图
2.4.1. 预处理(Preprocessing)
这个步骤主要是完成Header和Side information的解码,得到后面解码所需要的一些信息,并保存起来。
2.4.2. Huffman decoding
在2.3.1(子带和缩放因子频带)和2.3.2(Huffman码表的选择)中已经详细介绍了,在这里就不再重叙。
2.4.3. 反量化(Requantization)
经过Huffman解码之后的值必须经过反量化的处理,反量化过程根据使用的windows使用不同的反量化运算公式,其反量化的公式如下:
&amp;#61557; 短块:

公式 2 1
&amp;#61557; 长块:

公式 2 2
&amp;#61557; 混合块:
对于短块部分,按公式 2 1反量化;对于长块部分,按公式 2 2反量化。参考(图 2 1不同情况下huffman解码得到的576个值的含义)。
isi表示是第i个完成Huffman decoding的值,先将该值开4/3次方,这步一般通过查表完成。global_gain及preflag的值可以从side information中得到,当side information中的scalefac_scale=0时,scalefac_multiplier=0.5,scalefac_scale=1时则scalefac_multiplier=1,scalefac_l及scalefac_s为从scale_factor 所解出来的量化因子的值,preflag则是MP3标准中规定中所设定的常数值,而210则是系统中需要用来衡量的一个标准值。
2.4.4. 重排序(Reordering)
MP3编码器为了使Huffman编码更加有效率,对短块和混合块中的短块部分进行了Reordering,因此解码器要按照这个Reordering的方法Reverse Reordering。需注意,该步骤只作用于短块和混合块中的短块部分。
2.4.5. 立体声解码(Stereo decoding)
在这里,假设两个声道独立编解码,不对立体声进行解释。有关立体声处理的详细信息,请参考mp3官方协议。
2.4.6. 混叠消除(Alias reduction)
为了避免相邻的两个子频带之间的混迭,在编码和解码中都需要进行alias reduction去混迭的处理,这个运算可以看成是对任意两个相邻子频带连续做8次的butterfly的运算,该运算只对长块和混合块中的长块部分使用。具体算法如下:
for(sb=1;sb<32;sb++)
for(i=0;i<8;i++){
xar[18*sb-1-i]=xr[18*sb-1-i]Cs-xr[18*sb+i]Ca
xar[18*sb+i]=xr[18*sb+i]Cs+xr[18*sb-1-is]Ca
}
更形象一点,用图表示如下:

图 2 4 混叠消除示意图
2.4.7. IMDCT变换
对于长块及混合块中的长块部分,IMDCT transform作用在一个子带的18个频率线上,产生36个输出;对于短块以及混合块中的短块部分,IMDCT transform作用在一个子带的6个频率线上,产生12个输出,连续作用三次,则也产生36个输出,IMDCT transform的公式如下所示,长块时n为36,短块时n为12。

做完IMDCT transform之后,还要对输出的36个值做加窗运算,窗口函数是根据side information中的block_type决定的,窗口函数与block_type之间的关系如下:
&amp;#61557; block_type=0 (normal window)

&amp;#61557; block_type=1 (start block)

&amp;#61557; block_type=3 (stop block)

&amp;#61557; block_type=2 (short block)


对于长块,属于前三种情况其中一种;对于短块,属于最后一种情况;对于混合块,长块部分属于第一种情况, 短块部分属于最后一种情况。
最后一个步骤是对32个子频带中所计算出来的 进行overlapping,它是将当前子带计算出来的36个值的低18个值与前一个块相应子带计算出来的36个值的高18个值进行重叠相加,当前子带的后18个值被保存起来,用在下一个块中。公式如下:

在进行IMDCT变换之后,不再有长块、短块的概念,只需知道得到的576个值从低到高分为32个子带,每个子带18个值。
2.4.8. 子带合成滤波(Synthesis filter bank)
这部分是MP3解码的最后一个部分了,它负责从IMDCT的输出值中把PCM值还原出来,它可以分成五个步骤,首先是Matrixing运算,它从32个子带的每个子带中取出一个值组成32个值送入一个矩阵中进行运算,然后把输出的64个结果放入一个1024的先入先出(FIFO)的缓存中,接着从1024值中取出一半,组成一个512矢量,并对这512矢量进行加窗运算,加窗系数Di由mp3官方协议AnnexB Table3-B.3提供。最后将加窗结果进行叠加生成32个时域pcm输出,具体流程如下图所示,其中
 
有没有使用delphi编写的
 
to 江上游者:
有啊.有个开源的mmpalyer,带有mp3解码算法...

top 希望有人能给出其它音频格式的算法
 
顶部