目录
一、前言
二、libfdk_aac节解码API介绍
三、libfdk_aac节解码示例
四、libfdk_aac节解码框架
《libfdk-aac实现AAC解码代码实现》链接:
https://edu.csdn.net/learn/38258/606146?spm=1003.2001.3001.4157
在
1、HANDLE_AACDECODER aacDecoder_Open(TRANSPORT_TYPE transportFmt,UINT nrOfLayers);
该函数的作用是打开解码器,并返回解码器的句柄。
transportFmt是输入AAC的格式,TRANSPORT_TYPE的定义如下。和实际AAC的格式一样,实时AAC流通常采用TT_MP4_ADTS 的格式。参数nrOfLayers表示AAC流的层数,基本上填1。
typedef enum {
TT_UNKNOWN = -1,
TT_MP4_RAW = 0,
TT_MP4_ADIF = 1,
TT_MP4_ADTS = 2,
TT_MP4_LATM_MCP1 = 6,
TT_MP4_LATM_MCP0 = 7,
TT_MP4_LOAS = 10,
TT_DRM = 12
} TRANSPORT_TYPE;
2、AAC_DECODER_ERROR aacDecoder_Fill(HANDLE_AACDECODER self, UCHAR *pBuffer[],const UINT bufferSize[], UINT *bytesValid);
该函数是将输入的AAC数据拷贝到解码器内部的内存中。 参数self是解码器句柄。pBuffer是输入数据的地址;bufferSize为输入数据的大小。bytesValid是输入数据没有拷贝完剩余的大小。注意当bytesValid不为0的时候剩余的数据要和下一次AAC帧一起组合再次拷贝到解码器内部的内存中。
3、AAC_DECODER_ERROR aacDecoder_DecodeFrame(HANDLE_AACDECODER self, INT_PCM *pTimeData, const INT timeDataSize, const UINT flags);
该函数用于获取解码后的音频数据(通常是PCM)。参数self是解码器句柄;参数pTimeData为解码后输出的音频数据(PCM)的buff;参数timeDataSize为参数pTimeData内存的大小。flags的定义如下,通常可以将flags设置为0.
//触发内置错误隐藏模块以生成一个丢失帧的替代信号
#define AACDEC_CONCEAL 1
//刷新解码器内部所有滤波器组以获得所有延迟数据
#define AACDEC_FLUSH 2
//输入位流数据不连续时重新同步所有内部
#define AACDEC_INTR 4
//清除解码器所有信号延迟线和历史缓冲区
#define AACDEC_CLRHIST 8
4、CStreamInfo *aacDecoder_GetStreamInfo(HANDLE_AACDECODER self);
该函数用于获取解码的信息。参数self是解码器句柄,输出为解码信息,CStreamInfo的定义如下,主要包含解码后的帧大小(采样点个数)frameSize,解码后的音频数据通道数numChannels,解码后的音频数据的采样率sampleRate。
typedef struct {
/* These five members are the only really relevant ones for the user. */
INT sampleRate; /*!< The sample rate in Hz of the decoded PCM audio signal. */
INT frameSize; /*!< The frame size of the decoded PCM audio signal. \n
Typically this is: \n
1024 or 960 for AAC-LC \n
2048 or 1920 for HE-AAC (v2) \n
512 or 480 for AAC-LD and AAC-ELD \n
768, 1024, 2048 or 4096 for USAC */
INT numChannels; /*!< The number of output audio channels before the rendering
module, i.e. the original channel configuration. */
AUDIO_CHANNEL_TYPE
*pChannelType; /*!< Audio channel type of each output audio channel. */
UCHAR *pChannelIndices; /*!< Audio channel index for each output audio
channel. See ISO/IEC 13818-7:2005(E), 8.5.3.2
Explicit channel mapping using a
program_config_element() */
/* Decoder internal members. */
INT aacSampleRate; /*!< Sampling rate in Hz without SBR (from configuration
info) divided by a (ELD) downscale factor if present. */
INT profile; /*!< MPEG-2 profile (from file header) (-1: not applicable (e. g.
MPEG-4)). */
AUDIO_OBJECT_TYPE
aot; /*!< Audio Object Type (from ASC): is set to the appropriate value
for MPEG-2 bitstreams (e. g. 2 for AAC-LC). */
INT channelConfig; /*!< Channel configuration (0: PCE defined, 1: mono, 2:
stereo, ... */
INT bitRate; /*!< Instantaneous bit rate. */
INT aacSamplesPerFrame; /*!< Samples per frame for the AAC core (from ASC)
divided by a (ELD) downscale factor if present. \n
Typically this is (with a downscale factor of 1):
\n 1024 or 960 for AAC-LC \n 512 or 480 for
AAC-LD and AAC-ELD */
INT aacNumChannels; /*!< The number of audio channels after AAC core
processing (before PS or MPS processing). CAUTION: This
are not the final number of output channels! */
AUDIO_OBJECT_TYPE extAot; /*!< Extension Audio Object Type (from ASC) */
INT extSamplingRate; /*!< Extension sampling rate in Hz (from ASC) divided by
a (ELD) downscale factor if present. */
UINT outputDelay; /*!< The number of samples the output is additionally
delayed by.the decoder. */
UINT flags; /*!< Copy of internal flags. Only to be written by the decoder,
and only to be read externally. */
SCHAR epConfig; /*!< epConfig level (from ASC): only level 0 supported, -1
means no ER (e. g. AOT=2, MPEG-2 AAC, etc.) */
/* Statistics */
INT numLostAccessUnits; /*!< This integer will reflect the estimated amount of
lost access units in case aacDecoder_DecodeFrame()
returns AAC_DEC_TRANSPORT_SYNC_ERROR. It will be
< 0 if the estimation failed. */
INT64 numTotalBytes; /*!< This is the number of total bytes that have passed
through the decoder. */
INT64
numBadBytes; /*!< This is the number of total bytes that were considered
with errors from numTotalBytes. */
INT64
numTotalAccessUnits; /*!< This is the number of total access units that
have passed through the decoder. */
INT64 numBadAccessUnits; /*!< This is the number of total access units that
were considered with errors from numTotalBytes. */
/* Metadata */
SCHAR drcProgRefLev; /*!< DRC program reference level. Defines the reference
level below full-scale. It is quantized in steps of
0.25dB. The valid values range from 0 (0 dBFS) to 127
(-31.75 dBFS). It is used to reflect the average
loudness of the audio in LKFS according to ITU-R BS
1770. If no level has been found in the bitstream the
value is -1. */
SCHAR
drcPresMode; /*!< DRC presentation mode. According to ETSI TS 101 154,
this field indicates whether light (MPEG-4 Dynamic Range
Control tool) or heavy compression (DVB heavy
compression) dynamic range control shall take priority
on the outputs. For details, see ETSI TS 101 154, table
C.33. Possible values are: \n -1: No corresponding
metadata found in the bitstream \n 0: DRC presentation
mode not indicated \n 1: DRC presentation mode 1 \n 2:
DRC presentation mode 2 \n 3: Reserved */
INT outputLoudness; /*!< Audio output loudness in steps of -0.25 dB. Range: 0
(0 dBFS) to 231 (-57.75 dBFS).\n A value of -1
indicates that no loudness metadata is present.\n If
loudness normalization is active, the value corresponds
to the target loudness value set with
::AAC_DRC_REFERENCE_LEVEL.\n If loudness normalization
is not active, the output loudness value corresponds to
the loudness metadata given in the bitstream.\n
Loudness metadata can originate from MPEG-4 DRC or
MPEG-D DRC. */
} CStreamInfo;
5、void aacDecoder_Close(HANDLE_AACDECODER self);
解码器关闭;参数self是解码器句柄。
1、编码器初始化
int aac_dec_init()
{
uint8_t kNumberOfLayers = 1;
m_aacDec_Mng.aacDecoderHandle = aacDecoder_Open(TT_MP4_ADTS, kNumberOfLayers);
if (!m_aacDec_Mng.aacDecoderHandle) {
return -1;
}
return 0;
}
2、解码一帧AAC输出PCM数据
static CStreamInfo *aacDecodeFrames(unsigned char *pIndata,int inSize,unsigned char *pOutBuff,int outBuffSize)
{
int ret = 0;
unsigned int inputSize= inSize;
unsigned int valid = inputSize;
//将aac数据拷贝到解码器内部缓冲
ret = aacDecoder_Fill(m_aacDec_Mng.aacDecoderHandle, &pIndata, &inputSize, &valid);
if (ret != AAC_DEC_OK)
{
printf("aacDecoder_Fill is error %d\n",ret);
return NULL;
}
//解码aac并获取解码后的PCM数据
ret = aacDecoder_DecodeFrame(m_aacDec_Mng.aacDecoderHandle,(short*)pOutBuff,outBuffSize,0);
if (ret != AAC_DEC_OK)
{
printf("aacDecoder_DecodeFrame is error %d,outSize %d\n",ret,outBuffSize);
return NULL;
}
//获取解码后的信息
return aacDecoder_GetStreamInfo(m_aacDec_Mng.aacDecoderHandle);;
}
3、关闭解码器
int aac_dec_deInit()
{
if (m_aacDec_Mng.aacDecoderHandle)
{
aacDecoder_Close(m_aacDec_Mng.aacDecoderHandle);
}
return 0;
}