如何在 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 上使用硬件加速视频解码?的主要内容,如果未能解决你的问题,请参考以下文章

GPU编解码GPU硬解码---DXVA

开发那些事儿:如何解决RK芯片视频处理编解码耗时很长的问题?

Android 用MediaCodec实现视频硬解码

FFmpeg使用显卡进行转码硬件加速的记录,以及和软压的比较

Android 用MediaCodec实现视频硬解码

iOS 视频硬解码