Chienomi

動画エンコーディングから考える計算リソース

Live With Linux::basic

最近、原神というゲームを始めたのだが、このゲームはとにかく時間が溶けるゲームで、気づいたら5時間くらい経っているとかザラだ。

結果としていろんなものが滞っているのだが、こうして記事に出来たりもするので大目に見て欲しい。

ところで、私はよく人に教えるときに「コンピュータ時間・CPU時間視点で考えろ」という話をするのだけど(常にそうであるべきという話ではなく、その視点が持てなくてはならないという意味である)、その説明に非常に適している状況であると思ったので、せっかくだから活用しようと思う。

前提

私はゲームプレイ動画はVP9 WebMで保存している。

VP9(libvpx-vp9)はアクションカムで撮るような、動きのあるカメラ映像には適さない。のっぺりとした画像になってしまい、まだしもH.264(libx264)のほうが優れる。

だが、画面の部分が更新されるゲームやアニメにおいてはかなりの高圧縮でも劣化が目立たない。 H.265(libx265)ではわりと圧縮を緩めてもブロックノイズや字幕周りのゴーストが出るため、こうした場合にはVP9の優位性を感じる。 なぜか動画コーデックを比較する記事は大抵がアニメ映像を用いているため、VP9に良い結果が出る傾向があるだろう。

アクションRPGの画面は常に動いているため、必ずしもVP9が最適とは言えない。 だが、それでもゲーム画面はカメラのものと比べ階調が平坦であることもあり、VP9のほうが良好な結果を得られる。

だが、libvpx-vp9には大きな欠点がある。それは、計算量が多いことだ。 私が愛用するRyzen7 3700Xマシンはワットパフォーマンスを重視した良いマシンだが、残念ながらRadeon ReLiveで撮影したFHDの原神プレイ動画のエンコード速度は5〜6FPS程度である。 また、libvpx-vp9は並列性が低い。全くのシングルスレッドではないが、1.5スレッドくらいの感覚である。マルチスレッド化することはできるが、そうすると目立って画質が悪くなる割に、速度は伸びない。

CPU時間

5〜6FPSというのはなかなか問題である。

ReLiveの録画は60FPSであるから、1日3時間プレイしただけで1日でエンコードできなくなるということを意味する。 なんということだ。原神を1日3時間なんて殺生な!!!

と考えてしまう人は計算機を回し続けることに対する意識が足りない。

前述の通り、libvpx-vp9は基本的に並列化されていない。 3700Xは8コア16スレッドであるため、複数動画を同時に処理してもあまり処理速度は落ちない。 全く落ちない、ではないのだが、合計処理フレーム数は並列で走らせたほうが伸びる。処理速度が落ちてしまうので避けたいところだが、処理フレーム数だけで言えば、コア数と同じくらいの並列度は問題ないし、むしろそのほうが効率的だ。

仮にここでは4並列でエンコードするとする(8コア16スレッドの3700Xで、およそ、4並列までは処理速度に変動はなく、8並列まで合計での効率は伸び続ける)。 処理能力的には6FPSとすると、実時間の10倍の時間をかけていることになる。 10時間のプレイ動画なら100時間の処理時間が必要だ。

だが、合計処理量だけでいえば、1日で2.4時間分の動画を処理できるわけではなく、4並列で9.6時間分処理できることを意味する。 1日10時間プレイすると間に合わない計算だが、だいぶプレイできる時間は伸びた。毎日10時間プレイするのは生活的に厳しいから、なんとかなるくらいだろう。全部録画しているわけでもないし。

だが、注意すべきは、単独の動画ファイルの処理時間が短縮されるわけではない、ということだ。 10時間の動画ファイルの変換に100時間連続で走らせる必要があるという点は変わらない。 何日分か貯めておき、それを一気に変換すると何日も連続して走らせることになるが、プレイして追加された分をまた追加し、それを続けて処理するようにする、としていくとやがて消化できる可能性が高い。 もちろん、それはPCの処理能力にもよるし、Xeon Silver 4114だと2FPSも出ないため果てしない時間がかかるようになる。 いや、本当に大量の動画があり、それをただ処理するだけのマシンとしては並列数が増えるので悪くないのだが、それでも途方もなく時間がかかる。

また、並列数が増えた分、データが非常に断片化する。SSDに対してそれなりに大きなダメージがあることは覚悟しなくてはならない。 もっとも、私はこの処理したデータはもっと大きなストレージに転送してしまっているし、このSSDはF2FSでちょいちょいフォーマットされているので、対策済みとは言える。書き込み量だけでいえば、そこまで多いわけでもない。SSDを消耗品にしている感覚はあるが。

特にLUKSを使っている場合、Discardが通常効かないのと、Discardしても効果がいまいちだったりするので、時々データを対比してDiscard込みでファイルシステムを作り直したほうが良い。

エンコード時間

しかし、現状で動画コーデックというのは私の満足するレベルにない。 データサイズがまだ十分に小さくない、というのもあるが、劣化という面で見ると、気にならない程度の劣化に抑えられるサイズが大きすぎる。 そして、なおかつ処理時間が長い。

もちろん、ハードウェアエンコーダがあるわけだが、制約が厳しい上に品質が十分でない。 ハードウェアエンコーダによる処理はデータ保存に適しているとは言い難い。「録画用」だろう。

3700Xは大抵の処理において不足を感じる余地がない高性能なCPUであり、ラインナップがどうかではなく、実際性能として相当な処理能力がある。 もはやそれ以上の処理能力が意味を持たないタスクが大半の中、以前として動画エンコードが非常に重い。

もちろん、動画エンコードを中心価値として考えるならばプロセッサが遅い、と見ることができるが、実際のところ動画エンコードは際立って遅いのであり、処理能力向上によって見違えるほど速くなっているわけでもない。コア数を活用するのも難しく、libvpx-vp9は並列数を増やすのは画質とトレードオフであるし、libx265は中途半端な並列化だ。

だから結局、エンコーダの性能が満足するものではない、という結論であると思う。 「サイズを縮小するために計算量が増え遅くなった」という主張は正しくない。libtheoraはlibvpxよりも遅い(多くの場合、libvpx-vp9よりも遅い)。 エンコーダの進化は明らかにニーズに追いついておらず、libaomのAV1は現実的な速度でエンコードできないし、動画ソースが120FPSや144FPS、4k、はては8Kになろうという状況で、サイズも速度もどちらも妥当な範囲に収まっていない。

コンピュータリソースが特定の重い処理のためだけに極端な要求をされる、というのはあまり好ましいことではない。もちろん、それが特殊な要求であるならばやむなしではあるが、動画エンコードというのはむしろPCにとって今やマストな要求であるとすら言える。

その解決策としてハードウェアエンコーダを使う、というのはとても正しい。 実際、動画再生が現代のコンピュータにとっても重いためにハードウェアデコーダによって快適な再生を可能にするのはどう考えても妥当だろう。

ところが、ハードウェアエンコーダは品質が低く、また制限が非常に厳しい。 Radeon ReLiveのFHDキャプチャはだいたい25Mbpsであるが、1ヶ月程度で1TBのディスクが埋まるようなデータサイズが現代において許容可能であるとはとても思えないし、AMD AMF VP9のエンコードでは許容可能なクオリティは10Mbpsくらいだろう。

重要なことは、動画というのが一般ユーザーがごく普通に取り扱うものである、という前提のもと

  • 最新であるとしても、一般ユーザーが入手できる普及価格帯のコンピュータにおいて
  • 一般ユーザーが稼働可能な程度の時間で
  • 時間による空間量増大を追い越さない程度の大きさで
  • 視聴において明確に知覚できる劣化である

を満たさなければならないということだ。つまりこれは、(普及価格帯のコンピュータに載るものなら)何を使っても構わないが

  • 処理速度
  • データサイズ
  • 映像品質

が十分優れている必要がある、ということであり、ハードウェアの進化によって

  • 処理速度が向上する
  • 許容されるデータサイズが大きくなる

という変動を含めてのテクノロジーなのである。

だが、問題は現実にはFHDですらも十分に速くなく、十分に小さくない。 単純に言えば4kは4倍、8kは16倍の時間がかかり、16倍のサイズになる。

新しいコーデックはこれを小さくするためのものである、と考えて良い。 だが、現在ですら十分に速くないのが現実であり、小さくしようとすると処理時間は大幅に伸びてしまう。

そこでなんとかしようとするわけだが、そのためにデータサイズと映像品質を犠牲にする。 これは本末転倒だ。映像品質を下げて、それに伴い大きなデータサイズを必要とする、という状況があるならば、現状で十分に速いH.264(およそlibx264の意味)を使えば良いではないか、ということになる。

計算量から考えられる未来

AV1は8k時代を見据えた高圧縮なフォーマットである。

だが、libaomによるエンコードは、「映像品質が高く、サイズが小さい」を求める場合、1時間ほどのFHD動画に対して何ヶ月かの時間を要する。

libaomのパラメータを調整することで、これを「何日間か」まで短縮することができるが、この場合特に映像品質に対する影響が大きい。 そうすると10時間程度でエンコードできるlibvpx-vp9によるVP9動画と品質的には変わらないようなものになる。

もしも、libaomが十分に速いのであれば、こんなことは考える必要がない。 AV1のほうがサイズが小さく、それでいて映像品質が保たれたものになる、だけで話が終わるのだ。

libvpx-vp9のエンコード速度は、主にハードウェアの高速化によりそれが登場したときと比べれば10倍くらい高速化している。 だが、1時間の動画のエンコードに10時間かかるのは、明らかに「十分速い」状態ではない。

そして、libvpx-vp9が十分に速くなるまでには、まだまだ年月がかかるのは明らかである。 しかし、VP9は4k/8k動画を表現するのに十分に小さくできない、と考えられているからこそ、AV1が必要なわけである。

結果として、非現実的な計算時間を必要とし、それでいて満足できるほどには小さくならないエンコーダと、そんなエンコーダがなければアーカイブが困難なサイズになる映像データが残されるわけだ。 この問題が問題でなくなるほど、コンピュータが速くなる未来も、ストレージが大きくなる未来も、今のところ全く見えない。

なおかつ、8k動画というのはそんなに遠い未来の話でもない。 リソースを考えると、困るのは目に見えているのである。

というより、現在の4k/VP9(or H.265)ですら十分に困っている。 8k/AV1というのは、「もはやどうしようもない」という世界である。

これはVP9やAV1がダメだという話ではない。 H.265でも問題は変わらないからだ。 FHD/H.264はデータサイズは満足できるほど小さくならない、という状態を受け入れられるならば(もしくは映像品質に目立った劣化があっても構わないならば)それほど問題がない。 しかし、H.265/VP9/AV1はどうあがいても処理時間は長過ぎるし、なおかつ4k映像をアーカイブするにはH.264は映像品質に対するサイズが大きすぎる。

なお、スマートフォンのキャプチャなどだと、アスペクト比が特殊になるため、さらに遅くなり、ハードウェアエンコーダも使えなくなったりする。 もはや、「妥協はあるが問題はない」という条件が作れない。

必要な計算量を考える

問題が起きないことを確実視するのであれば、少なくとも動画自体のフレームレートより処理速度が上回っている必要がある。 つまり、60FPSの動画であれば、動画処理速度自体が60FPSあれば良い。

これは、リアルタイム録画が可能であるということも示している。 実際のところ、圧縮を極端に抑えれば現行のソフトウェアエンコーダーでも60FPSは可能な値だ。

だが、理想的なパラメーターにおいて(少なくとも1passで行う前提で)リアルタイムレコーディングが可能な速度、というのは現状とても考えられない。 それは、現状高性能なコンピュータでは、という意味ではなく、大幅に高速化したプロセッサですら満たすにはほど遠いからだ。この勢いで進化し続けても、現状のlibvpx-vp9のままVP9が現役であるうちに60FPSが出るようにはならないだろう。

よって、「計算量要求を満たすことはできないので、方法を変える」が結論になる。