Android音视频开发 -> 搭建开发环境
Android音视频开发 -> ffmpeg+h264+aac编译以及测试调用
Android音视频开发 -> 本地音频采集
Android音视频开发 -> 本地camera视频采集
Android音视频开发 -> ffmpeg+h264+avfilter+camera推流旋转角度
Android音视频开发 -> fdk-aac编码pcm为eld-aac
Android音视频开发 -> fdk-aac解码eld-aac为pcm
//解码器对象实例
HANDLE_AACDECODER aacDecoder;
int FdkAacDecode::fdkAacDecodeInit(JNIEnv *env) {
//Java方法初始化
aacDecodeClass = env->FindClass("com/zkzj/aaclib/AacUtil");
aacDecodeId = env->GetMethodID(aacDecodeClass, "receivePcmUdp", "([B)V");
//创建解码器实例,数据格式要与编码封装格式一致
aacDecoder = aacDecoder_Open(TT_MP4_RAW, 1);
//设置ASC信息(AOT_ER_AAC_ELD数据格式 采样率为8000 单声道)
UCHAR ld_conf[] = {0xF8, 0xF6, 0x20, 0x00};
UCHAR *conf_array[] = {ld_conf};
static UINT conf_len = sizeof(ld_conf);
//配置解码器
if (aacDecoder_ConfigRaw(aacDecoder, conf_array, &conf_len) > 0) {
LOGE("配置解码器失败");
return -1;
}
return 0;
}
void FdkAacDecode::fdkAacDecode(JNIEnv *env, jobject obj, jbyte *aacEldData, int aacEldLength) {
//接收aac-eld数据流以及获取长度
uint8_t *input = (uint8_t *) aacEldData;
unsigned int size = aacEldLength;
unsigned int valid = aacEldLength;
//加载准备解码的aac-eld
AAC_DECODER_ERROR code = aacDecoder_Fill(aacDecoder, &input, &size, &valid);
if (code > 0) {
LOGE("加载准备解码数据失败");
} else if (code == AAC_DEC_NOT_ENOUGH_BITS) {
LOGE("输入缓冲区的位用完啦");
}
//解码
int decsize = 2048;
unsigned char *decdata = (unsigned char *) malloc(decsize);
code = aacDecoder_DecodeFrame(aacDecoder, (INT_PCM *) decdata, decsize,
0);
if (code > 0){
LOGE("解码失败");
}
if (code == AAC_DEC_OK) {
//通过获取信息,计算实际输出的pcm数据大小
CStreamInfo *info = aacDecoder_GetStreamInfo(aacDecoder);
int pcm_size = info->numChannels * info->frameSize * 2;
//把结果保存到本地
jbyteArray pcmArray = env->NewByteArray(pcm_size);
env->SetByteArrayRegion(pcmArray, 0, pcm_size, (const jbyte *) decdata);
env->CallVoidMethod(obj, aacDecodeId, pcmArray);
}
}
void FdkAacDecode::fdkAacDecodeClose() {
aacDecoder_Close(aacDecoder);
}