抄来看看
今天我们来分享以下关于Android平台上面的视频编码机制
在所有的Android平台上进行视频编码都是一件很痛苦的事情,即使到了Android4.3,这种
状况依然没有很大的改变。在Android当中我们很难找到一个效率高同时又免费的将视频编成
AVC/H.264格式。对于Android5.0还没有更细微的研究,所以我们现在暂时先分析
android 4.4以前当中Android各个版本当中的视频编码实现机制。
从Android诞生之日起,MediaRecorder的相关API就没有大的改变过,也就是说从Android1.0到
现在的Android4.3之间一直没有很实用的关于视频编码的API被添加。但是Google自己开发的视频
聊天App--Google Talk对视频编码的处理十分出色。所以如果我们仔细的浏览一下AOSP就会发现那些
用于支持Google Talk实现的关于视频编码的部分的代码(当然Google Talk本身是不开源的。但是
支持Google Talk实现的那部分代码是位于AOSP当中的)。
如果我们想要录制高质量的视频,那么我们就需要深入的了解Android内部提供的关于视频编码的
实现。我们将会分析Android当中提供的MediaRecorder, OMXCodec, MediaCodec, Software encoding
一共4种方式。
(1) MediaRecorder
在很长的一段时间内,我们在Android当中只能使用这个API来录制视频。简单又稳定。但是这个API
只支持对来自Camera preview的frame进行编码。也就说如果你的permission节点当中没有声明
使用camera的权限,你甚至都不能使用MediaRecorder的API。
然后在Android 4.0当中,Google引入了一个隐藏的API,就是GRALLOC_BUFFER.如果我们使用的
是原生的Android系统的话,在ICS版本当中的Camera程序当中一定体验过一个短暂的人脸渐变动画(short-lived
face morphing feature).这个功能的实现是基于一个Hidden API实现的。这个隐藏的API
允许我们可以对来自Surface的frame进行编码。这个API在Android 4.3当中仍然是隐藏的。
关于如何使用Hidden API,网络上又很多教程,其中最简单的办法就是通过reflection。
但是使用隐藏的API本身有点不太稳定,毕竟有的OEM厂商会将AOSP当中的Hidden API删除掉,
例如某粮食品牌手机。
(2) OMXCodec
这种办法的编码过程(encoding)没有解码(decoding)过程稳定,但是比起来MediaRecorder的GRALLOC_BUFFER
来说稳定多了。
使用这种解决办法比使用MediaRecorder要灵活的许多,你可以在stagefright当中同时使用多个
MediaWriter,或者使用自己重新定制的MediaWriter。
如果你想做一些关于视频流(video streaming)的处理或者生成一些特殊的视频容器(video containers),
这个API将会特别好使用。
(3) MediaCodec
这个API是Android 4.1当中才引入的。在Android 4.3当中被优化和改进了一些。
他可以像GRALLOC_BUFFER那样直接提供从surface当中编码视频帧(encode video frame).Google可能会在
以后逐渐的见GRALLOC_BUFFER移除掉,或者deprecate掉。因为Google现在已经发布了具有同样功能的
MediaCodec,但是依然将GRALLOC_BUFFER设置成@hide.
所以如果你的程序的target platform是4.3的话,请优先使用这个api。但是缺点就是文档比较少,教程
也少。在一些特定的设备上甚至都会直接崩掉。
将编码过的帧(frame)封装到一个合适的视频容器(video container)当中是一个很困难的过程,但是直接使用
MediaMutex提供的API功能又十分有限。
在Android 4.1+以上的平台上,MediaCodec需要不同的颜色格式(color formats)作为输入缓冲区(input buffer),
MediaCodec的性能还是很高的,但是没有MediaRecorder稳定,在某些特定的设备上和定制的ROM上会崩掉。
(4) Software encoding
以上提到的三种方法都是基于硬件的编码。软编码的方式相对来说就是更稳定,同时移植性也更好。当然
唯一的缺点就是太难了。还有一个致命的缺点就是跟硬编码相比太慢了,尤其是软编码720P以及以上的视频时,
基本上就挂了。
所以我们在这里也就是提提,当然如果你足够土壕可以购买商业的解决办法,真的是很贵。
所以说还是要多看源代码,即使我们不做系统级的开发,但是我们会将会经常发现SDK当中提供的API并不能
直接解决我们遇到的需求,不是性能达不到,就是干脆解决不了问题。所以我们需要仔细的查看AOSP的代码,
然后查看里面的实现,有一些Hidden API会解决我们的问题。或者查看他们的实现,然后自己单独的移植
出来都可以帮助我们解决问题。
以上只是从理论上进行粗略的分析。并没有提供详细的代码和实现方面的方向。所以我只是提供一个大致的方向。
可以顺着这个方向查看源代码,或者直接Google。
希望以上的文章能对你有所帮助。