我正在为Android开发H264 H / W加速视频解码器。到目前为止,我已经找到了一些库MediaCodec
,Stagefright
,OpenMax IL
,OpenMax AL
和FFmpeg
。经过一番研究,我发现了 -
我在FFmpeg中找到了使用stagefright的great resource,但我不能使用FFmpeg作为其许可证,对分布式软件来说这是非常严格的限制。 (或者可以从这种方法中丢弃FFmpeg?)
我不能将MediaCodec用作Java API,我必须通过C ++层的JNI调用它,这是相对较慢的,我不被允许。
我不能使用OpenMax AL,因为它只支持通过缓冲队列解码MPEG-2传输流。这排除了传递原始h264 NALU或其他媒体格式的问题。
现在只剩下 - stagefright和OpenMax IL。我开始知道stagefright使用OpenMax(OMX)接口。那么我应该使用stagefright还是OpenMax IL?哪个更有希望?
此外,我发现Android H / W加速解码器是特定于供应商的,并且每个供应商都有自己的OMX接口API。这是真的吗?如果是这样,我是否需要编写OpenMax IL的H / W供应商特定实现?那么stagefright呢? - 它是硬件无关的还是硬件依赖的?如果使用stagefright或OpenMax IL无法实现H / W,我至少需要支持Qualcomm的Snapdragon,三星的Exynos和Tegra-4。
请注意,我需要解码H264附件B流,并期望解码后的解码数据,我将发送到我的视频渲染管道。基本上,我只需要解码器模块。
我真的很困惑。请帮助我正确指导。提前谢谢!
修改
我的软件用于商业目的,源代码也是私有的。我也被限制使用客户端的ffmpeg。 :)
答案 0 :(得分:2)
你真的应该选择MediaCodec。通过JNI调用java方法确实有一些开销,但是你应该记住开销的数量级。如果你为每个像素调用一个函数,JNI调用的开销可能会有问题。但是对于使用MediaCodec,每帧只进行一些函数调用,并且开销可以忽略不计。
参见例如http://git.videolan.org/?p=vlc.git;a=blob;f=modules/codec/omxil/mediacodec_jni.c;h=57df9889c97706436823a4960206e323565e221c;hb=b31df501269b56c65327be181cdca3df48946fb1作为使用JNI从C代码中使用MediaCodec的示例。由于其他人也采用了这种方式,我可以向您保证,JNI开销不是考虑其他API而非MediaCodec的理由。
直接使用stagefright或OMX是有问题的; ABI在每个平台版本之间有所不同(因此您可以只针对一个版本,或者针对不同版本进行多次编译,将其全部打包在一个软件包中),并且您必须处理许多特定于设备的怪癖,而MediaCodec应该(在现代版本上)应该在所有设备上都能正常工作。
答案 1 :(得分:1)
我找到了一个很好的使用stagefright与FFmpeg的资源,但我不能使用FFmpeg作为其许可证,它对分布式软件是相当严格的。 (或者可以从这种方法中丢弃FFmpeg?)
那不是真的。 FFmpeg是LGPL,因此您可以在商业可再发行应用程序中使用它。
但是,您可能正在使用经过GPL许可的FFmpeg的模块,例如: libx264。在这种情况下,您的程序必须符合GPL标准。
但即使这对分发软件也不好 - 它只是意味着你需要给你的客户(无论如何应该是国王),访问他们支付的应用程序的源代码,并且不允许限制他们的自由恕我直言也不错。
此外,我发现Android H / W加速解码器是特定于供应商的,并且每个供应商都有自己的OMX接口API。这是真的吗?
显然,是的。如果您需要硬件加速,有人必须编写一个程序,使您的特定硬件加速。