You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:能否通过MediaCodec将AAC解码为PCM Float?输出始终为16位

如何用MediaCodec将AAC解码为PCM Float格式?

我之前做音频解码时也碰到过一模一样的问题——明明在MediaFormat里设置了KEY_PCM_ENCODING为ENCODING_PCM_FLOAT,但解码器输出还是16位PCM。这里给你几个关键的排查点和解决方案:

  • 先确认解码器是否真的支持PCM Float输出
    很多时候,即使你手动设置了KEY_PCM_ENCODING参数,硬件解码器可能并不支持这个输出格式,会自动 fallback 到默认的16位PCM。你可以在configure之后,通过解码器的实际输出格式来验证:

    mediaDecode.configure(format, null, null, 0);
    // 获取解码器实际使用的输出格式
    MediaFormat actualOutputFormat = mediaDecode.getOutputFormat();
    int actualEncoding = actualOutputFormat.getInteger(MediaFormat.KEY_PCM_ENCODING);
    // 打印或者判断实际编码格式
    if (actualEncoding == AudioFormat.ENCODING_PCM_FLOAT) {
        // 解码器支持Float输出
    } else {
        // 解码器不支持,只能拿到16位PCM
    }
    
  • 正确读取Float格式的输出Buffer
    如果解码器确实支持PCM Float,你需要用FloatBuffer来读取输出数据,而不是习惯用的ShortBuffer。处理输出的代码大概是这样:

    int outputBufferId = mediaDecode.dequeueOutputBuffer(bufferInfo, 10000);
    if (outputBufferId >= 0) {
        ByteBuffer outputBuffer = mediaDecode.getOutputBuffer(outputBufferId);
        MediaFormat outputFormat = mediaDecode.getOutputFormat(outputBufferId);
        int encoding = outputFormat.getInteger(MediaFormat.KEY_PCM_ENCODING);
        
        if (encoding == AudioFormat.ENCODING_PCM_FLOAT) {
            // 转换为FloatBuffer读取数据
            FloatBuffer floatBuffer = outputBuffer.asFloatBuffer();
            float[] pcmFloatData = new float[floatBuffer.remaining()];
            floatBuffer.get(pcmFloatData);
            // 在这里处理你的Float格式PCM数据
        } else {
            // 处理16位PCM的情况
            ShortBuffer shortBuffer = outputBuffer.asShortBuffer();
            short[] pcm16BitData = new short[shortBuffer.remaining()];
            shortBuffer.get(pcm16BitData);
        }
        
        mediaDecode.releaseOutputBuffer(outputBufferId, false);
    }
    
  • 兼容性方案:手动将16位PCM转为Float
    如果你的目标设备解码器不支持PCM Float输出,也可以自己做格式转换。16位PCM的取值范围是-32768到32767,转换成Float格式只需要将每个short值除以32768.0f,得到-1.0f到1.0f之间的浮点值:

    short[] pcm16Bit = ...; // 从解码器获取的16位数据
    float[] pcmFloat = new float[pcm16Bit.length];
    for (int i = 0; i < pcm16Bit.length; i++) {
        pcmFloat[i] = pcm16Bit[i] / 32768.0f;
    }
    

另外补充一点:有些设备的软件解码器(比如OMX.google.aac.decoder)对PCM Float的支持会更好,如果硬件解码器不行,可以尝试指定使用软件解码器。


内容的提问来源于stack exchange,提问作者Nick Tseng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:34:56