如何在 Android 上使用硬件加速视频解码?
Posted
技术标签:
【中文标题】如何在 Android 上使用硬件加速视频解码?【英文标题】:How to use hardware accelerated video decoding on Android? 【发布时间】:2012-07-04 12:41:55 【问题描述】:我需要一个研究项目的硬件加速 H.264 解码,以测试自定义协议。
由于我在网络上进行了搜索,因此我找到了几种在 android 上执行硬件加速视频解码的方法。
-
使用 ffmpeg libstagefright (overview of libstagefright) 或直接在操作系统中使用 libstagefright,如here。
在特定硬件平台上使用 OpenMax。喜欢here about samsung device 和here about Qualcomm Snapdragon series
有人提到PVplayer,
有些人"say"libstagefright 是唯一的出路,而高通人显然已经取得了成功。
目前我不确定哪种方式可行。我现在有点困惑。如果一切正常,我当然更喜欢独立于硬件的方法。
我已经用 Galaxy Tab 7.7(3.2 和 Enxyos)测试了一些视频播放器的硬件加速,VLC、Mobo、Rock、vplayer、rock 和 mobo 工作正常,VLC 不工作,vplayer 似乎有一个渲染错误,这会降低其性能。
无论如何,我对 Rockplayer 进行了“操作”并删除了它在 data\data\com.redirecting\rockplayer 中的所有 .so 库,并且软件解码崩溃,而硬件解码仍然可以正常工作!我想知道他们是怎么做到的。 在我看来,硬件加速可以独立于硬件平台。
有人能解决这个问题吗?或者提供任何包含更多信息或更详细信息的参考?
【问题讨论】:
我有点糊涂了!您想直接访问(不使用 Android 媒体 API)到硬件加速解码器来解码您的比特流吗?因为所有现代手机 SOC 都使用硬件加速来解码 H.264。 @OakBytes,我想实现硬件加速解码,但是已经完成了。现在我只知道如何用ffmpeg软件解码来解码流。硬件加速是指 1080P@30fps 的性能水平,而软件解码则要弱得多。我避免将软件解码称为使用 CPU,因为硬件加速模块也是 CPU 的一部分。所有已经使用硬件加速的现代手机是什么意思? 使用 Gallery Media Player 播放 H.264 剪辑时,最近所有的 Android 手机都使用 H/W 加速 H.264 解码器。我猜你打算使用 H.264 解码器来解码原始 H.264 比特流并获得解码输出,而不是播放包含 H.264 视频和一些音频的文件。 @OakBytes 你是对的。这正是我想要的。只是原始比特流,没有 mkv 或 mp4 容器。对不起,我没有说得更清楚。我想基于 NAL 或原始比特流上的帧级别调用 H/W 解码,而不是为文件设置媒体播放器。 @Holyglenn - 你的项目成功了吗?也许你发现了一些关于主题的新信息? 【参考方案1】:为了回答上面的问题,我先介绍几个与Android相关的概念
OpenMAX
Android 使用 OpenMAX 作为编解码器接口。因此,所有本机编解码器(硬件加速或其他)都提供 OpenMAX 接口。 StageFright(播放器框架)使用此接口使用编解码器解码媒体
NDK
Android 允许 Java 应用程序使用 NDK 与底层 C/C++ 本机库进行交互。这需要使用 JNI(Java 原生接口)。
现在来回答你的问题How to tap native decoder to decode raw video bitstream?
在 Android 4.0 及以下版本中,Android 不提供对 Java 层底层视频解码器的访问。您需要编写本机代码才能直接与 OMX 解码器交互。尽管这是可能的,但这并不是一件容易的事,因为它需要了解 OMX 的工作原理以及如何使用 NDK 将此 OMX 映射到应用程序。
在 4.1(Jelly Bean 版本)中,Android 似乎通过 JAVA API 在应用程序级别提供了对硬件加速解码器的访问。有关新 API 的更多详细信息,请访问 http://developer.android.com/about/versions/android-4.1.html#Multimedia
【讨论】:
感谢您对概念和答案的澄清。我浏览了参考资料,却发现我必须深入研究操作系统框架。这肯定行得通。 然而,正如 Rockplayer 上的操作所暗示的那样,我删除了所有 .so 库并且硬件解码仍然有效,而软件解码失败,在 Android 4.0 版本中可能有一些更简单的方法,并且下面。至于我的原始比特流解码等等,我可能不得不弄清楚整个 OMX 的事情。可以给 Jelly Bean 中的 Java API 吗? @Holygenn 我在 Jelly Bean 中添加了指向媒体播放器 API 的链接。对于 RockPlayer,它是使用硬件加速解码器直接显示视频还是为您提供输出缓冲区?使用硬件加速解码器,前者比后者更容易 RockPlayer 是封闭源代码,只有 ffmpeg 的配置是开放的,因此我不确定它使用的是哪个。我的猜测是在解复用后的 Rockplayer 中,原始视频被输入一个开关,让用户根据菜单建议从 sw 3rd 方解码器或 hw 系统解码器中选择,然后处理并显示。我在 Honeycomb 3.2 下做了 Rockplayer 实验。所以似乎有一种方法可以在没有 NDK/JNI 的情况下使用系统编解码器,并不是说 NDK 太麻烦而是探索一种可能性。 据我了解,Jelly bean MediaCodec 为原始比特流提供系统编解码器(SW/HW)。这似乎正是我所需要的——我需要解码(使用硬件)并显示原始视频流。然而,随着好奇心的驱使,我更想知道如何在没有 Jelly Bean 的情况下实现硬件加速解码。非常感谢您迄今为止的帮助。【参考方案2】:使用ExoPlayer (github)。
它是一个由 Google 赞助的开源项目,用于替代平台的 MediaPlayer。管道中的每个组件都是可扩展的,包括示例源(如何从您的自定义协议中提取 H.264 帧)到渲染(到 Surface、SurfaceTexture 等)。
它包括一个不错的demo app showing usage。
【讨论】:
【参考方案3】:您可能想尝试MediaExtractor 和MediaCodec(它们也可用于 NDK - AMediaExtractor 和 AMediaCodec - 在此处查看播放 .mp4 的示例native-codec)
【讨论】:
以上是关于如何在 Android 上使用硬件加速视频解码?的主要内容,如果未能解决你的问题,请参考以下文章
开发那些事儿:如何解决RK芯片视频处理编解码耗时很长的问题?