在安卓执法仪开发过程中,我们发现有些设备的编码器性能较低,后来发现MediaCodec库支持异步模式了, 切换到异步模式果然会提高一些编码帧率.
同步模式
MediaCodec 同步模式调用图如下:
创建,配置,启动AAC编码器:
MediaFormat format = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, spec.getSample(), spec.getChannel());
format.setInteger(MediaFormat.KEY_BIT_RATE, 16000);
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1920); // 1920 = 16k的采样,60毫秒长度.
Timber.i("audio codec:mediaFormat = " + videoFormat);
mediaCodec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mediaCodec.start();
获取输入队列并塞入PCM数据:
int inputBufferIndex = mCodec.dequeueInputBuffer(100);
if (inputBufferIndex >= 0) {
if (pcmBuf.capacity() != length) {
pcmBuf = ByteBuffer.allocate(length * 2).order(ByteOrder.LITTLE_ENDIAN);
}
pcmBuf.asShortBuffer().put(pcm, 0, length);
pcmBuf.clear();
ByteBuffer inputBuffer;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
inputBuffer = mCodec.getInputBuffer(inputBufferIndex);
} else {
final ByteBuffer[] inputBuffers = mCodec.getInputBuffers();
inputBuffer = inputBuffers[inputBufferIndex];
}
inputBuffer.clear();
inputBuffer.put(pcmBuf);
mCodec.queueInputBuffer(inputBufferIndex, 0, length * 2, timestamp / 1000, 0);// , needKeyFrm
}
inputBufferIndex小于0表示没有可用的输出帧(可能编码缓冲已满).
获取输出的AAC音频帧:
int aacOutputBufferIndex = aacCodec.dequeueOutputBuffer(mBufferInfo, 0);
long timeSpend2 = SystemClock.elapsedRealtime() - begin;
if (timeSpend2 > 200) {
Timber.w("aac dequeueOutputBuffer spend too much time....%d ms", timeSpend2);
}
if (aacOutputBufferIndex >= 0) {
try