Android平台对H264视频硬解码
本文讲述如何使用Android标准的API (MediaCodec)实现H264的硬件解码。
原本我们是用JNI调用平台提供的硬件解码接口得到YUV帧,再放入opengl脚本里处理渲染的。可是换了新平台之后,没有拿到底层的接口,所以这两天找在Android上的H264解码方案。前天在友人的提示下找到了MediaCodec这个类,Android developer上面有MediaCodec的描述和用法,还算详细可以慢慢摸索。但是在网上关于这个类的用法是比较少。
那在这里贴代码介绍一下。
// Video Constants
private final static String MIME_TYPE = "video/avc"; // H.264 Advanced Video
private final static int VIDEO_WIDTH = 1280;
private final static int VIDEO_HEIGHT = 720;
private final static int TIME_INTERNAL = 30; public void initDecoder() { mCodec = MediaCodec.createDecoderByType(MIME_TYPE);
MediaFormat mediaFormat = MediaFormat.createVideoFormat(MIME_TYPE,
VIDEO_WIDTH, VIDEO_HEIGHT);
mCodec.configure(mediaFormat, mSurfaceView.getHolder().getSurface(),
null, 0);
mCodec.start();
}
这是初始化解码器操作,具体要设置解码类型,高度,宽度,还有一个用于显示视频的surface。
public boolean onFrame(byte[] buf, int offset, int length) {
Log.e("Media", "onFrame start");
Log.e("Media", "onFrame Thread:" + Thread.currentThread().getId());
// Get input buffer index
ByteBuffer[] inputBuffers = mCodec.getInputBuffers();
int inputBufferIndex = mCodec.dequeueInputBuffer(100);
Log.e("Media", "onFrame index:" + inputBufferIndex);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
inputBuffer.put(buf, offset, length);
mCodec.queueInputBuffer(inputBufferIndex, 0, length, mCount
* TIME_INTERNAL, 0);
mCount++;
} else {
return false;
}
// Get output buffer index
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = mCodec.dequeueOutputBuffer(bufferInfo, 100);
while (outputBufferIndex >= 0) {
mCodec.releaseOutputBuffer(outputBufferIndex, true);
outputBufferIndex = mCodec.dequeueOutputBuffer(bufferInfo, 0);
}
Log.e("Media", "onFrame end");
return true;
}
具体流程:
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
Android平台对H264视频硬解码的更多相关文章
- Android 用MediaCodec实现视频硬解码
http://blog.csdn.net/halleyzhang3/article/details/11473961 http://www.360doc.com/content/14/0119/10/ ...
- Android 用MediaCodec实现视频硬解码(转)
本文向你讲述如何用android标准的API (MediaCodec)实现视频的硬件编解码.例程将从摄像头采集视频开始,然后进行H264编码,再解码,然后显示.我将尽量讲得简短而清晰,不展示 那些不相 ...
- 【Android 直播软件开发:音视频硬解码篇】
开篇 炙手可热,望而生畏的音视频开发 时至今日,短视频App可谓是如日中天,一片兴兴向荣.随着短视频的兴起,音视频开发也越来越受到重视,但是由于音视频开发涉及知识面比较广,入门门槛相对较高,让许许多多 ...
- MediaCodec在Android视频硬解码组件的应用
https://yq.aliyun.com/articles/632892 云栖社区> 博客列表> 正文 MediaCodec在Android视频硬解码组件的应用 cheenc 201 ...
- WPF 视频硬解码渲染播放(无空域)(支持4K、8K、高帧率视频)
MediaWPF 基于 .NET 6 实现视频硬解码渲染Demo(无空域问题) 代码实现仅供学习参考 本项目视频渲染通过显卡进行视频解码,CPU几乎不参与工作,并且不存在令人烦躁的空域问题. 在播放摄 ...
- 【GPU编解码】GPU硬解码---DXVA
前面介绍利用NVIDIA公司提供的CUVID库进行视频硬解码,下面将介绍利用DXVA进行硬解码. 一.DXVA介绍 DXVA是微软公司专门定制的视频加速规范,是一种接口规范.DXVA规范制定硬件加速解 ...
- 【GPU编解码】GPU硬解码---DXVA (转)
前面介绍利用NVIDIA公司提供的CUVID库进行视频硬解码,下面将介绍利用DXVA进行硬解码. 一.DXVA介绍 DXVA是微软公司专门定制的视频加速规范,是一种接口规范.DXVA规范制定硬件加速解 ...
- 【计算机视觉】【并行计算与CUDA开发】GPU硬解码---DXVA
前面介绍利用NVIDIA公司提供的CUVID库进行视频硬解码,下面将介绍利用DXVA进行硬解码. 一.DXVA介绍 DXVA是微软公司专门定制的视频加速规范,是一种接口规范.DXVA规范制定硬件加速解 ...
- iOS8系统H264视频硬件编解码说明
公司项目原因,接触了一下视频流H264的编解码知识,之前项目使用的是FFMpeg多媒体库,利用CPU做视频的编码和解码,俗称为软编软解.该方法比较通用,但是占用CPU资源,编解码效率不高.一般系统都会 ...
随机推荐
- 【Ecstore】为自建模块添加自定义主题模板
做好ECSOTRE模块后,需在主题中添加模板,而添加模板页面时只有产品分类页.产品详细页.首页等内置模块的模板类型. 下面介绍如何添加一个自定义的模板类型“buildings”. 一.修改(建议复制到 ...
- URL锚点定位
我们都知道<a>标签中的url属性有三种值: 绝对 URL - 指向另一个站点(比如 href="http://www.example.com/index.htm") ...
- 浅谈window.attachEvent
以前写 JavaScript 脚本时,事件都是采用object.event = handler;的方式初始化.这种方式对于 Internet Explorer.Mozilla/Firefox 和 Op ...
- 检测.net framework 版本
项目中,自己要制作asp.net项目的安装文件,由于项目依赖于.net framework 3.5 sp1,故需检测环境是否符合要求,才能安装程序 度娘找到检测方案:各.net版本对应的安装补录下都有 ...
- MVC Controller 与 View 传值
Controller 到 View 1 强类型 控制器 // GET: /Test/ public ActionResult Index() { DateTime date = DateTime.No ...
- 前端MVVM学习之KnockOut(一)
MVVM理解 MVVM即Model-View-viewModel,是微软WPF和MVP(Model-View-Presenter)结合发展演变过来的一种新型架构框架. MVVM设计模式有以下优点: ( ...
- Html辅助方法 之 Form表单标签
一.Html.BeginForm <form>标签 //视图代码@using (Html.BeginForm("search", "home", F ...
- WPF 利用子线程弹出子窗体的研究
一般来说子线程都是用来处理数据的,主窗体用来实现展现,但是有些时候我们希望子窗体实现等待效果,遮挡主窗体并使主窗体逻辑正常进行,这个业务需求虽然不多,但是正好我们用到了,于是我打算把研究成果写在这了. ...
- bzoj1644 [Usaco2007 Oct]Obstacle Course 障碍训练课
Description 考虑一个 N x N (1 <= N <= 100)的有1个个方格组成的正方形牧场.有些方格是奶牛们不能踏上的,它们被标记为了'x'.例如下图: . . B x . ...
- Contains Duplicate II 解答
Question Given an array of integers and an integer k, find out whether there are two distinct indice ...