Android平台对H264视频硬解码
来源:互联网 发布:js显示隐藏div切换 编辑:程序博客网 时间:2024/06/06 21:58
http://www.cnblogs.com/superping/p/4884689.html
附件视频文件不可播放,需要在网上重新找一个264文件测试
本文讲述如何使用Android标准的API (MediaCodec)实现H264的硬件解码。
原本我们是用JNI调用平台提供的硬件解码接口得到YUV帧,再放入opengl脚本里处理渲染的。可是换了新平台之后,没有拿到底层的接口,所以这两天找在Android上的H264解码方案。前天在友人的提示下找到了MediaCodec这个类,Android developer上面有MediaCodec的描述和用法,还算详细可以慢慢摸索。但是在网上关于这个类的用法是比较少。
那在这里贴代码介绍一下。
1 // Video Constants 2 private final static String MIME_TYPE = "video/avc"; // H.264 Advanced Video 3 private final static int VIDEO_WIDTH = 1280; 4 private final static int VIDEO_HEIGHT = 720; 5 private final static int TIME_INTERNAL = 30; 6 7 public void initDecoder() { 8 9 mCodec = MediaCodec.createDecoderByType(MIME_TYPE);10 MediaFormat mediaFormat = MediaFormat.createVideoFormat(MIME_TYPE,11 VIDEO_WIDTH, VIDEO_HEIGHT);12 mCodec.configure(mediaFormat, mSurfaceView.getHolder().getSurface(),13 null, 0);14 mCodec.start();15 }
这是初始化解码器操作,具体要设置解码类型,高度,宽度,还有一个用于显示视频的surface。
1 public boolean onFrame(byte[] buf, int offset, int length) { 2 Log.e("Media", "onFrame start"); 3 Log.e("Media", "onFrame Thread:" + Thread.currentThread().getId()); 4 // Get input buffer index 5 ByteBuffer[] inputBuffers = mCodec.getInputBuffers(); 6 int inputBufferIndex = mCodec.dequeueInputBuffer(100); 7 8 Log.e("Media", "onFrame index:" + inputBufferIndex); 9 if (inputBufferIndex >= 0) {10 ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];11 inputBuffer.clear();12 inputBuffer.put(buf, offset, length);13 mCodec.queueInputBuffer(inputBufferIndex, 0, length, mCount14 * TIME_INTERNAL, 0);15 mCount++;16 } else {17 return false;18 }19 20 // Get output buffer index21 MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();22 int outputBufferIndex = mCodec.dequeueOutputBuffer(bufferInfo, 100);23 while (outputBufferIndex >= 0) {24 mCodec.releaseOutputBuffer(outputBufferIndex, true);25 outputBufferIndex = mCodec.dequeueOutputBuffer(bufferInfo, 0);26 }27 Log.e("Media", "onFrame end");28 return true;29 }
具体流程:
1.获取一个可用的inputBuffer的索引(出列)
2.将一帧数据放入inputBuffer
3.将inputBuffer入列进行解码
4.获得一个outputBuffer的索引(出列)
5.释放outputBuffer
6.在4,5间循环直到没有outputBuffer可出列为止
这里解码器有多个输入缓冲区(我测试是有3个),实现不卡顿。
常见的问题:
dequeueInputBuffer和dequeueOutputBuffer经常会获取不了缓冲区(跟机器的性能有关),如果参数为-1,则会一直等待;如果参数为正数,则等待相应的微秒后返回,没有可用缓冲区就会返回-1。
结论:
测试程序是读取一个H264裸流文件,识别每一帧然后将其放入解码器解码以及渲染。读取和识别的代码在Demo中。经测试,不同平台的解码效果还挺大。我播放的是720p的H264文件。最出色的居然是RK(瑞芯微)平台,缓冲区获取很少失败,但是会因为过热重启机器;高通平台试了几台机器(锤子、小米4、还有个别定制机),经常有拿不到缓冲区的情况。MTK的只有一台(TCL么么哒),直接初始化不了解码器。。。
这里跟GPU性能有关,我们解的是720p8m码率的视频,换成较低码率较低分辨率的,大部分机器还是可以正常运行的(除了么么哒)。当然或许有些平台的实现是软解码(使用cpu,ffmpeg方案),这我暂时还没遇到。
Demo链接如下(注意裸流文件要放置的路径):
http://files.cnblogs.com/files/superping/H264Demo.zip
阅读全文
0 0
- Android平台对H264视频硬解码
- Android平台对H264视频硬解码
- Android平台对H264视频硬解码
- iOS 视频h264硬解码
- ios 硬解码h264视频的坑
- Android MediaCodec硬解码H264文件
- Android MediaCodec硬解码H264文件
- iOS h264 硬解码
- ios 硬解码h264
- Android 用MediaCodec实现视频硬解码
- Android 用MediaCodec实现视频硬解码
- Android 用MediaCodec实现视频硬解码
- Android 用MediaCodec实现视频硬解码
- Android 用MediaCodec实现视频硬解码
- Android 用MediaCodec实现视频硬解码
- Android 用MediaCodec实现视频硬解码
- Android 用MediaCodec实现视频硬解码
- Android 用MediaCodec实现视频硬解码
- animeditor-Creating a New Animation Clip
- Android之Socket的基于UDP传输
- CTF/CTF练习平台-welcome to bugkuctf【php://filter及php://input】
- javascript对象创建
- mysql中select查询语句添加自增id
- Android平台对H264视频硬解码
- centos7使用yum安装mariaDB(开源MySQL)无法启动的解决办法
- Android M App 永久隐藏导航栏的Solution
- 单身狗(PAT-1065)
- VimTutor中文版
- 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法
- Spring源码深度解析(五)加载Bean
- Arduino学习日记二
- 【个人笔记重点,不作为参考】主题:数据可视化d3