Reputation: 125
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
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
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
Reputation: 13520
Put inputBuffer.rewind();
before inputBuffer.put(input);
and try it
Upvotes: 1