Android音视频开发 -> fdk-aac解码eld-aac为pcm

音视频开发系列

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

大体思路

  • fdk-aac 解码初始化
  • fdk-aac 开始解码

公共变量

//解码器对象实例
HANDLE_AACDECODER aacDecoder;

fdk-aac解码初始化

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;
}

fdk-aac开始解码

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);
    }
}

fdk-aac释放解码资源

void FdkAacDecode::fdkAacDecodeClose() {
    aacDecoder_Close(aacDecoder);
}

你可能感兴趣的:(音视频,android,java)