2013-07-05 2 views
1

Я пытаюсь создать кодировщик для «audio/3gpp» и моего краха приложения.BufferOverflowException при попытке кодирования данных

Я 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

Попробуйте добавить параметр MediaFormat.KEY_MAX_INPUT_SIZE в ваш mMediaFormat в соответствии с размером input. Это увеличит мощность inputBuffers.

1

Положите inputBuffer.rewind(); перед тем inputBuffer.put(input); и попробовать его

1

Обработка входного буфера выглядит хорошо - вы используете clear() для сброса положения и ограничения - поэтому я предполагаю, что вход вы предоставляете просто больше, чем может удерживать буфер. Если input.length больше, чем inputBuffer.limit(), вам необходимо предоставить его в небольших кусках.

Управление выходным буфером выглядит немного странным - вы перераспределяете outData на каждую итерацию цикла, поэтому, если вы получаете более одного буфера, вы в конечном итоге отбросьте все, кроме последнего.

Для ввода и вывода вы не обрабатываете отрицательные значения возврата. В частности, INFO_*_BUFFERS_CHANGED требует повторного приобретения массива ByteBuffer.

Смежные вопросы