MediaCodec
是 Android 提供的音视频编解码类,支持同步和异步两种工作模式。它们的主要区别体现在数据的提交(输入)与获取(输出)流程上。
一、同步方式(Synchronous Mode)
特点:
-
主动轮询
MediaCodec
,通过阻塞式 API 处理输入输出。 -
编码或解码过程在调用线程中完成,逻辑清晰,但效率相对较低。
常用 API:
int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferIndex);
// 填入数据后
codec.queueInputBuffer(inputBufferIndex, offset, size, presentationTimeUs, flags);
int outputBufferIndex = codec.dequeueOutputBuffer(bufferInfo, timeoutUs);
if (outputBufferIndex >= 0) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferIndex);
// 处理输出数据
codec.releaseOutputBuffer(outputBufferIndex, render);
}
优点:
-
实现简单,易于调试。
-
更适合短时任务或对性能要求不高的场景。
缺点:
-
需要频繁轮询,阻塞线程,耗 CPU。
-
线程和资源占用高,不适合复杂场景如直播、屏幕录制等。
二、异步方式(Asynchronous Mode)
特点:
-
使用回调接口处理输入输出。
-
编码解码过程异步触发,更高效地利用 CPU 和系统资源。
启用方式:
MediaCodec.Callback callback = new MediaCodec.Callback() {
@Override
public void onInputBufferAvailable(MediaCodec codec, int index) {
ByteBuffer inputBuffer = codec.getInputBuffer(index);
// 填充数据
codec.queueInputBuffer(index, offset, size, presentationTimeUs, flags);
}
@Override
public void onOutputBufferAvailable(MediaCodec codec, int index, MediaCodec.BufferInfo info) {
ByteBuffer outputBuffer = codec.getOutputBuffer(index);
// 处理输出
codec.releaseOutputBuffer(index, render);
}
@Override
public void onError(MediaCodec codec, MediaCodec.CodecException e) {
// 错误处理
}
@Override
public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
// 格式变化处理
}
};
codec.setCallback(callback);
codec.configure(...);
codec.start();
优点:
-
非阻塞,效率高。
-
适合高性能任务(如屏幕录制、直播、实时通信等)。
-
更好地利用多线程并行处理。
缺点:
-
实现复杂,回调逻辑容易出错。
-
对线程安全有更高要求。
总结对比:
项目 | 同步模式 | 异步模式 |
---|---|---|
工作方式 | 主动轮询 | 回调处理 |
是否阻塞 | 是 | 否 |
性能 | 一般 | 高 |
实现难度 | 简单 | 稍复杂 |
适合场景 | 本地录制、离线任务等 | 屏幕录制、直播、实时通信等 |