FFmpeg macOS硬件转码近似最优解

FFmpeg上的硬件加速涉及以下三块:

  1. 硬件上下文 `libavutil/hwcontext*`
  2. 硬件编解码
  3. 硬件filter

hwcontext在硬件解码、硬件编码、硬件filter之间起到配置硬件、维护上下文、支持多种硬件加速API之间互操作的作用。如果不注意hwcontext的配合使用,硬件编解码也能运行,但是性能表现很差。很多人卡在这里,不知如何优化。

另一方面,即使指定了hwcontext,因为FFmpeg转码处理自动配置的流水线会引入CPU做计算的filter,又引入了性能损失。一方面是GPU拷贝到CPU再拷贝到GPU的数据拷贝开销,一方面是CPU filter的计算开销。

硬件加速性能优化核心是全流水线在GPU运行 + 砍去不必要的开销。

FFmpeg很早就支持macOS/iOS videotoolbox:

  • FFmpeg 2.8 (2015年)支持videotoolbox解码
  • FFmpeg 3.1 支持videotoolbox H.264编码
  • FFmpeg 4.0 支持videotoolbox H.265编码

但总体来说,FFmpeg社区开发者多数不熟悉macOS平台开发,熟悉macOS的开发者又不熟悉FFmpeg,FFmpeg对videotoolbox的支持力度不够。我日常使用macOS,仅当作Unix来用,不是macOS/iOS开发者。用的过程中发现不少FFmpeg videotoolbox编解码bug,顺便试着修复了。

除了bug,我还发现FFmpeg缺少macOS平台的硬件filter。虽然理论上,FFmpeg支持vulkan filter,macOS也有vulkan SDK,但是FFmpeg vulkan要求最新的vulkan版本,macOS的vulkan SDK又是非原生支持的,FFmpeg + vulkan + macOS很难跑起来,目前看没有实用价值。

图像filter里最常用的功能是缩放、旋转、色彩空间转换。videotoolbox framework中除了编解码,还有:

  1. VTPixelTransferSession:实现了缩放和色彩空间转换等功能
  2. VTPixelRotationSession:图像旋转、反转等

https://developer.apple.com/documentation/videotoolbox/vtpixeltransfersession?language=objc

刚好满足了最常用的图像filter功能。我在FFmpeg libavfilter加上了这两个的封装:

  • libavfilter/vf_scale_vt.c
  • libavfilter/vf_transpose_vt.c

注意ffmpeg内的rotate filter是可以360°任意角度旋转的,不要求是90°的整数倍。transpose filter支持90°整数倍旋转和上下左右翻转。

全链路硬件加速转码示例如下:

./ffmpeg -hwaccel videotoolbox \
  -hwaccel_output_format videotoolbox_vld \
  -i ios-265.mov \
  -c:v hevc_videotoolbox \
  -profile:v main \
  -b:v 3M \
  -vf scale_vt=w=iw/2:h=ih/2:color_matrix=bt709:color_primaries=bt709:color_transfer=bt709 \
  -c:a copy \
  -tag:v hvc1 \
  /tmp/test.mp4
  • -hwaccel videotoolbox 提供videotoolbox硬件上下文,主要功能是硬件内存buffer分配;它的另一个功能是封装了CPU和GPU之间的数据传输拷贝,但在这个例子中用不到
  • -hwaccel_output_format videotoolbox_vld 指定了硬件输出图像格式;
    • 如不指定,一般默认会选中NV12
    • 指定了videotoolbox_vld,FFmpeg不会自动插入CPU filter,图像在GPU内存,如果需要的话,可以用hwdownload filter下载到CPU
    • 用软件解码器的时候,也可以用硬件filter,只需要先hwupload到GPU
  • FFmpeg videotoolbox视频解码不是单独的一个解码器,是在h264、h265解码器上的加速。有几个硬件视频解码加速都是这么实现的,一个公共的管理调度 + 不同的硬件加速。最新的是av1解码,FFmpeg内置的av1解码器,没有软件实现,全靠硬件加速完成解码功能。指定了-hwaccel videotoolbox之后,FFmpeg自动启用videotoolbox解码
  • -c:v hevc_videotoolbox指定编码器
  • -vf scale_vt=w=iw/2:h=ih/2:color_matrix=bt709:color_primaries=bt709:color_transfer=bt709
    • scale_vt是用VTPixelTransferSession实现的filter
    • w=iw/2:h=ih/2 宽高缩小一半
    • color_matrix=bt709:color_primaries=bt709:color_transfer=bt709 进行色彩空间转换
  • -tag:v hvc1与mp4封装有关,Apple平台要求hvc1,不指定的话默认是hev1,Apple系统播放器不支持

示例中,输入文件是4K HDR视频,

Input: hevc (Main 10) (hvc1 / 0x31637668), yuv420p10le(tv, bt2020nc/bt2020/arib-std-b67), 3840×2160

缩放加色彩空间转换之后,视频信息如下:

Output: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv, bt709, progressive), 1920×1080

整个流程性能接近最优。编码器本身还有一些参数配置可以优化,以后再分析。

作者:quink
来源:Fun With FFmpeg
原文:https://mp.weixin.qq.com/s/Yjp3erEARiha5A0drB4OBg

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

(0)

相关推荐

发表回复

登录后才能评论