1.应用背景
在一些集成了算法SDK的Android APP中,这些APP是取出摄像头实时帧,然后调用视觉算法SDK并产生检测结果。而当测试人员发现某一场景下算法效果欠佳时,需要从摄像头实时原始数据帧dump一段视频(mp4格式),因此,这些Android APP中需要提供相应的功能,而Android MediaCodec则很方便为开发人员提供应用接口去实现Android视频方面的操作。
2.Android MediaCodec简介
1.MediaCodec含义:MediaCodec是Android中提供的音视频编码、解码工具。它主要是完成上层接口的封装,提供给开发者使用,编解码功能是在native底层服务中完成的。
2.工作流程
1)缓存队列:client需要将数据放入输入队列,等待MediaCodec处理后,从输出队列获取结果数据
输入队列,接受数据(格式ByteBuffer);
输出队列,输出数据(格式ByteBuffer);
(2)使用
a.把原始数据放入输入缓冲区队列中一个空缓冲区上;
b.编/解码器从输入缓冲队列中获取缓冲区上数据,进行编码处理,结果存放到输出缓冲区上一个空缓冲区上;
c.处理完毕后,释放该输入缓冲区,它会被重新放回输入缓冲区队列,以便下次重复使用。
3.相关API
createDecoderByType:获取解码器对象
createEncoderBytype:获取编码器对象
configure:对编解码器进行配置,使编解码器转入配置状态
start:使编码器转入执行刷新状态
stop:结束并返回到未初始化状态
release:释放实例资源
createInputSurface:创建输入缓冲Surface
setOutputSurface:设置输出缓冲Surface
getInputBuffers:获取需要编码数据的输入流队列,返回的是一个ByteBuffer数组
queueInputBuffer:输入流入队列
dequeueInputBuffer:从输入流队列中取数据进行编码操作
getOutputBuffers:获取编解码之后的数据输出流队列,返回的是一个ByteBuffer数组
dequeueOutputBuffer:从输出队列中取出编码操作之后的数据
releaseOutputBuffer:处理完成,释放ByteBuffer数据
3.Android MediaMuxer简介
1.含义:在Android中,可以使用MediaMuxer来封装编码后的视频流和音频流到mp4容器中,目前MediaMuxer支持的文件输出格式包括MP4,webm和3gp。
2.使用
(1)构造
MediaMuxer mMediaMuxer = new MediaMuxer(mOutputVideoPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
// new MediaMuxer(String path, int format)指定视频文件输出路径和文件格式
(2)添加媒体通道
//开始编码 就会调用一次
MediaFormat outputFormat = mMediaCodec.getOutputFormat();
//配置封装器
// 增加一路指定格式的媒体流 视频
index = mMediaMuxer.addTrack(outputFormat);
(3)启动
MediaMuxer.start();
(4)写入数据
// 输出缓冲区
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int status = mMediaCodec.dequeueOutputBuffer(bufferInfo, 10000);
// index是addTrack(outputFormat)返回的
mMediaMuxer.writeSampleData(index, outputBuffer, bufferInfo);
(5)释放资源
MediaMuxer.stop();
MediaMuxer.release();
4.应用实例
1.功能
基于Android Studio开发APP,实现读取资源目录asserts所有NV21图片,并调用MediaCodec生成一段MP4。
2.代码:wangzhicheng2013/android_dump_mp4 (github.com)
注:
1.开发者需要在AndroidManfest.xml申请写sdcard权限,并编写相应权限申请代码。
2.代码里在创建AvcEncoderOnSynchronous需要提供帧率,如果设备帧率较低,而参数的帧率较高,那么录制的视频将加速。