尝试编码数据时出现BufferOverflowException

时间:2013-07-05 12:49:41

标签: java android buffer-overflow

我尝试为“audio / 3gpp”创建编码器,我的应用程序崩溃。

我配置了MediaCodec ......

    String mMime = "audio/3gpp";
    mMediaCodec = MediaCodec.createEncoderByType(mMime);
    MediaFormat mMediaFormat = MediaFormat.createAudioFormat(mMime, 44100, 1);
    mMediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 12000);
    mMediaFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
    mMediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
    mMediaCodec.configure(mMediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    mMediaCodec.start();

然后我尝试编码数据......

private byte[] EncodeDataTo3gp(byte[] input)
{
    byte[] outData = null;

    try 
    {
        ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();

        ByteBuffer[] outputBuffers = mMediaCodec.getOutputBuffers();
        int inputBufferIndex = mMediaCodec.dequeueInputBuffer(-1);
        if (inputBufferIndex >= 0) 
        {
            ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
            inputBuffer.clear();
            inputBuffer.put(input);
            mMediaCodec.queueInputBuffer(inputBufferIndex, 0, input.length, 0, 0);
        }

        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        int outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 0);
        while (outputBufferIndex >= 0) 
        {
            ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
            outData = new byte[bufferInfo.size];
            outputBuffer.get(outData);

            mMediaCodec.releaseOutputBuffer(outputBufferIndex, false);
            outputBufferIndex = mMediaCodec.dequeueOutputBuffer(bufferInfo, 0);
        }
    } catch (Throwable t) {
        t.printStackTrace();
    }

    return outData;
}

但是这个函数抛出异常。何时"inputBuffer.put(input);": java.nio.BufferOverflowException

3 个答案:

答案 0 :(得分:3)

尝试根据MediaFormat.KEY_MAX_INPUT_SIZE尺寸将mMediaFormat参数添加到input。它会增加inputBuffers的容量。

答案 1 :(得分:1)

inputBuffer.rewind();放在inputBuffer.put(input);之前并尝试

答案 2 :(得分:1)

输入缓冲区处理看起来没问题 - 你正在使用clear()来重置位置和限制 - 所以我假设你提供的输入只是大于缓冲区可以容纳的输入。如果input.length大于inputBuffer.limit(),则需要以较小的块提供。

输出缓冲区管理看起来有点奇怪 - 你在每次循环迭代时重新分配outData,所以如果你得到多个缓冲区,你最终会丢弃除最后一个之外的所有缓冲区。

对于输入和输出,您不处理负返回值。特别是,INFO_*_BUFFERS_CHANGED要求您重新获取ByteBuffer数组。