fdk-aac编解码

前言

最近在调试fdk-aac编解码,总结了一下需要注意的点,代码在公司内网懒得再敲了。本文介绍的是实时码流的编解码。有问题欢迎指出、讨论。

编译

1. fdk-aac开源代码下载:

2. 根据所使用的交叉编译器来设置cmake中的toolchain,例如我是在Hi3516上使用的,toolchain需要设置为hisiv300,就需要在下载的开源代码根目录下CMakeList.txt中添加命令:

# SET (CMAKE_C_COMPILER path) // path代指编译器路径

3. 执行cmake ./

4. 步骤3执行成功后会生成一个Makefile,终端下输入make开始编译

        a) fdk-aac文件夹不可以放在共享目录中(我实在虚拟机中使用的,所以会有共享目录)

        b) 编译成功后会生成libfdk-aac.so、libfdk-aac.so.2、libfdk-aac.so.2.0.2三个文件

5. 使用时需要将3个库都放到lib中

编码

1. 参考开源库中aac_aenc.c中的demo即可实现编码。

2. 需要注意的一点是,每次送入encoder的数据的size是有要求的。

AACENC_InfoStruct aac_info;

/* 中间省略了参数设置、初始化encoder的过程 */

/*
 * input_size: 输入PCM数据的大小
 * channels:通道数
 * frameLength:每帧每个通道的采样点数
 */
int channels = 2; // 2:双通道
int input_size = channels * 2 * aac_info.frameLength;

3. 当然,如果你和我碰到一样的情况,采集的PCM数据大小和input_size不同,也可以通过加一个缓冲buffer来解决。每当采集到PCM数据,就将其存储到缓冲buffer中,当缓冲buffer中数据长度达到input_size时就取出input_size个字节进行编码。

RTP打包

打包编码后的aac数据这位博主写的很详细。

从零开始写一个RTSP服务器(五)RTP传输AAC_JT同学的博客-CSDN博客_rtp发送aac

解码

fdk-aac解码主要有两种模式:RAW模式和ADTS模式。

RAW模式

基本流程如下:

aacDecoder_Open();
aacDecoder_ConfigRaw();
loop{
  aacDecoder_Fill();
  aacDecoder_DecodeFrame();
}
aacDecoder_Close();

1. RAW模式需要在初始化decoder时,调用aacDecoder_ConfigRaw()传入AudioSpecInfo(ASC),这个结构体中存储着送入的raw数据的samplerate、channel等,送数据时需要去掉ADTS头。

2. 自己构建ASC数据可能会出现问题,建议在编码的时候就保存下来。在用fdk-aac编码时调用aacEncInfo()会获取到一个结构体AACENC_InfoStruct,该结构体中最后两个成员confBuf{64}confSize就分别对应ASC和ASC的size。

ADTS模式

基本流程如下:

aacDecoder_Open();
loop{
  /* 添加 增加adts头的代码 */
  aacDecoder_Fill();
  aacDecoder_DecodeFrame();
}
aacDecoder_Close();

1. ADTS模式初始化时不需要传入AudioSpecInfo(ASC),送数据时需要加上ADTS头。我编码时设置的是AAC_LC,采样率48K,双通道。参数不同的可以参考下面图片。

/* 添加ADTS头
 * 一帧完整AAC数据 = ADTS头(7字节) + AAC源数据
 * 
 * aac_frame
 * aac_frame_size
 *
 */

void addADTSHead(unsigned char *aac_frame, int aac_frame_size)
{
    int profile = 2; // AAC_LC
    int freqIdx = 3; // sampleRate: 48K
    int chanCfg = 2; // channel: stero

    aac_frame[0] = 0xFF;
    aac_frame[1] = 0xF1;
    aac_frame[2] = (((profile - 1) << 6) + (freqIdx << 2) + (chanCfg >> 2));
    aac_frame[3] = (((chanCfg & 3) << 6) + (aac_frame_size >> 11));
    aac_frame[4] = ((aac_frame_size & 0x7FF) >> 3);
    aac_frame[5] = (((aac_frame_size & 7) << 5) + 0x1F);
    aac_frame[6] = 0xFC;
}

 

 

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值