AAC音频能力协商问题 9


视频会议中,通常音频能力的比较是比较简单的,通常是只是比较一下格式就行了。但是aac系列音频就是一个例外。它有一个复杂的能力表示方式,在交互的时候也不会明确的指明确切的采样率,通道数,而是像264格式一样,给出的是能力的level上限,需要我们去匹配比较。这里简单的介绍一下aac能力,和工作中碰到的问题的总结。

案例描述

视频会议的能力协商中关于音频的问题一般都集中在aac上,特别是在对外厂商的对通过程中这个问题尤其突出。这个案例就介绍一下aac能力描述和工作中碰到的例子加以说明。

案例分析

首先我来介绍下aac在H245中的表示。

AAC LD in H.245

AAC LD in H.245

这是一个最常见的aac-ld能力,通过抓包我们发现,aac-lc主要包含了profileAndLevel、formatType、maxal-sduFrames、audioObjectType、audioSpecificConfig这5个参数,还有其他很多的参数比如maxAudioObject、muxConfigPresent、streamMuxConfig、errorProtection_SpecificConfig、EP_DataPresent等等,其中就前面5个是主要的参数主要用于aac-lc、后面几个参数通常是用于aac-ld。我对于这些参数的初略的了解了一下,因为很多东西对与我们能力对通来说并没有帮助,而且要彻底的理解这些参数要理解aac的编解码过程。其中最重要的就是profileAndLevel、audioObjectType、audioSpecificConfig、streamMuxConfig和formatType这几个参数基本上能确定这个aac能力的大小,和开通道的时候具体的通道数和采样率。下面来具体说明一下这几个重要的参数,以及怎样查找文档。

profileAndLevel:

AAC profileAndLevel这是一张没有截图完整的表,还有下面的的profile值。在日常的应用中我发现这个值实际用到没几个。如果是aac-lc的单声道用的是0x02也就是Main Audio Profile/L2,如果是双声道的那么是0x0f也就是 High Quality Audio Profile/L2。如果是aac-ld单声道那么用的是0x18 Low Delay Audio Profile/L3,双声道的是0x19 Low Delay Audio Profile/L4。这些都是根据不同厂商使用中得出来的。通过14496-3的文档中能查到Low Delay Audio Profile/L4到底是多大的能力

AAC LD Level

AAC LD Level

通过查表我们看到Low Delay Audio Profile L4的能力最大支持2个声道,最大采样率为48K。这里面我们看到他能力描述都是通过最大能力,不是指明确切的单声道还是双声道。而是通过开通到的时候来指定到底开的是单声道还是双声道。这就是解析aac能力的难点。

AAC in H.245 capabilitySet

AAC in H.245 capabilitySet

这个图中standard:0,代表的是profileAndLevel,并且这个profile的值为2代表的是Main Audio Profile/L2。

audioObjectType:

AAC Profile definitions - audioObjectType

AAC Profile definitions – audioObjectType

这个参数比较简单,是一个可选参数,aac-lc就是2表示aac-lc,如果是aac-ld那么就是23。

AAC LC in H.245 capabilitySet

AAC LC in H.245 capabilitySet

这个抓包里面standard:3表示的audioObjectType这个参数,而下面的2就是他的值,表示AAC LC。

formatType

这个值是指示在如下的原始数据格式和音频格式之间的比特流格式类型的选择强制参数。通常这个参数填的都是0,表示原始数据格式。AAC LC in H.245 capabilitySet - formatType这个抓包中standard:1表示formatType这个参数,而NULL表示的是原始数据格式。

audioSpecificConfig

这个参数也是个可选参数,但是他不能再能力集交换的时候出现,也就是说他要出现也只能出现在打开通道的参数中。而且是aaclc的开通道中,(那么aacld的呢,下面个参数会说到)它指示了这个aac-ld能力的具体采样率,和通道数。比如这个例子中

AAC LC in H.245 capabilitySet - audioSpecificConfig

AAC LC in H.245 capabilitySet – audioSpecificConfig

Standard:4表示audioSpecificConfig,他是一个2字节的值具体的值可以通过查看二进制得到

AAC LC in H.245 capabilitySet - audioSpecificConfig - buf

AAC LC in H.245 capabilitySet – audioSpecificConfig – buf

通过上图我们看见这个具体的2个字节的值是0x1288这个两个字节到底是什么意思呢?

AAC LC - audioSpecificConfig - buf AAC Sample Frequancy Definitions AAC Audio Channel Definitions

这张图为我们解释了到底这2个字节代表什么,从第一位开始每一位代表什么都详细的给列出来了。我们不妨以0x1288来解析一下,0x1288 = 0001 0010 1000 1000,根据上图前5个bit也就是00010代表的是aduioObjectType那么就是2,表示为aac-lc,后四个字节表示采样率0101,也就是5,5相应的采样率为emFs32000,也就是32k,我们keda的aac的采样率用的都是这个默认的32k采样率。后面4bit为0001,为1,那么代表这个音频是单声道的emChnl1。后面三个我们不需要关注。这样我们就能确切的知道,打开通道的具体通道数和采样率了,解码器也就知道以怎样的方式解码。

streamMuxConfig

这个参数也是可选的参数,他的性质和audioSpecificConfig一样,也是只能存在于开通道的时候,只不过是上面这个用于aaclc,这个用于aacld,仅此而已。不过这两个参数之间的各个位表示的内容还是有一点关系的。其实streamMuxConfig中表示具体的通道数采样率也是用的audioSpecificConfig,只不过他还多了一些其他的位表示其他的含义。

AAC LD in H.245 capabilitySet - streamMuxConfig

AAC LD in H.245 capabilitySet – streamMuxConfig

这个是一个aacld开通道的时候streamMuxConfig参数,这个参数的具体7个字节含义见14496-3中的关于streamMuxConfig的解释,上面有7个字节表示的语法表他的构成根据不同的参数的值而不同。所以这里很难说清楚。下图是一种常见的情况,其中我们需要注意的是(audioSpecificConfig)和(audioSpecificConfig end)中间这一段,这一段其实就是上面讲的audioSpecificConfig的参数,表示了具体的通道数和采样率。其他参数具体含义我不是很清楚,也不需要搞清楚,因为我们只需要了解通道数,和采样率的具体值。这样其实我们在协议栈抛上来的6个字节当中有选择的解析它的audioSpecificConfig这2个字节的东西。

AAC LD - audioSpecificConfig

到这里,其实已经把aac在视频会议中能力交换中的东西,说明的差不多了。

解决过程

上面介绍了aac的参数,和具体用法。我们还是来看看在实际工作中碰到的问题。Aac对通中出现过很多的问题,因为之前我们的aaclc还算是标准的,但是aacld就不是很标准了,我们aacld开通道的时候带的config参数是aaclc的参数,导致外厂的终端拒绝我们的开通到,所以我们无法开启aacld的双声道通道。通过阅读14496-3协议,我们也把aacld标准化了以后,通道是打开了,但是双方都听不见声音。这个问题后来证实是因为双方的采样率不同导致的,我们自己的aacld采样率使用的32k的,但是大多数的外厂aacld的采样率都是用的48k的。所以导致双方无法解码。

总结

这个案例主要介绍一下aac的详细描述,以及其使用的方法。他的主要难点是他不像其他音频是指定了采样率,通道数。aac在能力交换的时候不会指定具体的能力,而是给出一个最大的能力,指示其能够最大支持到几通道,最大的采样率为多少。这和h264有点类似,所以处理起来比较麻烦。但是只要使用好h_245和14496-3这两个文档,遇到问题查一下就能搞清楚。


Leave a comment

Your email address will not be published. Required fields are marked *

9 thoughts on “AAC音频能力协商问题

  • Regan

    我按照你说的,我们跟别的厂家互联的时候,传输AAC_LD的时候,别的厂家还是不能播放声音,我们都是48K.

  • Regan

    这个是我AAC_LD参数配置,这个参数配置有什么问题?
    char m_Info[] ={0x41, 0x01, 0x73, 0x1a};
    struct PluginCodec_H323GenericParameterDefinition AAC_LD_h323params[] =
    {
    {{1,0,0,0,0},2, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {2}},
    {{1,0,0,0,0},5, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMin, {1}},
    {{0,0,0,0,0},0, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMax, {24}},
    {{0,0,0,0,0},1, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_logical, {0}},
    {{0,0,0,0,0},3, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_unsignedMax, {23}},
    {{0,1,0,1,0},8, PluginCodec_H323GenericParameterDefinition::PluginCodec_GenericParameter_octetString, {octetstring:m_Info}},
    };

    • Jacky Wei Post author

      两个明显的错误:
      1. AAC LD的streamMuxConfig必须是7个字节。
      2. 0×73, 0x1a必须是根据实际的audio sampleRate, channel算出来的,具体计算方法我在文章中有写。

      • Regan

        我发送的是7个字节 char m_Info[7] = {0x41,0x01,0x73,0x1a,0x00,0x11,0x00};
        在设置formatType :
        Parameter identifier value = 1 ; Parameter = 1(0—->the raw data format,1—->LATM)当我设置为Parameter = 0的时候还需要发送streamMuxConfig 7个字节吗?
        我有两个问题:
        1)在设置formatType抓包standard:1的时候,我修改参数 Parameter = 0(the raw data format模式,logic:NULL)的时候我还需要发送streamMuxConfig 7个字节吗?(我分别发送两种方式,1>发送streamMuxConfig 7个字节;2>没有发送streamMuxConfig7个字节。都不能播放声音,在RAW的模式下我应该怎么处理?)
        2)在设置formatType抓包standard:1的时候,我修改参数 Parameter = 1(LATM模式,)的时候,我发送streamMuxConfig 7个字节,可以和别的厂家链接,能够播放声音。问题:抓包看到 logic:NULL(为什么抓包看到还是NULL,我设置为1应该不是1吗?)

  • neko

    standard:3表示的audioObjectType这个参数 这些参数的数值定义在什么文档中可以查看到?还有就是AAC Profile definitions – audioObjectType这个表在什么文档中的呢?

    • Jacky Wei Post author

      standard:3表示的audioObjectType这个参数的定义位于ITU/T H.245文档中能力集相关的定义。

      AAC Profile definitions – audioObjectType:这个在14496-3中。

  • amay

    我现在在调试和柯达的设备对接,我发过去的音频格式是AAC-LC(raw),单声道,32K采样率,config=01288,但是柯达设备没有声音,柯达设备发出的音频数据,我已经可以解码,以您的经验这会是什么原因,我不清楚需要发送AAC-LC(raw)还是AAC-LC(LATM)还是AAC-LC(adts)?