Skip to content

LV055-AAC编码 ​

一、封装库 ​

在这里,有介绍多个AAC编码器:Fraunhofer FDK AAC - Hydrogenaudio Knowledgebase

1. FFmpeg (libavcodec) ​

  • 包含完整的AAC编码器(如aac、libfdk_aac)
  • 支持硬件加速(如MediaCodec、VideoToolbox)
  • 跨平台,API稳定,社区活跃

2. fdk-aac ​

质量更高,尤其在低码率下表现优于FFmpeg内置的AAC编码器(如aac)。支持HE-AAC(SBR)和HE-AAC v2(PS),适合对音质要求严格的场景(如音乐流媒体)。

3. 选择哪个? ​

FFmpeg支持的功能较多,视频的封装、解封装这些都支持,但是我这里只需要尝试音频aac编码,所以选下面这个 fdk-aac。

二、编译fdk-aac ​

1. 下载源码 ​

到写这个文档,看起来最新版本是:Release v2.0.3: fdk-aac 2.0.3 · mstorsjo/fdk-aac · GitHub

2. 结构分析与裁剪 ​

2.1 需要哪些函数? ​

c
aacDecoder_Open();
aacDecoder_ConfigRaw();
aacDecoder_Fill();
aacDecoder_DecodeFrame();
aacDecoder_GetStreamInfo();

2.2 解码库关联的库文件 ​

text
1. aacDecoder_Open();						// libAACdec/src/aacdecoder_lib.cpp
	--fmin();								// libFDK/include/common.h
		--fixmin_UI();						// libFDK/include/commonfix.h
	--transportDec_Open();					// libMpegTPDec/src/tpdec_lib.cpp
		--GetRam_TransportDecoder();		// libMpegTPDec/src/tpdec_lib.cpp
		--adtsRead_CrcInit();				// libMpegTPDec/src/tpdec_adts.cpp
			--FDKcrcInit();					// libFDK/src/FDK_crc.cpp
		--GetRam_TransportDecoderBuffer();	// libFDK/include/FDK_bitstream.h
	--transportDec_SetParam();				// libMpegTPDec/src/tpdec_lib.cpp
		--FDK_ResetBitBuffer();				// libFDK/src/FDK_bitbuffer.cpp
	--CAacDecoder_Open();					// libAACdec/src/aacdecoder.cpp
		--GetAacDecoder();					// libSYS/include/genericStds.h
		--FDK_QmfDomain_ClearRequested();	// libFDK/src/FDK_qmf_domain.cpp
		--CAacDecoder_AncDataInit();		// libAACdec/src/aacdecoder.cpp
		--CStreamInfoInit();				// libAACdec/src/aacdecoder.cpp
		--CProgramConfig_Init();			// libMpegTPDec/src/tpdec_asc.cpp
		--CConcealment_InitCommonData();	// libSYS/include/genericStds.cpp
		--GetDrcInfo();						// libAACdec/src/aac_ram.h
		--aacDecoder_drcInit();				// libAACdec/src/aacdec_drc.cpp
		--aacDecoder_drcSetParam();			// libAACdec/src/aacdec_drc.cpp
		--CConcealment_GetDelay();			// libAACdec/src/conceal.cpp
		--GetWorkBufferCore1();				// libAACdec/src/aac_ram.h
		--GetWorkBufferCore2();				// libAACdec/src/aac_ram.h
	--transportDec_Close();					// libMpegTPDec/src/tpdec_lib.cpp
	--FDK_chMapDescr_init();				// libSYS/src/syslib_channelMapDescr.cpp
	--transportDec_RegisterAscCallback();	// libMpegTPDec/src/tpdec_lib.cpp
	--transportDec_RegisterFreeMemCallback();	// libMpegTPDec/src/tpdec_lib.cpp
	--transportDec_RegisterCtrlCFGChangeCallback();	// libMpegTPDec/src/tpdec_lib.cpp
	--FDKmemclear();						// libSYS/include/genericStds.cpp
	--transportDec_RegisterSscCallback();	// libMpegTPDec/src/tpdec_lib.cpp
	--FDK_drcDec_Open();					// libDRCdec/
	--transportDec_RegisterUniDrcConfigCallback();
	--pcmDmx_Open();						// libPCMutils
	--pcmLimiter_Create();					// libPCMutils
	--setConcealMethod();					// libAACdec
	--aacDecoder_Close();					// libAACdec

2. aacDecoder_ConfigRaw();
	--transportDec_OutOfBandConfig();		// libMpegTPDec

3. aacDecoder_Fill();
	--transportDec_FillData();				// libMpegTPDec

4. aacDecoder_DecodeFrame();				// 与以上类似

2.3 需要哪些库? ​

text
libAACdec, libFDK, libMpegTPDec, libSYS, libDRCdec, libPCMutils

2.4 裁剪 ​

本质上是对CMakeList.txt进行修改,使其只编译我们所需要的部分。修改下面这部分:

cmake
set(libfdk_aac_SOURCES
    ${AACDEC_SRC} ${AACENC_SRC}
    ${ARITHCODING_SRC}
    ${DRCDEC_SRC}
    ${MPEGTPDEC_SRC} ${MPEGTPENC_SRC}
    ${SACDEC_SRC} ${SACENC_SRC}
    ${SBRDEC_SRC} ${SBRENC_SRC}
    ${PCMUTILS_SRC} ${FDK_SRC} ${SYS_SRC})

修改为:

cmake
set(libfdk_aac_SOURCES
    ${AACDEC_SRC}
    ${DRCDEC_SRC}
    ${MPEGTPDEC_SRC}
    ${PCMUTILS_SRC} ${FDK_SRC} ${SYS_SRC})

但是这个其实并不准确,调用一些函数的时候报错,查到最后好像就删了ARITHCODING_SRC:

cmake
set(libfdk_aac_SOURCES
    ${AACDEC_SRC} ${AACENC_SRC}
    ${DRCDEC_SRC}
    ${MPEGTPDEC_SRC} ${MPEGTPENC_SRC}
    ${SACDEC_SRC} ${SACENC_SRC}
    ${SBRDEC_SRC} ${SBRENC_SRC}
    ${PCMUTILS_SRC} ${FDK_SRC} ${SYS_SRC})

3. 编译fdk-aac库 ​

shell
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release \
         -DCMAKE_INSTALL_PREFIX="/path/to/install"
cmake --build .
make install

要是想要交叉编译的话,可以直接在fdk-aac-2.0.3文件夹 下创建一个arm_linux_setup.cmake文件,在cmake编译时加载该配置文件即可。arm_linux_setup.cmake文件内容如下:

cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(tools  /home/xxx/toolChain/gcc-arm-linux-gnueabihf)
set(CMAKE_C_COMPILER ${tools}/bin/arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER ${tools}/bin/arm-linux-gnueabihf-g++)

其中gcc -arm-linux-gnueabihf为自己的交叉编译工具链名称。然后可以用下面的命令编译:

shell
mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../arm_linux_setup.cmake \
         -DCMAKE_BUILD_TYPE=Release \
         -DCMAKE_INSTALL_PREFIX="/path/to/install"
cmake --build .
make install

编译完成后会生成对应的动态库:

shell
[ 98%] Building CXX object CMakeFiles/fdk-aac.dir/libSYS/src/syslib_channelMapDescr.cpp.o
[100%] Linking C shared library libfdk-aac.so
[100%] Built target fdk-aac

4. 编译示例 ​

编译示例的话,libfdk_aac_SOURCES 要包含所有的源文件:

shell
gcc test-encode-decode.c sha1.c wavreader.c -I. -I./output/include/fdk-aac/ -L./output/lib -lfdk-aac -lm

内部好像用到了数学库,编译的时候要加上-lm

三、应用示例 ​

参考资料:

【fdk-aac-2.0.3开源库裁剪与交叉编译】-CSDN博客

Last updated: