gf_ai_box/include/modules/audiotk/audio_encoder.c
2026-04-12 17:47:54 +08:00

730 lines
21 KiB
C

/*
*******************************************************************************
* Copyright (c) 2010-2022 VATICS(KNERON) Inc. All rights reserved.
*
* +-----------------------------------------------------------------+
* | THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED |
* | AND COPIED IN ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH |
* | A LICENSE AND WITH THE INCLUSION OF THE THIS COPY RIGHT NOTICE. |
* | THIS SOFTWARE OR ANY OTHER COPIES OF THIS SOFTWARE MAY NOT BE |
* | PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON. THE |
* | OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED. |
* | |
* | THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT |
* | ANY PRIOR NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY |
* | VATICS(KNERON) INC. |
* +-----------------------------------------------------------------+
*
*******************************************************************************
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <audio_encoder.h>
#ifdef HAS_HW_AAC_ENC
#include <vmf/audio_aac4enc.h>
#else
#include <fdk-aac/aacenc_lib.h>
#endif
#ifdef GAMR_SUPPORT
#include <opencore/interf_enc.h> //! For GAMR encoder.
#endif
#include <g711/G711SEnc.h>
#include <g726/G726SEnc.h>
typedef int (*Enc_Release) (void** handle);
typedef int (*Enc_EncodeOneFrame) (void* handle, ATK_AUDIOENC_ONEFRAME_CONF_T* conf);
typedef int (*Enc_GetConf) (void* handle, void *conf_buf);
struct ATK_AUDIOENC_HANDLE_T
{
#ifdef HAS_HW_AAC_ENC
VMF_AAC4ENC_HANDLE_T* handle_;
#else
HANDLE_AACENCODER handle_; /**< The handle of audio encoders (FDK). */
#endif
unsigned int aac_output_channels_;
int g711_mode_;
unsigned int gamr_mode_;
unsigned int step_offset_;
Enc_Release release_func; /**< The callback function of one encoder for release resource. */
Enc_EncodeOneFrame enc_func; /**< The callback function of one encoder for encode data. */
Enc_GetConf getconf_func; /**< The callback function of one encoder for get configuration. */
unsigned int sample_rate_; /**< Sample rate. */
unsigned int channels_; /**< The number of channels. */
unsigned int bit_rate_; /**< The number of channels. */
unsigned int is_interleaved_; /**< the input data is interleaved or not. */
unsigned int period_size_in_frames; /**< Distance between interrupts is # frames. */
void* pcmbuffer;
};
#ifdef HAS_HW_AAC_ENC
/**
* @brief Function to initialize AAC4 audio encoder.
*
* @param[in] aac4enc_handle The handle of AAC4 audio encoder.
* @param[in] config Initial configuration for audio encoder.
* @return negative: failed, otherwise: success.
*/
static int ATK_AAC4Enc_Init(ATK_AUDIOENC_HANDLE_T *aac4enc_handle, const ATK_AAC4ENC_CONFIG_T *config)
{
VMF_AAC4ENC_INITOPT_T tVmfAac4encInit;
memset(&tVmfAac4encInit, 0, sizeof(VMF_AAC4ENC_INITOPT_T));
tVmfAac4encInit.dwBitRate = config->dwBitRate;
tVmfAac4encInit.dwSampleRate = aac4enc_handle->sample_rate_ = config->dwSampleRate;
tVmfAac4encInit.dwADTS = config->dwAdts; // 0: Raw, 1: ADTS or 2: ADIF
if( (aac4enc_handle->channels_ == 2) && (aac4enc_handle->is_interleaved_) )
{
// stereo
tVmfAac4encInit.dwChannel = 2;
}
else if( (aac4enc_handle->channels_ == 1) || (aac4enc_handle->is_interleaved_ == 0) )
{
// mono
tVmfAac4encInit.dwChannel = 1;
}
else
{
fprintf(stderr, "[%s, %s]: Unsupport channel number for AAC4 encoder.\n", __FILE__, __func__);
return -1;
}
switch(config->dwStereoMode)
{
case 0: // stereo
case 1: // joint stereo
if (tVmfAac4encInit.dwChannel == 1)
{
fprintf(stderr, "[%s, %s]: The output channels of AAC is large than the input channels.\n", __FILE__, __func__);
return -1;
}
aac4enc_handle->aac_output_channels_ = 2;
tVmfAac4encInit.dwStereoMode = config->dwStereoMode;
break;
case 3: // mono
aac4enc_handle->aac_output_channels_ = 1;
tVmfAac4encInit.dwStereoMode = config->dwStereoMode;
break;
default:
fprintf(stderr, "[%s, %s]: Unsupport stereo mode for AAC4 encoder.\n", __FILE__, __func__);
return -1;
}
aac4enc_handle->handle_ = VMF_AAC4ENC_Init(&tVmfAac4encInit);
if (!aac4enc_handle->handle_) {
fprintf(stderr, "[%s, %s]: AAC4 init failed.\n", __FILE__, __func__);
return -1;
}
return 0;
}
/**
* @brief Function to encode one audio frame.
*
* @param[in] handle The handle of audio encoder (tk).
* @param[in] pbyInBuf The input data buffer,
* @param[out] pbyOutBuf The output encoded data buffer.
* @param[in] dwOutBufSize The size of output data buffer.
* @return negative: failed, otherwise: The size of encoded data (bytes).
*/
static int ATK_AAC4Enc_EncodeOneFrame(ATK_AUDIOENC_HANDLE_T *handle, ATK_AUDIOENC_ONEFRAME_CONF_T* conf)
{
VMF_AAC4ENC_ONEFRAME_CONF_T tVmfAac4OneFrameConf;
VMF_AAC4ENC_HANDLE_T *ptAac4encHandle = handle->handle_;
memset(&tVmfAac4OneFrameConf, 0, sizeof(VMF_AAC4ENC_ONEFRAME_CONF_T));
tVmfAac4OneFrameConf.pbyInBuf = conf->pbyInBuf;
tVmfAac4OneFrameConf.pbyOutBuf = conf->pbyOutBuf;
tVmfAac4OneFrameConf.dwOutBufSize = conf->dwOutBufSize;
if (0 != VMF_AAC4ENC_SetOptions(ptAac4encHandle, &tVmfAac4OneFrameConf))
{
fprintf(stderr, "[%s, %s]: Unable to set options for encoder.\n", __FILE__, __func__);
return -1;
}
if (0 != VMF_AAC4ENC_PorcessOneFrame(ptAac4encHandle))
{
fprintf(stderr, "[%s, %s]: AAC4Enc_OneFrame failed.\n", __FILE__, __func__);
return -1;
}
return VMF_AAC4ENC_GetBitStreamSize(ptAac4encHandle);
}
/**
* @brief Function to get information about the encoder.
*
* @param[in] handle The handle of audio encoder (tk).
* @param[out] conf_buf The buffer which to store the information.
* @return negative: failed, otherwise: success.
*/
static int ATK_AAC4Enc_GetConf(ATK_AUDIOENC_HANDLE_T *handle, void *conf_buf)
{
//---header
//dwDataType (4 bytes)
//payload len (4 bytes)
//--paylaod
//codec_type (4 bytes)
//sameple rate (4 bytes)
//channel num (4 bytes)
//dwProfileLevel (4 bytes)
//aac header size (4 bytes)
//aac header data
unsigned int *values = (unsigned int*) conf_buf;
uint32_t dwSpecConfSize = 0;
if (0 != VMF_AAC4ENC_GetConf(handle->handle_, conf_buf, &dwSpecConfSize, values))
{
return -1;
}
values[0] = FOURCC_CONF;
values[1] = 20 + dwSpecConfSize;
values[2] = FOURCC_AAC4;
values[3] = handle->sample_rate_;
values[4] = handle->aac_output_channels_;
values[6] = dwSpecConfSize;
return 0;
}
#else
/**
* @brief Function to initialize AAC4 audio encoder.
*
* @param[in] aac4enc_handle The handle of AAC4 audio encoder.
* @param[in] config Initial configuration for audio encoder.
* @return negative: failed, otherwise: success.
*/
static int ATK_AAC4Enc_Init(ATK_AUDIOENC_HANDLE_T *aac4enc_handle, const ATK_AAC4ENC_CONFIG_T *config)
{
int format = 0;
unsigned int AOTmode = 0;
if (config->dwAdts == 1)
format = 2;
else if(config->dwAdts == 2)
format = 1;
if (config->dwELDMode == 1 )
AOTmode = 39;
else
AOTmode = 2;
switch(config->dwStereoMode)
{
case 0: // stereo
case 1: // joint stereo
aac4enc_handle->aac_output_channels_ = 2;
break;
case 3: // mono
aac4enc_handle->aac_output_channels_ = 1;
break;
default:
fprintf(stderr, "[%s, %s]: Unsupport stereo mode for AAC4 encoder.\n", __FILE__, __func__);
return -1;
}
// ELD mode only support RAW
if (config->dwELDMode == 1) {
printf("check ELD setting\n");
if( format != 0) {
fprintf(stderr, "[%s, %s]: Error, ELD mode must use RAW\n", __FILE__, __func__);
return -1;
}
if(config->dwSampleRate <= 8000 || config->dwSampleRate > 48000) {
fprintf(stderr, "[%s, %s]: Error, ELD mode support 16000-48000 sample rate\n", __FILE__, __func__);
return -1;
}
} else { //LC mode only suppor ADTS/ADIF
if( format == 0) {
fprintf(stderr, "[%s, %s]: Error, LC mode must use ADTS/ADIF\n", __FILE__, __func__);
return -1;
}
}
if (aacEncOpen(&(aac4enc_handle->handle_), 0, aac4enc_handle->channels_) != AACENC_OK) {
fprintf(stderr, "[%s, %s]: Unable to open encoder.\n", __FILE__, __func__);
return -1;
}
if (aacEncoder_SetParam(aac4enc_handle->handle_, AACENC_AOT, AOTmode ) != AACENC_OK) {
fprintf(stderr, "Unable to set the AOT\n");
return -1;
}
if (aacEncoder_SetParam(aac4enc_handle->handle_, AACENC_SAMPLERATE, config->dwSampleRate) != AACENC_OK) {
fprintf(stderr, "[%s, %s]: Unable to set the sample rate.\n", __FILE__, __func__);
return -1;
}
if (aacEncoder_SetParam(aac4enc_handle->handle_, AACENC_CHANNELMODE, aac4enc_handle->channels_) != AACENC_OK) {
fprintf(stderr, "[%s, %s]: Unable to set the channel mode.\n", __FILE__, __func__);
return -1;
}
if (aacEncoder_SetParam(aac4enc_handle->handle_, AACENC_CHANNELORDER, 1) != AACENC_OK) {
fprintf(stderr, "[%s, %s]: Unable to set the wav channel order.\n", __FILE__, __func__);
return -1;
}
if (aacEncoder_SetParam(aac4enc_handle->handle_, AACENC_BITRATE, config->dwBitRate) != AACENC_OK) {
fprintf(stderr, "[%s, %s]: Unable to set the bitrate.\n", __FILE__, __func__); //now bitrate is VBR in low level, so this not work.
return -1;
}
if (aacEncoder_SetParam(aac4enc_handle->handle_, AACENC_TRANSMUX, format) != AACENC_OK) {
fprintf(stderr, "[%s, %s]: Unable to set the ADTS transmux.\n", __FILE__, __func__); //now bitrate is VBR in low level, so this not work.
return -1;
}
if (aacEncEncode(aac4enc_handle->handle_, NULL, NULL, NULL, NULL) != AACENC_OK) {
fprintf(stderr, "[%s, %s]: Unable to initialize the encoder.\n", __FILE__, __func__);
return -1;
}
aac4enc_handle->sample_rate_ = config->dwSampleRate;
return 0;
}
/**
* @brief Function to release encoder.
*
* @param[in] ptHandle The handle of AAC encoder.
* @return Success: 0 Fail: negative integer.
*/
static int ATK_AACEnc_Release(void** handle)
{
if (aacEncClose((HANDLE_AACENCODER *)handle) != 0) {
fprintf(stderr, "[%s, %s]: Release the encoder fail.\n", __FILE__, __func__);
return -1;
}
*handle = NULL;
return 0;
}
/**
* @brief Function to get information about the encoder.
*
* @param[in] handle The handle of audio encoder (tk).
* @param[out] conf_buf The buffer which to store the information.
* @return negative: failed, otherwise: success.
*/
static int ATK_AAC4Enc_GetConf(ATK_AUDIOENC_HANDLE_T *handle, void *conf_buf)
{
//---header
//dwDataType (4 bytes)
//payload len (4 bytes)
//--paylaod
//codec_type (4 bytes)
//sameple rate (4 bytes)
//channel num (4 bytes)
//dwProfileLevel (4 bytes)
//aac header size (4 bytes)
//aac header data
AACENC_InfoStruct info;
memset(&info, 0, sizeof(AACENC_InfoStruct
));
unsigned int *values = (unsigned int*) conf_buf;
if (aacEncInfo(handle->handle_, &info) != AACENC_OK) {
fprintf(stderr, "[%s, %s]: Unable to get the encoder info.\n", __FILE__, __func__);
return -1;
}
handle->period_size_in_frames = info.frameLength;
values[0] = FOURCC_CONF;
values[1] = 20 + info.confSize;
values[2] = FOURCC_AAC4;
values[3] = handle->sample_rate_;
values[4] = handle->aac_output_channels_;
values[6] = info.confSize;
memcpy(&values[7], info.confBuf, info.confSize);
return 0;
}
/**
* @brief Function to encode one audio frame.
*
* @param[in] handle The handle of audio encoder (tk).
* @param[in] pbyInBuf The input data buffer,
* @param[out] pbyOutBuf The output encoded data buffer.
* @param[in] dwOutBufSize The size of output data buffer.
* @return negative: failed, otherwise: The size of encoded data (bytes).
*/
static int ATK_AAC4Enc_EncodeOneFrame(ATK_AUDIOENC_HANDLE_T *handle, ATK_AUDIOENC_ONEFRAME_CONF_T* conf)
{
int input_size = 2*handle->channels_*handle->period_size_in_frames; //16bits * channel * frames (bytes)
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 in_elem_size;
int out_identifier = OUT_BITSTREAM_DATA;
int out_size;//, out_elem_size;
void *in_ptr, *out_ptr;
AACENC_ERROR err;
in_ptr = conf->pbyInBuf;
in_elem_size = 16/8; //16 bits = 2bytes fixed
in_args.numInSamples = input_size/2;
in_buf.numBufs = 1;
in_buf.bufs = &in_ptr;
in_buf.bufferIdentifiers = &in_identifier;
in_buf.bufSizes = &input_size;
in_buf.bufElSizes = &in_elem_size;
out_ptr = conf->pbyOutBuf;
out_size = conf->dwOutBufSize;
out_buf.numBufs = 1;
out_buf.bufs = &out_ptr;
out_buf.bufferIdentifiers = &out_identifier;
out_buf.bufSizes = &out_size;
out_buf.bufElSizes = (signed int *)&handle->aac_output_channels_;
if ((err = aacEncEncode(handle->handle_, &in_buf, &out_buf, &in_args, &out_args)) != AACENC_OK) {
fprintf(stderr, "[%s, %s]: Encoding failed err code 0x%x.\n", __FILE__, __func__,err);
return -1;
}
return out_args.numOutBytes;
}
#endif
#ifdef GAMR_SUPPORT
// ==========================================================================
/**
* @brief Function to initialize GAMR audio encoder.
*
* @param[in] aac4enc_handle The handle of GAMR audio encoder.
* @param[in] config Initial configuration for audio encoder.
* @return negative: failed, otherwise: success.
*/
static int ATK_GAMREnc_Init(ATK_AUDIOENC_HANDLE_T *gamrenc_handle, const ATK_GAMRENC_CONFIG_T *config)
{
gamrenc_handle->sample_rate_ = config->dwSampleRate;
gamrenc_handle->bit_rate_ = config->dwBitRate;
gamrenc_handle->gamr_mode_ = config->dwMode;
gamrenc_handle->handle_ = Encoder_Interface_init(0);//dtx
return (gamrenc_handle->handle_ != NULL) ? 0 : -1;
}
/**
* @brief Function to encode one audio frame.
*
* @param[in] handle The handle of audio encoder (tk).
* @param[in] in_buf The input data buffer,
* @param[out] out_buf The output encoded data buffer.
* @param[in] out_buf_size The size of output data buffer.
* @return negative: failed, otherwise: The size of encoded data (bytes).
*/
static int ATK_GAMREnc_EncodeOneFrame(ATK_AUDIOENC_HANDLE_T *handle, ATK_AUDIOENC_ONEFRAME_CONF_T* conf)
{
size_t outputSize = 0;
short* pcmbuffer = (short*)handle->pcmbuffer;
short* tmpIn = (short*)conf->pbyInBuf;
for (unsigned int i=0; i < handle->period_size_in_frames; i++)
{
pcmbuffer[i] = tmpIn[i << 1];
}
outputSize = Encoder_Interface_Encode(handle->handle_, handle->gamr_mode_, pcmbuffer, conf->pbyOutBuf, 0);
return outputSize;
}
/**
* @brief Function to get information about the encoder.
*
* @param[in] handle The handle of audio encoder (tk).
* @param[out] conf_buf The buffer which to store the information.
* @return negative: failed, otherwise: success.
*/
static int ATK_GAMREnc_GetConf(ATK_AUDIOENC_HANDLE_T *handle, void *conf_buf)
{
//---header
//dwDataType (4 bytes)
//payload len (4 bytes)
//--paylaod
//codec_type (4 bytes)
//sample rate (4 bytes)
unsigned int *values = (unsigned int*) conf_buf;
values[0] = FOURCC_CONF;
values[1] = 8;
values[2] = FOURCC_GAMR;
values[3] = handle->sample_rate_;
return 0;
}
static int ATK_GAMREnc_Release(void** handle)
{
Encoder_Interface_exit(*handle);
*handle = NULL;
return 0;
}
#endif
static int ATK_G711Enc_ALaw_Encode(ATK_AUDIOENC_HANDLE_T* handle, ATK_AUDIOENC_ONEFRAME_CONF_T* conf)
{
G711_ALaw_Encode((short*)conf->pbyInBuf, conf->pbyOutBuf, handle->period_size_in_frames, handle->step_offset_);
return handle->period_size_in_frames;
}
static int ATK_G711Enc_ULaw_Encode(ATK_AUDIOENC_HANDLE_T* handle, ATK_AUDIOENC_ONEFRAME_CONF_T* conf)
{
G711_ULaw_Encode((short*)conf->pbyInBuf, conf->pbyOutBuf, handle->period_size_in_frames, handle->step_offset_);
return handle->period_size_in_frames;
}
/**
* @brief Function to get information about the encoder.
*
* @param[in] handle The handle of audio encoder (tk).
* @param[out] conf_buf The buffer which to store the information.
* @return negative: failed, otherwise: success.
*/
static int ATK_G711Enc_GetConf(ATK_AUDIOENC_HANDLE_T *handle, void *conf_buf)
{
//---header
//dwDataType (4 bytes)
//payload len (4 bytes)
//--paylaod
//codec_type (4 bytes)
//compression_format [ulaw or alaw] (4 bytes)
unsigned int *values = (unsigned int*) conf_buf;
values[0] = FOURCC_CONF;
values[1] = 8;
values[2] = FOURCC_G711;
values[3] = (handle->g711_mode_ == 0) ? FOURCC_ULAW : FOURCC_ALAW;
return 0;
}
// ==========================================================================
/**
* @brief Function to initialize G726 audio encoder.
*
* @param[in] g726enc_handle The handle of G726 audio encoder.
* @param[in] config Initial configuration for audio encoder.
* @return negative: failed, otherwise: success.
*/
static int ATK_G726Enc_Init(ATK_AUDIOENC_HANDLE_T *g726enc_handle, const ATK_G726ENC_CONFIG_T *config)
{
g726enc_handle->bit_rate_ = config->dwBitRate;
g726enc_handle->handle_ = (void *)g726_enc_init(g726enc_handle->bit_rate_);
return (g726enc_handle->handle_ != NULL)? 0:-1;
}
static int ATK_G726Enc_Release(void** handle)
{
g726_enc_release((g726_enc_handle_t*)(*handle));
*handle = NULL;
return 0;
}
/**
* @brief Function to encode one audio frame.
*
* @param[in] handle The handle of audio encoder (tk).
* @param[in] in_buf The input data buffer,
* @param[out] out_buf The output encoded data buffer.
* @param[in] out_buf_size The size of output data buffer.
* @return negative: failed, otherwise: The size of encoded data (bytes).
*/
static int ATK_G726Enc_EncodeOneFrame(ATK_AUDIOENC_HANDLE_T *handle, ATK_AUDIOENC_ONEFRAME_CONF_T* conf)
{
return g726_encode_frame((g726_enc_handle_t*)handle->handle_, conf->pbyOutBuf, (const int16_t*) conf->pbyInBuf, handle->period_size_in_frames, handle->step_offset_);
}
/**
* @brief Function to get information about the encoder.
*
* @param[in] handle The handle of audio encoder (tk).
* @param[out] conf_buf The buffer which to store the information.
* @return negative: failed, otherwise: success.
*/
static int ATK_G726Enc_GetConf(ATK_AUDIOENC_HANDLE_T *handle, void *conf_buf)
{
//---header
//dwDataType (4 bytes)
//payload len (4 bytes)
//--paylaod
//codec_type (4 bytes)
//dwCodewordBits (4 bytes)
unsigned int *values = (unsigned int*) conf_buf;
values[0] = FOURCC_CONF;
values[1] = 8;
values[2] = FOURCC_G726;
values[3] = handle->bit_rate_ / 8000;
return 0;
}
// ==========================================================================
ATK_AUDIOENC_HANDLE_T* ATK_AudioEnc_Init(const ATK_AUDIOENC_INITOPT_T *ptInitOpt, const void *pConfig)
{
ATK_AUDIOENC_HANDLE_T *handle = NULL;
if(pConfig == NULL || ptInitOpt == NULL)
{
return NULL;
}
handle = (ATK_AUDIOENC_HANDLE_T*) calloc(1, sizeof(ATK_AUDIOENC_HANDLE_T));
if(handle == NULL)
{
return NULL;
}
handle->channels_ = ptInitOpt->dwChannels;
handle->is_interleaved_ = (ptInitOpt->bIsInterleaved > 0)? 1:0;
handle->period_size_in_frames = ptInitOpt->dwPeriodSizeInFrames;
int ret = -1;
switch(ptInitOpt->eType)
{
case kAAC4:
#ifdef HAS_HW_AAC_ENC
handle->release_func = (Enc_Release) VMF_AAC4ENC_Release;
#else
handle->release_func = (Enc_Release) ATK_AACEnc_Release;
#endif
handle->enc_func = (Enc_EncodeOneFrame) ATK_AAC4Enc_EncodeOneFrame;
handle->getconf_func = (Enc_GetConf) ATK_AAC4Enc_GetConf;
ret = ATK_AAC4Enc_Init(handle, pConfig);
break;
case kG711:
{
ATK_G711ENC_CONFIG_T* g711_config = (ATK_G711ENC_CONFIG_T*) pConfig;
if (g711_config->iCompressionMode == 0)
{
handle->enc_func = (Enc_EncodeOneFrame) ATK_G711Enc_ULaw_Encode;
handle->g711_mode_ = 0;
}
else
{
handle->enc_func = (Enc_EncodeOneFrame) ATK_G711Enc_ALaw_Encode;
handle->g711_mode_ = 1;
}
handle->getconf_func = (Enc_GetConf) ATK_G711Enc_GetConf;
ret = 0;
}
break;
case kG726:
handle->release_func = (Enc_Release)ATK_G726Enc_Release;
handle->enc_func = (Enc_EncodeOneFrame) ATK_G726Enc_EncodeOneFrame;
handle->getconf_func = (Enc_GetConf) ATK_G726Enc_GetConf;
ret = ATK_G726Enc_Init(handle, pConfig);
break;
case kGAMR:
#ifdef GAMR_SUPPORT
handle->release_func = (Enc_Release) ATK_GAMREnc_Release;//GAMREnc_Release;
handle->enc_func = (Enc_EncodeOneFrame) ATK_GAMREnc_EncodeOneFrame;
handle->getconf_func = (Enc_GetConf) ATK_GAMREnc_GetConf;
handle->pcmbuffer = malloc(handle->period_size_in_frames * sizeof(short));
if(handle->pcmbuffer != NULL)
{
ret = ATK_GAMREnc_Init(handle, pConfig);
if(ret < 0)
{
free(handle->pcmbuffer);
handle->pcmbuffer = NULL;
}
}
else
{
fprintf(stderr, "[%s, %s]: Unable to allocate buffer.\n", __FILE__, __func__);
}
#endif
break;
default:
break;
}
if(ret < 0)
{
free(handle);
return NULL;
}
handle->step_offset_ = ((handle->is_interleaved_) && (handle->channels_ > 1)) ? (handle->channels_) : 1;
return handle;
}
int ATK_AudioEnc_Release(ATK_AUDIOENC_HANDLE_T *ptHandle)
{
if(!ptHandle)
return -1;
if(ptHandle->handle_)
{
void* phandle = (void *)ptHandle->handle_;
#ifdef HAS_HW_AAC_ENC
if(ptHandle->release_func && (ptHandle->release_func(&(phandle)) != 0))
{
#else
if(ptHandle->release_func && (ptHandle->release_func(&(phandle)) != 0))
{
#endif
fprintf(stderr, "[%s, %s]: Release encoder failed.\n", __FILE__, __func__);
}
ptHandle->handle_ = NULL;
}
if(ptHandle->pcmbuffer)
{
free(ptHandle->pcmbuffer);
ptHandle->pcmbuffer = NULL;
}
free(ptHandle);
return 0;
}
int ATK_AudioEnc_EncodeOneFrame(ATK_AUDIOENC_HANDLE_T *ptHandle, ATK_AUDIOENC_ONEFRAME_CONF_T* ptConf)
{
return ptHandle->enc_func(ptHandle, ptConf);
}
int ATK_AudioEnc_GetConf(ATK_AUDIOENC_HANDLE_T *ptHandle, void *pConfBuf)
{
return ptHandle->getconf_func(ptHandle, pConfBuf);
}