目录

前言

1、AAC介绍

2、AAC 格式

一、libfdk_aac介绍

二、libfdk_aac主要API介绍

1、AACENC_ERROR aacEncOpen(HANDLE_AACENCODER *phAacEncoder,const UINT encModules,const UINT maxChannels);

2、AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER  hAacEncoder,const AACENC_PARAM param,const UINT value);

3、AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER  hAacEncoder,AACENC_InfoStruct  *pInfo);

4、AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER  hAacEncoder,const AACENC_BufDesc  *inBufDesc,const AACENC_BufDesc  *outBufDesc,const AACENC_InArgs  *inargs,AACENC_OutArgs *outargs);

5、AACENC_ERROR aacEncClose( HANDLE_AACENCODER *phAacEncoder);

三、libfdk_aac编码示例

四、AAC编码器软件框架


《libfdk-aac实现PCM编码AAC代码实现》链接:

https://edu.csdn.net/learn/38258/606136?spm=1003.2001.3001.4157

前言

1、AAC介绍

AAC(高级音频编码) 是一种用于有损数字音频压缩的音频编码标准。作为MP3格式的继承者,AAC 在相同比特率下通常可以实现比 MP3 编码器更高的音质;早在1997 年AAC 已被ISO和IEC 标准化为MPEG-2和MPEG-4规范的一部分。AAC 提供 8 kHz 到 96 kHz 之间的采样频率和 1 到 48 之间的任意数量的通道;默认情况下,AAC编码将使用更长的 1024 点/960 点进行压缩编码。AAC属于MPEG-2和MPEG-4规范的一部分,具有复杂的规格,共分为9种规格/档次,如下:
MPEG-2 AAC:
    1、MPEG-2 AAC LC低复杂度规格(Low Complexity);
    2、MPEG-2 AAC Main主规格;
    3、MPEG-2 AAC SSR可变取样率规格(Scaleable Sample Rate);
MPEG-4 AAC:
    4、MPEG-4 AAC LC低复杂度规格(Low Complexity),现在的手机比较常见的MP4格式中的音频部份就包括了该种规格的音频;
    5、MPEG-4 AAC Main主规格;
    6、MPEG-4 AAC SSR可变取样率规格(Scaleable Sample Rate);
    7、MPEG-4 AAC LTP长时期预测规格(Long Term Predicition);
    8、MPEG-4 AAC LD低延迟规格(Low Delay);
    9、MPEG-4 AAC HE高效率规格(High Efficiency)。

2、AAC 格式

MPEG-2 中定义了AAC的两种格式分别用于文件存储的ADIF(音频数据交换格式),以及用于传输流中传输数据的ADTS(音频数据传输流)格式。

ADIF格式的AAC音频流由ADIF头数据和AAC音频流组成,通常一个文件中只有一个ADIF头,也就是说ADIF格式的AAC解码必须从文件头部第一帧开始解码。如下图所示在AAC 编码数据流之前有一个ADIF的头信息。
         在AAC标准文档中对ADIF码流格式的介绍如下图1,一个ADIF的音频序列,中首先是ADIF的头,和对齐字节,之后是编码的原始数据流。下图2是ADIF Header的的定义。
                                                                             图1

                                                                图2

在ADTS格式的音频流中每个音频帧头部有包含一个ADTS的头;和ADIF不同ADTS格式的音频可以从任意一帧AAC音频数据进行解码,无需从音频一帧进行解码。ADTS格式的音频数据流如下图所示。

在AAC标准文档中对ADTS码流格式的介绍如下图3;ADTS格式的音频数据通过SyncWord来进行判断下一帧音频。

图3

如下图4,是ADTS格式一帧音频的格式。一帧音频包含了ADTS的固定头adts_fixed_header和可变头adts_variable_header,adts错误检查字段,以及aac编码后的原始数据raw_data_block。

图4

下图5是ADTS的头信息定义,包含了固定头(Fixed Header)和可变头(Variable Header)。可以看出在ADTS的固定头中包含了AAC编码的档次、通道数、采样率索引等。在可变头中包含了帧长度等信息。ADTS的头信息共56Bit(7个字节),在RTP传输ADTS格式的音频时候通常去掉7个字节的ADTS头数据,在解码端重新组装ADTS的头。

图5

一、libfdk_aac介绍

libfdk_aac是一个开源库,用于以AAC 格式对数字音频数据进行编码和解码。它支持多种音频对象类型,包括MPEG-2和MPEG-4 AAC LC、HE-AAC (AAC LC + SBR )、HE-AACv2 (LC + SBR + PS ) 以及AAC-LD (low延迟)和 AAC-ELD(增强低延迟)。编码库支持采样率8~ 96 kHz ,最多可以支持8 个通道(7.1 环绕声)。fdk_aac 支持的音频对象如下表1。

表1

AAC Profile名称 MPEG-4 Audio object type FDK_AAC是否支持
低复杂度 (AAC-LC) 2 YES
高效 (HE-AAC) 2、5 YES
高效版本 2 (HE-AAC) 2、5、29 YES
低延迟 (AAC-LD) 23 YES
增强型低延迟 (AAC-ELD) 39 YES

fdk_aac 支持的音频采样率下表2。

表2

采样率 8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000

libfdk_aac源码下载路径为github:https://github.com/mstorsjo/fdk-aac.git。

二、libfdk_aac主要API介绍

1、AACENC_ERROR aacEncOpen(HANDLE_AACENCODER *phAacEncoder,const UINT encModules,const UINT maxChannels);

该函数用于打开AAC编码器,成功返回0;函数共有3个参数;phAacEncoder:成功打开编码器后返回AAC编码器的句柄;encModules:通常默认0,表示编码器内部分配内存maxChannels:音频通道数,范围1~8。

2、AACENC_ERROR aacEncoder_SetParam(const HANDLE_AACENCODER  hAacEncoder,const AACENC_PARAM param,const UINT value);

该函数用于设置AAC编码器参数。成功返回0;函数共有3个参数;phAacEncoder:编码句柄;param:编码器参数类型详细见表3;value:参数值。param常见的取值如下表3所示,详细类型定义在AACENC_PARAM中;主要包含音频对象规格、码率、采样率、帧长度、声道模式、编码帧类型等。

表3

AAC 参数类型 参数说明 参数取值范围
AACENC_AOT 音频对象类型 2: MPEG-4 AAC Low Complexity等详细见表1
AACENC_BITRATE 编码码率 如64k,96k等
AACENC_BITRATEMODE 码率模式 0:CBR固定码率,1-7其他模式
AACENC_SAMPLERATE 音频采样率 48000,44100等,详细见表2
AACENC_SBR_MODE 音普带复制 在ELD( Enhanced Low-Delay.)下参数配置
AACENC_GRANULE_LENGTH 编码帧长度 1024  512  480
AACENC_CHANNELMODE 声道模式 单声道、双声道、8声道等
AACENC_CHANNELORDER 输入音频声道排列方式 0:采用MPEG声道排列方式。1:采用wav声道排列方式
AACENC_AFTERBURNER 通过消耗内存和CPU来提升音质 0:关闭,1:开启
AACENC_BANDWIDTH 编码带宽 0:编码器内部决定带宽,其他值表示配置等目标带宽
AACENC_TRANSMUX 编码帧类型 0:原始编码帧,1:带有ADIF头的编码帧,2:带有ADTS头的编码帧,其他:6/7/10

3、AACENC_ERROR aacEncInfo(const HANDLE_AACENCODER  hAacEncoder,AACENC_InfoStruct  *pInfo);

该函数用于获取编码器信息。函数有2个参数;hAacEncoder编码器句柄;pInfo:编码器信息。AACENC_InfoStruct的定义如下;主要包含声道数、帧长度、编码延长等。

typedef struct {UINT     maxOutBufBytes;      /*!< Maximum number of encoder bitstream bytes within one frame.Size depends on maximum number of supported channels in encoder instance.For superframing (as used for example in DAB+), size has to be a multiple accordingly. */UINT      maxAncBytes;         /*!< Maximum number of ancillary data bytes which can be inserted intobitstream within one frame. */UINT     inBufFillLevel;      /*!< Internal input buffer fill level in samples per channel. This parameterwill automatically be cleared if samplingrate or channel(Mode/Order) changes. */UINT      inputChannels;       /*!< Number of input channels expected in encoding process. */UINT       frameLength;         /*!< Amount of input audio samples consumed each frame per channel, dependingon audio object type configuration. */UINT      encoderDelay;        /*!< Codec delay in PCM samples/channel. Depends on framelength and AOT. Does notinclude framing delay for filling up encoder PCM input buffer. */UCHAR    confBuf[64];         /*!< Configuration buffer in binary format as an AudioSpecificConfigor StreamMuxConfig according to the selected transport type. */UINT      confSize;            /*!< Number of valid bytes in confBuf. */} AACENC_InfoStruct;

4、AACENC_ERROR aacEncEncode(const HANDLE_AACENCODER  hAacEncoder,const AACENC_BufDesc  *inBufDesc,const AACENC_BufDesc  *outBufDesc,const AACENC_InArgs  *inargs,AACENC_OutArgs *outargs);

该函数用于编码一帧音频数据并输出编码后的音频帧。该函数有5个参数;hAacEncoder:编码器句柄;inBufDesc:输入原始PCM音频数据;outBufDesc:输出编码后的AAC音频数据;inargs:输入原始PCM音频参数,如输入音频所有通道的采样点数;outargs:输出编码后AAC音频参数,如输出AAC帧长度等。

5、AACENC_ERROR aacEncClose( HANDLE_AACENCODER *phAacEncoder);

该函数用于关闭AAC编码器。

三、libfdk_aac编码示例

1、打开编码器,初始化编码器参数

static HANDLE_AACENCODER init_fdk_aac(int sample_rate,int channels,int bitrate)
{HANDLE_AACENCODER handle;CHANNEL_MODE mode;int aot = 2; //lc 低复杂度,算法速度快switch (channels) {case 1: mode = MODE_1;       break;case 2: mode = MODE_2;       break;case 3: mode = MODE_1_2;     break;case 4: mode = MODE_1_2_1;   break;case 5: mode = MODE_1_2_2;   break;case 6: mode = MODE_1_2_2_1; break;default:fprintf(stderr, "Unsupported WAV channels %d\n", channels);return NULL;}//打开aac 编码器if (aacEncOpen(&handle, 0, channels) != AACENC_OK) {fprintf(stderr, "Unable to open encoder\n");return NULL;}//设置算法模式 lc等if (aacEncoder_SetParam(handle, AACENC_AOT, aot) != AACENC_OK) {fprintf(stderr, "Unable to set the AOT\n");return NULL;}//设置编码输入帧长if (aacEncoder_SetParam(handle, AACENC_GRANULE_LENGTH, 1024) != AACENC_OK) {fprintf(stderr, "Unable to set the audio frame length\n");return NULL;}//设置采样率if (aacEncoder_SetParam(handle, AACENC_SAMPLERATE, sample_rate) != AACENC_OK) {fprintf(stderr, "Unable to set the AOT\n");return NULL;}//声道模式if (aacEncoder_SetParam(handle, AACENC_CHANNELMODE, mode) != AACENC_OK) {fprintf(stderr, "Unable to set the channel mode\n");return NULL;}//设置pcm数据格式if (aacEncoder_SetParam(handle, AACENC_CHANNELORDER, 1) != AACENC_OK) {fprintf(stderr, "Unable to set the wav channel order\n");return NULL;}//设置编码码率if (aacEncoder_SetParam(handle, AACENC_BITRATE, bitrate) != AACENC_OK) {fprintf(stderr, "Unable to set the bitrate\n");return NULL;}//设置编码帧为ADTS格式if (aacEncoder_SetParam(handle, AACENC_TRANSMUX, TT_MP4_ADTS) != AACENC_OK) {fprintf(stderr, "Unable to set the ADTS transmux\n");return NULL;}//初始化 handleif (aacEncEncode(handle, NULL, NULL, NULL, NULL) != AACENC_OK) {fprintf(stderr, "Unable to initialize the encoder\n");return NULL;}//获取音频编码信息if (aacEncInfo(handle, &g_aacInfo) != AACENC_OK) {fprintf(stderr, "Unable to get the encoder info\n");return NULL;}return handle;
}

2、关闭编码器

static void deInit_fdk_aac(HANDLE_AACENCODER *pHandle)
{aacEncClose(pHandle);
}

3、编码PCM音频帧为AAC

static int fdk_aac_enc(HANDLE_AACENCODER *pHandle,uint16_t *pInPcmData,int inputSize,uint8_t *pOutBuff,int outBuffsize)
{AACENC_ERROR err;AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 };AACENC_InArgs in_args = { 0 };AACENC_OutArgs out_args = { 0 };int in_identifier = IN_AUDIO_DATA;int out_identifier = OUT_BITSTREAM_DATA;int in_size = inputSize, in_elem_size = 2;while(1){void *in_ptr = pInPcmData;//输入参数和输入buff配置in_args.numInSamples = inputSize <= 0 ? -1 : inputSize/in_elem_size;//输入数据中所有声道采样点个数in_buf.numBufs = 1;   //输入buff个数in_buf.bufs = &in_ptr; //输入PCM音频地址in_buf.bufferIdentifiers = &in_identifier;//输入in_buf.bufSizes = &in_size;  //输入PCM大小in_buf.bufElSizes = &in_elem_size;//每个采样点数据类型(大小)short//输出参数和输出buff配置void * out_ptr = pOutBuff; int out_size = outBuffsize;int out_elem_size = 1;   //输出每个out_buf.numBufs = 1; //输出buff个数out_buf.bufs = &out_ptr;//输出buff的地址out_buf.bufferIdentifiers = &out_identifier;out_buf.bufSizes = &out_size;//输出buff的大小out_buf.bufElSizes = &out_elem_size;//输出数据类型(大小)charif ((err = aacEncEncode(*pHandle, &in_buf, &out_buf, &in_args, &out_args)) != AACENC_OK) {if (err == AACENC_ENCODE_EOF)break;fprintf(stderr, "Encoding failed\n");return 0;}if (out_args.numOutBytes == 0)continue;break;}return out_args.numOutBytes;
}

四、AAC编码器软件框架

 AAC编码代码实现请参考 <音频数据进行AAC编码课程>

libfdk_aac编码AAC相关推荐

  1. libfdk_aac解码AAC

    目录 一.前言 二.libfdk_aac节解码API介绍 三.libfdk_aac节解码示例 四.libfdk_aac节解码框架 <libfdk-aac实现AAC解码代码实现>链接: ht ...

  2. 【Android RTMP】音频数据采集编码 ( AAC 音频格式解析 | FLV 音频数据标签解析 | AAC 音频数据标签头 | 音频解码配置信息 )

    文章目录 安卓直播推流专栏博客总结 一. AAC 音频格式解析 二. FLV 音频数据标签解析 1. 分析 FLV 格式中的 AAC 音频格式数据 2. AAC 音频特殊配置 3. AAC 音频数据标 ...

  3. 【Android RTMP】音频数据采集编码 ( 音频数据采集编码 | AAC 高级音频编码 | FAAC 编码器 | Ubuntu 交叉编译 FAAC 编码器 )

    文章目录 安卓直播推流专栏博客总结 一. 音频数据采集.编码 二. AAC 高级音频编码 三. FAAC 编码器 四. Ubuntu 18.04.4 交叉编译 FAAC 编码器 安卓直播推流专栏博客总 ...

  4. ffmpeg pcm编码aac

    本博文参考自雷神博客 https://blog.csdn.net/leixiaohua1020/article/details/25430449 这是ffmpeg加上libfdk-aac 将pcm转a ...

  5. ffmpeg编码aac音频

    主要代码如下 #include<stdio.h> #include "libavutil/avutil.h" #include "libavutil/time ...

  6. Android端直播SDK实现方案

    概述 直播系统的架构总体上分为采集模块.预览模块.处理模块.编码模块.推流模块. 把这五个模块串联起来就构成了整个直播系统的数据流.如下图所示: 音频采集:采集原始的PCM数据. 音频处理:对音频进行 ...

  7. pcm编码为aac/MP3格式ffmpeg(八)

    前言 pcm音频是未压缩的数据,占空间,在存储或者传输时一般都会选择先进行有损压缩(比如aac,MP3等等).pcm音频数据在文件存储时一般都按照planner格式存储,例如: 声道1声道2声道3.. ...

  8. PCM 编码为AAC

    PCM 编码为AAC 简介 ffmpeg version 3.4 Copyright (c) 2003-2017 the FFmpeg developersbuilt with Apple LLVM ...

  9. 1小时学会:最简单的iOS直播推流(七)h264/aac 硬编码

    最简单的iOS 推流代码,视频捕获,软编码(faac,x264),硬编码(aac,h264),美颜,flv编码,rtmp协议,陆续更新代码解析,你想学的知识这里都有,愿意懂直播技术的同学快来看!! 源 ...

最新文章

  1. 19 个 JavaScript 常用的简写技术
  2. 页面传值-laber
  3. Python基础知识(第十天)
  4. #ifndef、#def、#endif等宏是什么意思
  5. Azure IoT Edge on Windows 10 IoT Core
  6. 浅谈闪电网络的可行性
  7. spring boot task实现动态创建定时任务
  8. LInux终端中Ctrl+S卡死
  9. 关于K2路由破解锐捷校园认证这件事(ZZU版)
  10. 怎样才能从Java初级程序员成长为一名合格的架构师?
  11. 计算机对写字教学的冲淡,不断改进评价方法努力促进写字教学
  12. html 下拉框设置提示语,为 Html 的 Select 加一个提示语和输入方法
  13. 高级java人员都用过的17个jvm参数
  14. HFSS 快速建立微带线
  15. python 解决问题的集合-No JSON object could be decoded
  16. 蛋白质结构预测的意义、方法、数据库
  17. 读书笔记:《图说区块链》
  18. Microsoft Virtual WiFi Miniport Adapter 使用方法
  19. 在应急响应过程中,有什么好的方法可以寻找某一日期创建的文件?
  20. 队伍不好带!周鸿祎要拆分360业务 鼓励内部创业

热门文章

  1. php中的时间戳_PHP 时间戳 timestamp
  2. 【Gaze】Generating Image Descriptions via Sequential Cross-Modal Alignment Guided by Human Gaze
  3. RMC(AC450)的各种通讯技术
  4. 网站域名被DNS劫持了怎么办?dns被劫持了怎么处理
  5. mysql_d58_ 主键_外键_自增_索引_一对一_多对多_limit_分组_连表操作
  6. 计算机学院家长座谈会,计算机信息技术学院召开新生家长座谈会
  7. android可以剪辑代码的控件,Android 仿抖音视频裁剪范围选择控件,支持本地视频和网络视频...
  8. 数字通信第三章——数字调制方法概念
  9. linux 7 services设定,CentOS 7 systemd service 设置limit,不生效问题
  10. 基于安卓/android/微信小程序的流动人口管理移动APP#计算机毕业设计