Android 移动设备 (Snapdragon 820) 上使用 C++ 的播放器的 MediaCodec (NDK) 与 OpenMAX
MediaCodec (NDK) vs. OpenMAX for player on Android mobile (Snapdragon 820) using C++
根据审查 Android NDK 下可用的示例,似乎要使用硬件解码器 (OMX.xxx),我们可以使用 MediaCodec 或 OpenMAXAL 接口。
我的问题是:
这是在移动设备(Android 上的骁龙 820)上使用硬件解码器的最佳方式吗?
使用 OMX 比使用 MediaCodec 有什么优势吗?当前 Android headers 实际上只支持 MPEG2/.ts mimetype。我希望您可以通过 OpenMax 支持视频(mp4 等)的流式解码 - 评估正确吗?
我的要求是:
- 支持普通容器流式播放音视频
- 利用移动硬件 (GPU + DSP) 进行解码。
- 逐帧执行图像处理。
- 避免为音频和视频编写自己的时间同步。
我用ffmpeg写了基本的播放器,但是我不能使用硬件解码器,所以没有遵循它。
我对可以实现上述目标的任何其他框架(免费或商业)持开放态度。
一般来说,MediaCodec 是推荐的。
在 MediaCodec 在 Android 4.1 中可用之前,在 Android 4.0 中添加了 OpenMAX AL API 作为权宜之计。它实际上已被弃用(尽管我不确定是否有任何官方声明这么说)。
它们在略有不同的抽象级别上运行,并且在大多数情况下,MediaCodec 的工作较少。
使用 OpenMAX AL,您需要提供数据的 MPEG TS 流来解码和播放。它不支持其他容器格式。它也不会让您直接访问解码数据,但会直接播放。但是,它确实负责音频和视频的同步。
OpenMAX AL 的优点:
- 如果您的输入是 MPEG TS,则可以避免整个额外的步骤
- 自动处理同步
缺点:
- 其他一切
使用 MediaCodec,您需要提供单独的数据包进行解码。它本身根本不支持任何容器格式,但作为调用者的您应该处理好这一点。它确实可以让您直接访问解码后的输出数据,但要呈现它,您需要手动处理同步。 (在 Android 6.0 中,有一个新的 class MediaSync,它可以帮助解决这个问题。)
MediaCodec 的优点:
- 通用、灵活
- 适用于任何容器(不需要重新打包成 MPEG TS)
MediaCodec 的缺点:
- 需要您手动处理同步
- 水平很低,需要你做很多工作
要提取单个数据包,可以使用 MediaExtractor class,这对于静态文件的一些常见文件格式很有用。我不认为它可用于流式传输,例如虽然 MP4 支离破碎。
因此,如果您想对 MPEG TS 以外的格式进行流式播放,您需要自己处理数据包的提取(或使用其他库,例如 libavformat,来完成该任务)。如果您使用 OpenMAX AL,则需要将各个数据包打包回 MPEG TS(使用例如 libavformat)。如果您使用 MediaCodec,您将需要在播放期间处理音频和视频的同步。
如果您需要对解码帧进行处理,MediaCodec 可能是唯一的选择。您可以将解码后的图像数据作为原始 YUV 获取,或者将其获取到可以使用着色器修改的 GL 表面。 (不过,后者也可能使用 OpenMAX AL。)
根据审查 Android NDK 下可用的示例,似乎要使用硬件解码器 (OMX.xxx),我们可以使用 MediaCodec 或 OpenMAXAL 接口。
我的问题是:
这是在移动设备(Android 上的骁龙 820)上使用硬件解码器的最佳方式吗?
使用 OMX 比使用 MediaCodec 有什么优势吗?当前 Android headers 实际上只支持 MPEG2/.ts mimetype。我希望您可以通过 OpenMax 支持视频(mp4 等)的流式解码 - 评估正确吗?
我的要求是:
- 支持普通容器流式播放音视频
- 利用移动硬件 (GPU + DSP) 进行解码。
- 逐帧执行图像处理。
- 避免为音频和视频编写自己的时间同步。
我用ffmpeg写了基本的播放器,但是我不能使用硬件解码器,所以没有遵循它。
我对可以实现上述目标的任何其他框架(免费或商业)持开放态度。
一般来说,MediaCodec 是推荐的。
在 MediaCodec 在 Android 4.1 中可用之前,在 Android 4.0 中添加了 OpenMAX AL API 作为权宜之计。它实际上已被弃用(尽管我不确定是否有任何官方声明这么说)。
它们在略有不同的抽象级别上运行,并且在大多数情况下,MediaCodec 的工作较少。
使用 OpenMAX AL,您需要提供数据的 MPEG TS 流来解码和播放。它不支持其他容器格式。它也不会让您直接访问解码数据,但会直接播放。但是,它确实负责音频和视频的同步。
OpenMAX AL 的优点:
- 如果您的输入是 MPEG TS,则可以避免整个额外的步骤
- 自动处理同步
缺点:
- 其他一切
使用 MediaCodec,您需要提供单独的数据包进行解码。它本身根本不支持任何容器格式,但作为调用者的您应该处理好这一点。它确实可以让您直接访问解码后的输出数据,但要呈现它,您需要手动处理同步。 (在 Android 6.0 中,有一个新的 class MediaSync,它可以帮助解决这个问题。)
MediaCodec 的优点:
- 通用、灵活
- 适用于任何容器(不需要重新打包成 MPEG TS)
MediaCodec 的缺点:
- 需要您手动处理同步
- 水平很低,需要你做很多工作
要提取单个数据包,可以使用 MediaExtractor class,这对于静态文件的一些常见文件格式很有用。我不认为它可用于流式传输,例如虽然 MP4 支离破碎。
因此,如果您想对 MPEG TS 以外的格式进行流式播放,您需要自己处理数据包的提取(或使用其他库,例如 libavformat,来完成该任务)。如果您使用 OpenMAX AL,则需要将各个数据包打包回 MPEG TS(使用例如 libavformat)。如果您使用 MediaCodec,您将需要在播放期间处理音频和视频的同步。
如果您需要对解码帧进行处理,MediaCodec 可能是唯一的选择。您可以将解码后的图像数据作为原始 YUV 获取,或者将其获取到可以使用着色器修改的 GL 表面。 (不过,后者也可能使用 OpenMAX AL。)