Agent P
Agent P

Reputation: 125

BufferOverflowException when trying to encode data

I try create encoder for "audio/3gpp" and my app crash.

I configurate 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();

And then I trying to encode data...

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

But this function is throwing an exception. when "inputBuffer.put(input);": java.nio.BufferOverflowException

Upvotes: 3

Views: 3171

Answers (3)

a.toropov
a.toropov

Reputation: 228

Try to add MediaFormat.KEY_MAX_INPUT_SIZE parameter to your mMediaFormat according to input size. It will increase capacity of inputBuffers.

Upvotes: 4

fadden
fadden

Reputation: 52353

The input buffer handling looks okay -- you're using clear() to reset the position and limit -- so I'm assuming that the input you're providing is simply larger than the buffer can hold. If input.length is larger than inputBuffer.limit(), you'll need to provide it in smaller chunks.

The output buffer management looks a little strange -- you're re-allocating outData on each loop iteration, so if you get more than one buffer out you'll end up discarding all but the last one.

For both input and output, you're not handling negative return values. In particular, INFO_*_BUFFERS_CHANGED requires you to re-acquire the ByteBuffer array.

Upvotes: 2

Apoorv
Apoorv

Reputation: 13520

Put inputBuffer.rewind(); before inputBuffer.put(input); and try it

Upvotes: 1

Related Questions