rtp负载mp3音频

43 篇文章 0 订阅

最近有客户要求在进行rtsp拉流时希望音频是mp3,而我们常规支持的只有常用的g711a,u这些。所以开始查找资料进行探索,目前rtp负载mp3有两种方式,一种是 rfc3119文档描述的方法把音频数据累积,然后提取出ADU数据作为一帧音频数据通过rtp发送出去,第二种就是 rfc2250文档描述的在每帧音频头前再加4个字节的头,两种方法的差异性在我看来是rfc2250文档描述的方法较简单,实现比较容易,rfc3119文档描述的方法较麻烦,优点是丢包后带来的音频解码影响相对较小. 经过两周的折腾,终于把两种方法都实现了,使用vlc都可以听到清晰的音频,现在来说说这两周中遇到的坑。

由于我们是嵌入式设备,内存和资源以及处理能力都比较有限,所以设备没有采用MPEG1 Layer3 和MPEG2 Layer3这两种官方标准音频格式编码,而是用的MPEG2.5 Layer3, 好处是采样率支持8k采样率,耗费设备资源性能较小. 坑就是这个MPEG2.5 ,在官方RFC文档中没有这个MPEG2.5的相关描述,它是一个非标准的编码格式,在解音频帧 side_info头信息时,官方文档中描述 side_info的长度有32,17,9 三种,根据编码方式和单双声道的不同而不同,而这个MPEG2.5 我无法确定其side_info的长度,就把这三个都试了一遍,结果解析出来的音频都不对,后面陷入瓶颈,只好老老实实去看live555的源码,live555支持rtp上传mp3,最后发现MPEG2.5单声道的side_info的长度是9字节,并且我之前写的解析ADU数据的解析方法也写错了,移位的时候写错了长度,导致解析出来的数据全是错的,所以无法正确解析音频。通过参考live555的源码,我修改了自己的代码,完成了对两种负载方法实现.

第一种rfc2250实现方法:
在mp3音频数据的帧头前加4个字节,如下图rfc2250文档描述,实际可以是4个0字节.

3.5 MPEG Audio-specific header

   This header shall be attached to each RTP packet at the start of the
   payload and after any RTP headers for an MPEG1/2 Audio payload type.

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |             MBZ               |          Frag_offset          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

           Frag_offset: Byte offset into the audio frame for the data
                        in this packet.

这里需要保证rtp负载的是一帧完整的mp3音频帧,mp3音频帧可以通过前四个字节的头信息计算出这帧音频的长度,可以用此方法判断自己拿到的音频帧是否是完整的音频帧,mp3实时采样时位率是变化的,所以音频帧的长度并不固定,这里贴一个简单的头部解析图,是我之前分析时随手写的

FF E3 38 C4: 4字节头
1111 1111 1110 0011 0011 1000 1100 0100

FF E3 28 C4: 4字节头  位率是变化的
1111 1111 1110 0011 0010 1000 1100 0100

FF E3 48 C4: 4字节头  位率是变化的
1111 1111 1110 0011 0100 1000 1100 0100

同步信息 11 bit: 1111 1111 111

版本 2 bit: 00                                00-MPEG2.5   01-未定义   10-MPEG2     11-MPEG1

层 2 bit: 01                                  00-未定义    01-Layer3   10-Layer2    11-Layer1

CRC校验 1 bit: 1                              0-校验       1-不校验

位率 4 bit: 00 11                             24kbps    (16kbps) 

采样频率 2 bit: 10                            8kHZ

帧长调节 1 bit: 0                             0-无需调整        1-需要调整

保留字 1 bit: 0                               没有使用

声道模式 2 bit: 11                            00-立体声Stereo  01-Joint Stereo  10-双声道     11-单声道

扩充模式 2 bit: 00                            当声道模式为 01 时才使用

版权 1 bit: 0                                 0-无版权  1-有版权

原版标志 1 bit: 1                             0-非原版  1-原版

强调方式 2 bit: 00                            00-未定义

下文摘自互联网,文章末尾会标注出处。

**表2.1.1 MP3帧头字节说明**表
名称位长
说明
同步信息11所有位均为1,第1字节恒为FF>
版本200-MPEG 2.5 01-未定义 10-MPEG 2 11-MPEG 1
200-未定义 01-Layer 3 10-Layer 2 11-Layer 1
CRC校验10-校验 1-不校验
比特率4单位是kbps,例如采用MPEG-1 Layer 3,128kbps是,值为1001
具体参数对应比特率表
采样率2采样频率,对于MPEG-1: 00-44.1kHz 01-48kHz 10-32kHz 11-未定义
对于MPEG-2: 00-22.05kHz 01-24kHz 10-16kHz 11-未定义
对于MPEG-2.5: 00-11.025kHz 01-12kHz 10-8kHz 11-未定义
帧长调节1用来调整文件头长度,0-无需调整,1-调整,具体调整计算方法见下文
保留字1没有使用
声道模式2表示声道, 00-立体声Stereo 01-Joint Stereo 10-双声道 11-单声道
扩充模式2当声道模式为01是才使用
Value   强度立体声    MS立体声
00             off             off
01             on              off
10             off              on
11              on             on
版权1文件是否合法,0-不合法 1-合法
原版标志1是否原版, 0-非原版 1-原版
强调方式2用于声音经降噪压缩后再补偿的分类,很少用到,今后也可能不会用。
00-未定义 01-50/15ms 10-保留 11-CCITT J.17

**表2.1.2 MP3数据帧比特率表**
bits
V1,L1
V1,L2
V1,L3
V2,L1
V2,L2
V2,L3
0000
free
free
free
free
free
free
0001
32
32
32
32(32)
32(8)
8(8)
0010
64
48
40
64(48)
48(16)
16(16)
0011
96
54
48
96(56)
56(24)
24(24)
0100
128
64
56
128(64)
64(32)
32 (32)
0101
160
80
64
160(80)
80(40)
64 (40)
0110
192
96
80
192(96)
96(48)
80 (48)
0111
224
112
96
224(112)
112(56)
56 (56)
1000
256
128
112
256(128)
128(64)
64 (64)
1001
288
160
128
288(144)
160(80)
128 (80)
1010
320
192
160
320(160)
192(96)
160 (96)
1011
352
224
192
352(176)
224(112)
112 (112
1100
384
256
224
384(192)
256(128)
128 (128)
1101
416
320
256
416(224)
320(144)
256 (144)
1110
448
384
320
448(256)
384(160)
320 (160)
1111
bad
bad
bad
bad
bad
bad
V1 - MPEG 1 V2 - MPEG 2 and MPEG 2.5 L1 - Layer 1 L2 - Layer 2 L3 - Layer 3 "free" 表示位率可变 "bad" 表示不允许值
### 2.2.2、CRC校验
    如果帧头的校验位为0,则帧头后就有一个16位的CRC值,这个值是big-endian的值,把这个值和该帧通过计算得出的CRC值进行比较就可以得知该帧是否有效。
例子中是校验值为0,需要进行校验。CRC校验值即是 帧头的后2个字节:06 9B
CRC校验本文不做详细介绍。

###2.2.3、 MP3帧长的计算
MP3帧长取决于位率和频率,计算公式为:

Size=((采样个数 * (1 / 采样率))* 帧的比特率)/8 + 帧的填充大小

a),帧的填充大小就是第23位的帧长调节,不是0就是1。

**b),**采样个数:MPEG的不同规范(MPEG-1/2/3),以及同一规范中不同的 Layer(Layer I/II/III),每一帧所对应的采样数,都是固定的,其具体的值参见下表:

表 2.2.2 MPEG帧的采样数索引表(单位:个/帧)

MPEG 1
MPEG 2(LSF)
MPEG 2.5(LSF)
Layer 1
384
384
384
Layer 2
1152
1152
1152
Layer 3
1152
576
576

对于Mp3格式,MPEG 2.5 Layer3 采样个数是固定的576,
Size = ((每帧采样数/8*比特率)/采样频率)+填充
例:
如2.2.1中的数据,比特率为16K,采样率为8K,填充0,则其帧长度为:
(576* 16K/8)/8K +0= 144 (字节)

###2.2.4、Side Info(通道信息)
    在帧头后边是Side Info(姑且称之为通道信息)。对标准的立体声MP3文件来说其长度为32字节。通道信息后面是Scale factor(增益因子)信息。当解码器在读到上述信息后,就可以进行解码了。 图2.2.1中是紧接着校验位的后32字节的数据。
帧边信息解码的主要目的在于找出解这帧的各个参数,包括主数据开始位置,尺度因子长度等。帧边信息如图2.2.4-1所示。

图2.2.4-1 side info

在这里插入图片描述
这里写图片描述 其中,main_data_begin(主数据开始)是一个偏移值,指出主数据是在同步字之前多少个字节开始。需要注意的是,1.帧头不一定是一帧的开始,帧头CRC校验字和帧边信息在帧数据中是滑动的。2.这个数值忽略帧头和帧边信息的存在,如果main_data_begin = 0, 则主数据从帧边信息的下一个字节开始.
这里要细说main_data_begin,之前做的的时候好久都没搞清楚它的意思,简单的说,例如,从当前帧side_info数据中算出AUD数据的size是500, main_data_begin是380,则表示要从前面几帧音频数据中读到380字节数据,再从当前帧中读到120字节的数据,新的AUD帧的头信息要用当前mp3帧的头,头信息包含4字节头和边信息。

第二种rfc3119实现方法,收取到音频帧后把数据放入链表中,通过每一帧中的main_data_begin和ADU size来判断前面累积的音频数据是否够一帧ADU数据(累积的数据只算frame_date,不算4字节头和side_info的数据),如果前面累积的frame_date_size大于或者等于main_data_begin,则开始取ADU数据,方法是往前偏移main_data_begin字节开始取数据,不算头信息和side_info,取到足够main_data_begin的数据后再从当前mp3帧取剩下的数据,最终组成新的AUD帧,长度是前面计算出的ADU size.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿木小呆呆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值