Chienomi

mesaがH.264とHEVCのサポートを削除

Live With Linux::manjaro

ffmpegでVA-APIを使用したビデオエンコーディングができなくなっており、原因を調べていったところ、mesaがH.264(AVC)とHEVC(H.265)のサポートを削除したようである。

手元にアップデートを適用していないRyzen7 5700U APUを搭載したラップトップがあったので前後で比較してみる。

アップデート前

❯ vainfo
Trying display: wayland
Trying display: x11
vainfo: VA-API version: 1.16 (libva 2.16.0)
vainfo: Driver version: Mesa Gallium driver 22.2.3 for AMD Radeon Graphics (renoir, LLVM 14.0.6, DRM 3.48, 6.0.8-1-MANJARO)
vainfo: Supported profile and entrypoints
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileVC1Simple              : VAEntrypointVLD
      VAProfileVC1Main                : VAEntrypointVLD
      VAProfileVC1Advanced            : VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointVLD
      VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
      VAProfileH264Main               : VAEntrypointVLD
      VAProfileH264Main               : VAEntrypointEncSlice
      VAProfileH264High               : VAEntrypointVLD
      VAProfileH264High               : VAEntrypointEncSlice
      VAProfileHEVCMain               : VAEntrypointVLD
      VAProfileHEVCMain               : VAEntrypointEncSlice
      VAProfileHEVCMain10             : VAEntrypointVLD
      VAProfileHEVCMain10             : VAEntrypointEncSlice
      VAProfileJPEGBaseline           : VAEntrypointVLD
      VAProfileVP9Profile0            : VAEntrypointVLD
      VAProfileVP9Profile2            : VAEntrypointVLD
      VAProfileNone                   : VAEntrypointVideoProc


❯ vdpauinfo
display: :0   screen: 0
API version: 1
Information string: G3DVL VDPAU Driver Shared Library version 1.0

Video surface:

name   width height types
-------------------------------------------
420    16384 16384  NV12 YV12 
422    16384 16384  UYVY YUYV 
444    16384 16384  Y8U8V8A8 V8U8Y8A8 
420_16 16384 16384  
422_16 16384 16384  
444_16 16384 16384  

Decoder capabilities:

name                        level macbs width height
----------------------------------------------------
MPEG1                          --- not supported ---
MPEG2_SIMPLE                    3 78336  4096  4906
MPEG2_MAIN                      3 78336  4096  4906
H264_BASELINE                  52 78336  4096  4906
H264_MAIN                      52 78336  4096  4906
H264_HIGH                      52 78336  4096  4906
VC1_SIMPLE                      1 78336  4096  4906
VC1_MAIN                        2 78336  4096  4906
VC1_ADVANCED                    4 78336  4096  4906
MPEG4_PART2_SP                  3 78336  4096  4906
MPEG4_PART2_ASP                 5 78336  4096  4906
DIVX4_QMOBILE                  --- not supported ---
DIVX4_MOBILE                   --- not supported ---
DIVX4_HOME_THEATER             --- not supported ---
DIVX4_HD_1080P                 --- not supported ---
DIVX5_QMOBILE                  --- not supported ---
DIVX5_MOBILE                   --- not supported ---
DIVX5_HOME_THEATER             --- not supported ---
DIVX5_HD_1080P                 --- not supported ---
H264_CONSTRAINED_BASELINE       0 78336  4096  4906
H264_EXTENDED                  --- not supported ---
H264_PROGRESSIVE_HIGH          --- not supported ---
H264_CONSTRAINED_HIGH          --- not supported ---
H264_HIGH_444_PREDICTIVE       --- not supported ---
VP9_PROFILE_0                  --- not supported ---
VP9_PROFILE_1                  --- not supported ---
VP9_PROFILE_2                  --- not supported ---
VP9_PROFILE_3                  --- not supported ---
HEVC_MAIN                      186 139264  8192  4352
HEVC_MAIN_10                   186 139264  8192  4352
HEVC_MAIN_STILL                --- not supported ---
HEVC_MAIN_12                   --- not supported ---
HEVC_MAIN_444                  --- not supported ---
HEVC_MAIN_444_10               --- not supported ---
HEVC_MAIN_444_12               --- not supported ---
AV1_MAIN                       --- not supported ---
AV1_HIGH                       --- not supported ---
AV1_PROFESSIONAL               --- not supported ---

Output surface:

name              width height nat types
----------------------------------------------------
B8G8R8A8         16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 P010 P016 I8A8 
R8G8B8A8         16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 P010 P016 I8A8 
R10G10B10A2      16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 P010 P016 I8A8 
B10G10R10A2      16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 P010 P016 I8A8 

Bitmap surface:

name              width height
------------------------------
B8G8R8A8         16384 16384
R8G8B8A8         16384 16384
R10G10B10A2      16384 16384
B10G10R10A2      16384 16384
A8               16384 16384

Video mixer:

feature name                    sup
------------------------------------
DEINTERLACE_TEMPORAL             y
DEINTERLACE_TEMPORAL_SPATIAL     -
INVERSE_TELECINE                 -
NOISE_REDUCTION                  y
SHARPNESS                        y
LUMA_KEY                         y
HIGH QUALITY SCALING - L1        y
HIGH QUALITY SCALING - L2        -
HIGH QUALITY SCALING - L3        -
HIGH QUALITY SCALING - L4        -
HIGH QUALITY SCALING - L5        -
HIGH QUALITY SCALING - L6        -
HIGH QUALITY SCALING - L7        -
HIGH QUALITY SCALING - L8        -
HIGH QUALITY SCALING - L9        -

parameter name                  sup      min      max
-----------------------------------------------------
VIDEO_SURFACE_WIDTH              y        48     4096
VIDEO_SURFACE_HEIGHT             y        48     4096
CHROMA_TYPE                      y  
LAYERS                           y         0        4

attribute name                  sup      min      max
-----------------------------------------------------
BACKGROUND_COLOR                 y  
CSC_MATRIX                       y  
NOISE_REDUCTION_LEVEL            y      0.00     1.00
SHARPNESS_LEVEL                  y     -1.00     1.00
LUMA_KEY_MIN_LUMA                y  
LUMA_KEY_MAX_LUMA                y  

アップデート後

❯ vainfo
Trying display: wayland
Trying display: x11
vainfo: VA-API version: 1.16 (libva 2.16.0)
vainfo: Driver version: Mesa Gallium driver 22.2.4 for AMD Radeon Graphics (renoir, LLVM 14.0.6, DRM 3.48, 6.0.11-1-MANJARO)
vainfo: Supported profile and entrypoints
      VAProfileMPEG2Simple            : VAEntrypointVLD
      VAProfileMPEG2Main              : VAEntrypointVLD
      VAProfileJPEGBaseline           : VAEntrypointVLD
      VAProfileVP9Profile0            : VAEntrypointVLD
      VAProfileVP9Profile2            : VAEntrypointVLD
      VAProfileNone                   : VAEntrypointVideoProc

❯ vdpauinfo
display: :0   screen: 0
API version: 1
Information string: G3DVL VDPAU Driver Shared Library version 1.0

Video surface:

name   width height types
-------------------------------------------
420    16384 16384  NV12 YV12 
422    16384 16384  UYVY YUYV 
444    16384 16384  Y8U8V8A8 V8U8Y8A8 
420_16 16384 16384  
422_16 16384 16384  
444_16 16384 16384  

Decoder capabilities:

name                        level macbs width height
----------------------------------------------------
MPEG1                          --- not supported ---
MPEG2_SIMPLE                    3 78336  4096  4906
MPEG2_MAIN                      3 78336  4096  4906
H264_BASELINE                  --- not supported ---
H264_MAIN                      --- not supported ---
H264_HIGH                      --- not supported ---
VC1_SIMPLE                     --- not supported ---
VC1_MAIN                       --- not supported ---
VC1_ADVANCED                   --- not supported ---
MPEG4_PART2_SP                  3 78336  4096  4906
MPEG4_PART2_ASP                 5 78336  4096  4906
DIVX4_QMOBILE                  --- not supported ---
DIVX4_MOBILE                   --- not supported ---
DIVX4_HOME_THEATER             --- not supported ---
DIVX4_HD_1080P                 --- not supported ---
DIVX5_QMOBILE                  --- not supported ---
DIVX5_MOBILE                   --- not supported ---
DIVX5_HOME_THEATER             --- not supported ---
DIVX5_HD_1080P                 --- not supported ---
H264_CONSTRAINED_BASELINE      --- not supported ---
H264_EXTENDED                  --- not supported ---
H264_PROGRESSIVE_HIGH          --- not supported ---
H264_CONSTRAINED_HIGH          --- not supported ---
H264_HIGH_444_PREDICTIVE       --- not supported ---
VP9_PROFILE_0                  --- not supported ---
VP9_PROFILE_1                  --- not supported ---
VP9_PROFILE_2                  --- not supported ---
VP9_PROFILE_3                  --- not supported ---
HEVC_MAIN                      --- not supported ---
HEVC_MAIN_10                   --- not supported ---
HEVC_MAIN_STILL                --- not supported ---
HEVC_MAIN_12                   --- not supported ---
HEVC_MAIN_444                  --- not supported ---
HEVC_MAIN_444_10               --- not supported ---
HEVC_MAIN_444_12               --- not supported ---
AV1_MAIN                       --- not supported ---
AV1_HIGH                       --- not supported ---
AV1_PROFESSIONAL               --- not supported ---

Output surface:

name              width height nat types
----------------------------------------------------
B8G8R8A8         16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 P010 P016 I8A8 
R8G8B8A8         16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 P010 P016 I8A8 
R10G10B10A2      16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 P010 P016 I8A8 
B10G10R10A2      16384 16384    y  NV12 YV12 UYVY YUYV Y8U8V8A8 V8U8Y8A8 P010 P016 I8A8 

Bitmap surface:

name              width height
------------------------------
B8G8R8A8         16384 16384
R8G8B8A8         16384 16384
R10G10B10A2      16384 16384
B10G10R10A2      16384 16384
A8               16384 16384

Video mixer:

feature name                    sup
------------------------------------
DEINTERLACE_TEMPORAL             y
DEINTERLACE_TEMPORAL_SPATIAL     -
INVERSE_TELECINE                 -
NOISE_REDUCTION                  y
SHARPNESS                        y
LUMA_KEY                         y
HIGH QUALITY SCALING - L1        y
HIGH QUALITY SCALING - L2        -
HIGH QUALITY SCALING - L3        -
HIGH QUALITY SCALING - L4        -
HIGH QUALITY SCALING - L5        -
HIGH QUALITY SCALING - L6        -
HIGH QUALITY SCALING - L7        -
HIGH QUALITY SCALING - L8        -
HIGH QUALITY SCALING - L9        -

parameter name                  sup      min      max
-----------------------------------------------------
VIDEO_SURFACE_WIDTH              y        48     4096
VIDEO_SURFACE_HEIGHT             y        48     4096
CHROMA_TYPE                      y  
LAYERS                           y         0        4

attribute name                  sup      min      max
-----------------------------------------------------
BACKGROUND_COLOR                 y  
CSC_MATRIX                       y  
NOISE_REDUCTION_LEVEL            y      0.00     1.00
SHARPNESS_LEVEL                  y     -1.00     1.00
LUMA_KEY_MIN_LUMA                y  
LUMA_KEY_MAX_LUMA                y  

VA-API, VDPAUともに使えない状態だ。 ひっそりとVC1(WMV)も削除されている。

どのような問題か

mesaは特許上の懸念からH.264, HEVCおよびVC1のサポートをデフォルトで無効にすることを決定したようである。

もっとも、これはよく分からない問題だ。 例えばx264やx265のようなソフトウェアであれば、非公式な(ソフトウェア)エンコーダであり、特許侵害の懸念を持つのは妥当な話になる。

ところが、mesaの場合、エンコーダ/デコーダのロジックはビデオカード上にあり、単にストリームをビデオカードに渡しているに過ぎない。 それが問題だというのであれば、どちらかというと「オープンソースのビデオドライバ」という点からして問題になるように思われ、妥当だと考えるのはかなり難しい。

だが、いずにせよmesaはこれらのサポートをデフォルトで無効にするという決断を下し、実施した。 多くのディストリビューションが(少なくとも現時点では)mesaをそのままパッケージしており、この影響を受けて混乱しているようだ。

この問題は特にAMDのビデオカードのユーザーにのしかかっている。

というのも、Nvidiaユーザーは(プロプライエタリの)NvidiaドライバでなくNouveauを使っている人自体が少ないだろうし、Nouveau経由でNVENC/NVDECやCudaが使えない以上、そのような要求をする人はなおさらNvidiaドライバを使う可能性が高い。

また、Intelユーザーは少なくともArchlinuxではサポートが残されている。

こうした問題に対するManjaroの対応はArchlinuxのそれとは別の話になる。 というのも、Manjaroの場合はユーザーフレンドリーを裏切る事態であればそれらのオプションを有効にしてビルドする決断を下す可能性がある(高いわけではない)。 ただ、少なくとも、現時点ではそうではない。

これが意味するところとしては、H.264およびHEVCは広く使われているビデオコーデックであるが、Linuxではこれらを再生したり変換するときにハードウェアビデオアクセラレーションが使えない。 これは、再生したり変換できないという意味ではない。CPUパワーを使って処理することは依然として可能だからだ。 また、NvidiaビデオカードでNvidiaドライバを使う場合は除外される。

ただし、mesaを自分でオプションつきでビルドするという選択は可能である。 これはこの問題を無視して使いつづける(暫定的な)唯一の方法だ。

デコード

現実的な問題として、AMD環境においてH.264及びHEVCのハードウェアデコードを利用することは困難であり、もしCPUパワーでの再生が難しく、その要件があるのであれば、mesaをビルドするよりほかにないだろう。

当初、私は「HEVCでも軽いので4kでも再生は問題ないだろう」と考えていた。 実際、比較的重い動画(例えば4kのMMDなどはかなり重い部類に入る)でもVP9からHEVCに変換することでソフトウェア再生が叶うケースも少なくなかった。 しかし、実際に試してみたところ、自分で撮影した4k60FPSのHEVC動画の再生がかなり厳しかった。

そもそもAMDとしても、ffmpegとしても、デコードはVA-APIによって十分サポートされているからAMFのサポートを必要としないと考えているようであり、mesaの判断が誤ったものに見える。 そして、この状態をいつまでも続けられるわけではないから、mesaが撤回するか、AMDがmesaに働きかけるか、あるいはAMDがAMFサポートを手厚くしてffmpegがそれをサポートするかといった何かしらの方策が取られるだろう。 それが待てないのならば暫定的な対策としてmesaをビルドするよりほかにない。 もし、事態が長引くならManjaroがmesaのビルドオプションを変更する可能性もあるだろう。

Gitリポジトリのhttps://gitlab.manjaro.org/packages/extra/mesaPKGBUILDが含まれているので、こんな感じでオプションを追加して

diff --git a/PKGBUILD b/PKGBUILD
index 3cb5610..b3955a6 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -74,6 +74,7 @@ build() {
     -D osmesa=true \
     -D shared-glapi=enabled \
     -D microsoft-clc=disabled \
+    -D video-codecs=vc1dec,h264dec,h264enc,h265dec,h265enc \
     -D valgrind=enabled
 
   # Print config

あとはmakepkgしてpacman -Uでインストールすれば良い。

これが暫定対策であること(この方法がいつまで使えるか分からない)、自分でビルドしていることを忘れないようにしよう。

エンコード

手立てがないデコードと比べればエンコードはまだ現実的な対応が考えられる。

というのも、AMDはVulkanのAMDGPU Proドライバー経由でH.264のAMFへのアクセスを実装している。 これはH.264だけである。Windowsであればhevc_amfの利用が可能だが、Linuxではh264_amfしか実装されていない。

実際のところ60FPSのデスクトップキャプチャはソフトウェアではかなり困難なので、キャスティングはハードウェアエンコードを必要とするだろう。 従来はVA-APIがその最適な手段であったが、AMFを使うというのは有力な方法だ。 h264_amfであれば4k 60FPSキャプチャも見えてくる。

例えばVA-APIを使ったエンコーディングは次のような形であったが

ffmpeg -vaapi_device /dev/dri/renderD128 -f alsa -thread_queue_size 16384 -i pulse -framerate 60 -f x11grab -thread_queue_size 16384 -analyzeduration 30M -probesize 100M -video_size 1920x1080 -framerate 30 -i $DISPLAY -vf 'format=nv12,hwupload' -r 60 -c:v h264_vaapi -qp 0 -preset ultrafast desktop.mp4

h264_vaapiに代えてh264_amfを使うことができる。

ffmpeg -f alsa -thread_queue_size 16384 -i pulse -framerate 60 -f x11grab -thread_queue_size 16384 -analyzeduration 30M -probesize 100M -video_size 1920x1080 -i $DISPLAY+1920,0 -r 60 -c:v h264_amf -qmin 10 -qmax 25 -profile:v main -quality speed desktop.mp4

h264_amflibamfrt64.so.1を要求するが、これはManjaro(Archlinux)の場合、amf-amdgpu-proで提供されており、このパッケージをビルドしてインストールすれば良い。 ちゃんと理解していなかったが、AMDGPU PROはAMDGPUのようなドライバーではなく、部分ごとに分かれているようだ。

なお、RX6000シリーズユーザーはamf-amdgpu-pro-fixを使うこと。

Intelの場合はh264_qsv, hevc_qsvを使えばよさそうに思えたが、やろうとするとVA-APIを見に行ってしまうのと、どうやってもうまく動かなかったので、現状はVA-APIが使える状態になっているということに甘えるよりほかになさそうだった。

Nvidiaの鞍替えは考えられるか

NvidiaはそもそもVA-APIをサポートせず、VDPAUのサポートも中途半端な状態で投げ出している。 現実的にNvidiaにおいてNVENC/NVDECを使うには、それらを直接扱う必要がある。

幸いにもffmpegやmpvがこれらをサポートしているため、困りはしない。 というよりも、AMF(MCE)とは比べ物にならないほど性能が高いため、ハードウェアビデオアクセラレーションにおいては非常に快適になるだろう。

しかし、NvidiaのLinuxサポートは手薄く、性能的にも機能的にも大きく劣る。 特にスクリーンキャスティングにおいて画面が激しくちらつくといった問題は、ビデオ会議などを多様する現代においては結構厳しいものがある。

このため、mesaの問題があってなお、現状Linuxに最も適しているのはAMDである。