Android 音视频 --H,flutter 小程序开发
请求一个空的输入 input buffer
填入数据、并将其交给 MediaCodec
MediaCodec 处理数据后,将处理后的数据放在一个空的 output buffer
获取填充数据了的 output buffer,得到其中的数据,然后将其返还给 MediaCodec
2.3 MediaCodec API 说明
MediaCodec 可以处理具体的视频流,主要有这几个方法:
configure:配置为编码器 start:成功地配置组件后,调用 start 方法。
getInputBuffers:获取需要编码数据的输入流队列,返回的是一个 ByteBuffer 数组
queueInputBuffer:输入流入队列 dequeueInputBuffer:从输入流队列中取数据进行编码操作
getOutputBuffers:获取编解码之后的数据输出流队列,返回的是一个 ByteBuffer 数组
dequeueOutputBuffer:从输出队列中取出编码操作之后的数据
releaseOutputBuffer:处理完成,释放 ByteBuffer 数据
stop:完成解码/编码任务后,需注意的是 codec 任然处于活跃状态且准备重新 start。
flush:冲洗组件的输入和输出端口 release:释放 codec 实例使用的资源。
reset:使 codec 返回到初始(未初始化)状态。
2.4 Talk is cheap, Show me the code
初始化 MediaCodec
/**
视频类型
*/
private final static String MIME_TYPE = "video/avc";
/**
初始化播放
*/
private void initVideo(SurfaceHolder holder) {
try {
// 初始化 MediaCodec,方法有两种,分别是通过名称和类型来创建
// 这里使用通过类型来创建
mMediaCodec = MediaCodec.createDecoderByType(MIME_TYPE);
// 获取视频的宽高
mVideoHeight = holder.getSurfaceFrame().width();
mVideoWidth = holder.getSurfaceFrame().height();
// MediaFormat,这个类包含了比特率、帧率、关键帧间隔时间等,其中比特率如果太低就会造成类似马赛克的现象。
mMediaFormat = MediaFormat.createVideoFormat(MIME_TYPE,
1080, 1920);
// 设置比特率?
mMediaFormat.setInteger(KEY_BIT_RATE,
mVideoHeight * mVideoWidth * 5);
// 设置帧率?
mMediaFormat.setInteger(KEY_FRAME_RATE, 30);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 描述编码器要使用的所需比特率模式的键
// BITRATE_MODE_CQ: 表示完全不控制码率,尽最大可能保证图像质量
//BITRATE_MODE_CBR: 表示编码器会尽量把输出码率控制为设定值
//BITRATE_MODE_VBR: 表示编码器会根据图像内容的复杂度(实际上是帧间变化量的大小)来动态调整输出码率,图像复杂则码率高,图像简单则码率低;
mMediaFormat.setInteger(MediaFormat.KEY_BITRATE_MODE,
MediaCodecInfo.EncoderCapabilities.BITRATE_MODE_VBR);
}
mMediaFormat.setInteger(KEY_I_FRAME_INTERVAL, 1);
byte[] headerSps = {0, 0, 0, 1, 103, 66, 0, 41, -115, -115, 64, 80,
30, -48, 15, 8, -124, 83, -128};
byte[] headerPps = {0, 0, 0, 1, 104, -54, 67, -56};
mMediaFormat.setByteBuffer("csd-0", ByteBuffer.wrap(headerSps));
mMediaFormat.setByteBuffer("csd-1", ByteBuffer.wrap(headerPps));
mMediaCodec.configure(mMediaFormat, holder.getSurface(), null, 0);
mMediaCodec.start();
} catch (IOException e) {
e.printStackTrace();
}
}
视频解码部分代码
将接收到或从文件读取到的 byte[]传入 onFrame 中
评论