FFmpeg Android 硬件编解码现状及展望

一、功能特性

自FFmpeg 6.0版本开始,FFmpeg对Android硬件编解码的支持逐步完善了,当前支持的功能特性包括:

  • 通过JNI调用Java MediaCodec
  • 直接调用NDK MediaCodec
  • 解码:H264、H265、MPEG2、MPEG4、VP8、VP9、AV1
  • 编码:H264、H265、MPEG4、VP8、VP9、AV1
  • 输入输出方式
    • Surface/ANativeWindow作为编码器输入,作为解码器输出
    • Buffer输入输出:YUV420P/NV12格式的AVFrame

值得一提的是,Java MediaCodec和NDK MediaCodec两套编解码的实现是共存的,运行时可以通过参数控制选择用哪一个,并且在获取不到JVM时,自动选择NDK MediaCodec的实现。

基于NDK MediaCodec的实现一方面性能更好,另一方面是可以脱离JVM环境运行:

  1. 你可以在adb命令行里执行FFmpeg命令做硬件编解码,做推流
  2. 你也可以在App程序里直接调用FFmpeg命令行

Android上运行FFmpeg命令行,当前有两大热门的应用场景:

  1. termux https://github.com/termux/termux-app
  2. ffmpeg-kit https://github.com/arthenica/ffmpeg-kit

二、亮点功能

做Android音视频开发的同学熟悉,MediaCodec编码器对非16整数倍分辨率的视频有兼容性问题,特别是早期华为麒麟的芯片,容易crash。我在FFmpeg里实现MediaCodec硬件编码时,通过FFmpeg自带的bsf(bit stream filter)解决了和分辨率相关的兼容性问题。简单来说,就是自动做align,再通过bsf修改输出的码流,修改SPS中的crop部分,裁切掉多余的padding。

三、已知缺陷

当前编码器支持YUV420P和NV12两种pixel format输入。但是,某些芯片只支持NV12格式,配置YUV420P格式会报错。

1、设备支持哪种pixel format,Android只提供了Java的API,没有NDK API,没有JVM时就没法查询

2、即使能够查询,也得要知道MediaCodec编码器的名字,知道MediaCodec编码器的名字是在avcodec open之后,设置pixel format是在avcodec open之前

3、编码器的pixel format是用户设定的,不像解码器有个get_format回调能够协商

以上种种困难导致的后果就是,如果你设置编码器输入格式是YUV420P,打开编码器可能失败。

NV12基本都支持,一般建议用NV12格式。之所以提供YUV420P作为一个选项,是在输入图像本身是YUV420P的情况下,省去一道YUV420P到NV12的转换,提升性能。

最近发现的另一个问题是:有个Vivo手机,用的联发科天玑9000的CPU,AMediaFormat_getRect返回图像的right/bottom信息错乱了,结果是解码正常,但是按照crop信息输出,图像只剩一小块了。可能要加黑名单,忽略掉联发科芯片返回的crop信息。

四、展望

未来我会重点放在NDK MediaCodec上,通过JNI调用Java MediaCodec实在繁琐,只做基本维护,不做开发了。

高版本Android提供了异步的NDK MediaCodec接口,我在编码器上实现了一个版本,性能提升挺明显的,patch还没合并到FFmpeg仓库里,打算再多做些测试。解码器也会加上异步方式,只是原有的解码器实现比较乱,收拾起来要花更多时间。

等给FFmpeg MediaCodec加上异步的支持之后,再支持鸿蒙的硬件编解码基本水到渠成了,因为看公开的API,基本上只是把Android MediaCodec的API换了个鸿蒙的前缀。现在没有开发测试环境,等有条件再说吧!

关于10bit的编解码支持,当前可以用Surface/ANativeWindows做输入输出来实现,Android没提供可用的10bit的pixel format。HDR编码的支持,看Android API情况和应用场景而定,对我而言优先级不高。类似的还有tunneled 模式,支持起来也许不难,但是构造测试场景麻烦。

肯定还有其他场景我没考虑到的,欢迎来聊。

作者:quink
来源:公众号——Fun With FFmpeg
原文:https://mp.weixin.qq.com/s/lBfbFGF6ryGs_WR21yBhRA

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论