【问题标题】:MediaCodec (NDK) vs. OpenMAX for player on Android mobile (Snapdragon 820) using C++ [closed]使用 C++ 的 Android 手机(Snapdragon 820)播放器的 MediaCodec(NDK)与 OpenMAX [关闭]
【发布时间】:2020-07-24 00:02:09
【问题描述】:

根据查看 Android NDK 下可用的示例,看来为了使用硬件解码器 (OMX.xxx),我们可以使用 MediaCodec 或 OpenMAXAL 接口。

我的问题是:

  1. 这是在移动设备上使用硬件解码器(Android 上的 Snapdragon 820)的最佳方式吗?

  2. 使用 OMX 优于 MediaCodec 有什么优势吗?当前的 Android 标头实际上仅支持 MPEG2/.ts mimetype。我希望您可以支持通过 OpenMax 对视频(mp4 等)进行流式解码 - 评估是否正确?

我的要求是:

  1. 支持普通容器的流式音频和视频播放。
  2. 利用移动硬件 (GPU + DSP) 进行解码。
  3. 按帧执行图像处理。
  4. 避免为音频和视频编写自己的时间同步。

我用ffmpeg写过基本的播放器,但是我还不能使用硬件解码器,所以没有关注它。

我对任何其他可以实现上述目标的框架(免费或商业)持开放态度。

【问题讨论】:

    标签: android android-mediacodec


    【解决方案1】:

    一般来说,推荐使用 MediaCodec。

    在 Android 4.1 中提供 MediaCodec 之前,OpenMAX AL API 作为权宜之计已添加到 Android 4.0 中。它实际上已被弃用(尽管我不确定是否有任何官方声明这么说)。

    它们在稍微不同的抽象级别上运行,在大多数情况下,MediaCodec 的工作量较少。

    使用 OpenMAX AL,您需要提供数据的 MPEG TS 流以进行解码和播放。它不支持其他容器格式。它也不让您直接访问解码的数据,而是直接播放。但是,它确实负责音频和视频的同步。

    OpenMAX AL 的优点:

    • 如果您的输入是 MPEG TS,您可以避免整个额外步骤
    • 自动处理同步

    缺点:

    • 其他一切

    使用 MediaCodec,您需要提供单独的数据包进行解码。它本身根本不支持任何容器格式,但您作为调用者应该负责这一点。它确实使您可以直接访问解码的输出数据,但要呈现它,您需要手动处理同步。 (在 Android 6.0 中,有一个新的 MediaSync 类,它可以帮助解决这个问题。)

    MediaCodec 的优点:

    • 通用、灵活
    • 同样适用于任何容器(不需要重新打包到 MPEG TS)

    MediaCodec 的缺点:

    • 需要您手动处理同步
    • 相当低级,需要你做很多工作

    对于提取单个数据包,有 MediaExtractor 类,它对于静态文件的一些常见文件格式很有用。我认为它不适用于流媒体,例如虽然是碎片化的 MP4。

    因此,如果您想对 MPEG TS 以外的格式进行流式播放,您需要自己处理数据包的提取(或使用其他一些库,例如 libavformat 来完成该任务)。如果您使用 OpenMAX AL,则需要将各个数据包打包回 MPEG TS(使用例如 libavformat)。如果您使用 MediaCodec,则需要在播放期间处理音频和视频的同步。

    如果您需要对解码后的帧进行处理,MediaCodec 可能是唯一的选择。您可以将解码的图像数据作为原始 YUV 获取,也可以将其获取到可以使用着色器修改的 GL 表面中。 (不过,后者也可以使用 OpenMAX AL。)

    【讨论】:

    • 您好 mstorsjo,感谢您快速进行利弊分析。我已经使用 FFmpeg + OpenCV 实现了基本的流式传输——它完成了我需要的所有事情,但同步不是 100%,因为我必须丢弃音频帧并且没有硬件加速。我认为对于 MediaCodec,它可以流式传输在线提到的 mp4、webp 等格式。我会仔细检查。看来 MediaCodec 将是可行的方法 - 再次感谢。
    • 还有一个问题 - MediaCodec 是否保证它将使用硬件解码器,如果失败则回退到 sw 模式?
    • 使用MediaCodec,您可以手动选择要使用的编解码器;如果它被命名为OMX.google.*,它是一个软件编解码器,否则它可能是一个硬件编解码器。如果您使用MediaCodec.createDecoderByType,实际上您应该始终首先获得一个硬件编解码器(如果可用)。有关详细信息,请参阅stackoverflow.com/questions/37715529/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 2015-12-02
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 2011-03-05
    相关资源
    最近更新 更多