Android MediaCodec onOutputBufferAvailable - how to control callback frequency?

634 Views Asked by At

I'm using MediaCodec with targetSdkVersion 28 (Android 9) to convert the PCM stream from AudioRecorder into AMR for a 3GPP/GSM VoIP application. The onInputBufferAvailable() callback calls AudioRecord.read(bb, bb.limit()) to queue the PCM samples to the encoder through the available ByteBuffer and the onOutbufferAvailable() callback accepts the AMR frame and passes it down to the RTP layer for packetization and transmission. This works well on a variety of Android 7, 8 and 9 devices that we've been testing with.

However, on a Samsung XCoverPro running Android 10, the onOutbufferAvailable() callback isn't being triggered until 26 AMR frames are available, instead of a single frame as has happened previously. Given that each frame represents 20ms of audio, this is causing an audio delay of over half a second. So my question is, what control do I have over a MediaCodec audio encoder to get it to trigger the onOutputBufferAvailable() callback when a particular number of frames (ideally between 1 and 5) are available?

The encoder is created like this...

    String mimeType = MediaFormat.MIMETYPE_AUDIO_AMR_NB;
    MediaFormat format = new MediaFormat();
    format.setString(MediaFormat.KEY_MIME, mimeType);
    format.setInteger(MediaFormat.KEY_SAMPLE_RATE, sampleRate);
    format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
    format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
    MediaCodec encoder = MediaCodec.createEncoderByType(mimeType);
    encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);

I've experimented with the MediaFormat.KEY_MAX_INPUT_SIZE parameter but that doesn't appear to have any effect, and setting MediaFormat.KEY_LATENCY didn't help either (any anyway the docs say it only applies to video codecs).

Any suggestions?

0

There are 0 best solutions below