RIFEで動画のリアルタイムフレーム補間 (MPC-BE編)
少し前までは動画のリアルタイムフレーム補間といえばAMD Radeonグラフィックスカードで利用できたFluidMotionVideoが手軽でしたが、利用できるのはVegaアーキテクチャのGPU・APUまでで、それ以降ではサポートが打ち切られてしまいました。
一応自分のPCはRyzen 7 5700Gを積んでいるためまだ利用はできるのですが、ゲーム用途では性能がそろそろボトルネックになりつつあるため、なんとかGPU側で出来ないかChatGPTとやりとりしながら試してみることにしました。
環境
OS: Windows 11 Pro
Python: 3.12.9
CUDA: 12.8
MediaPlayer: MPC-BE x64 1.8.3
GPU: GeForce RTX 4070 SUPER
必要パッケージのインストールと設定
今回利用するのは以下です。
Pythonのバージョンは多少前後してもたぶん大丈夫。たぶん。
PythonとMPC-BEは事前にインストールされているものとします。
最近のMPC-BEの場合はVapourSynthFilterのインストールをしなくてもデフォルトで利用できるかも。
- CUDA Toolkit
- VapourSynth
- VapourSynthFilter
- VapourSynth-RIFE(vs-rife)
CUDA Toolkitのインストール
既にNvidia Appsとかドライバとかが入ってる場合はインストールオプションでカスタムを選択してCUDAだけ入れるのをオススメします。
インストールが完了したらコマンドプロンプトを起動し、以下のコマンドでバージョンが表示されればOKです。
nvcc --version
nvidia-smi
VapourSynth のインストール
Relesesからインストーラーを落としてきてインストールするだけ。
CUDA版 pytorchのインストール
vsrifeはpytorchを利用するのですが、vsrifeの依存関係に任せるとCPU用のtorchが入ってしまい、cudaを利用するコードで"rife: CUDA is not available"
といったエラーが出るので、予めCUDA版をインストールします。
pip uninstall torch torchvision torchaudio
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126
VapourSynth-RIFE(vs-rife) のインストール
pip install -U vsrife
MPC-BEで外部フィルタを追加
MPC-BEのオプションを開き、外部フィルタ>フィルターの追加から、VapourSynth Filterを選択して追加します。
VapourSynth Filterがない場合は次の手順でVapourSynthFilter のインストールを行ってみてください。
VapourSynth Filter のインストール
以下からzipをダウンロードしてきて、解凍したファオルダのinstall.cmdを実行すればOKのはず
フィルターの作成
ここらへんを参考にします。
ドキュメントいわく、Filterが実行された場合、VpsFilterSourceがスクリプト内に公開される(globalで利用できる)とのことなので、これを起点にいじっていきます。
基本的にこのVpsFilterSourceに現在再生している動画が入ってきます。
動作確認
一旦以下のようにvpyファイルとしてコードを保存し、
(中身はPython)
clip = VpsFilterSource
clip = clip.std.eExpr("x 1.1 *")
clip.set_output()
先ほど設定した外部フィルタのVapourSynth Filterをクリックしスクリプトのパスを指定します。
動画を再生してみて、色が変わっていればフィルタが適用されている証拠です。
エラーがあった場合は動画に表示されます。
RIFEの適用
使用するモデルに関してはpython -m vsrife
で全部ダウンロードできるんですが、かなり容量があるので必要なものだけ自動でダウンロードした方が良いです。
import vapoursynth as vs
from vsrife import rife
core = vs.core
core.num_threads = 8
clip = VpsFilterSource
# rifeがRGBしか受け付けないため一度変換
clip = core.resize.Bicubic(clip, format=vs.RGBH)
clip = rife(
clip,
model="4.25.lite",
auto_download=True,
factor_num=2, # フレームレートを2倍に(2/1)
factor_den=1,
)
clip = vs.core.resize.Bicubic(clip, format=vs.YUV420P8, matrix_s="709")
# 出力
clip.set_output()
結果
重い!! とにかく重いです。
検証に使用した動画は一般的な1080/24pの動画(FHD/24fps)なんですが、フレームレートを2倍にするだけでも4070 SUPERでGPUの平均使用率が85%ぐらいまで跳ね上がります。
補間品質に関しては流石で、動きの早いシーンでもFluidMotionと異なりフレームの破綻があまり目立ちません。
動きの遅いパンやチルトするシーンなんかはFluidMotionの方が滑らかですが、全体的にはやはりrifeの方が見ていて違和感がないです。
ただやはりMPC-BEでは動作が色々不安定なので、素直に他のメディアプレイヤーで動かしたほうが楽な気がします・・・。
(MPCのバージョンやモデルを色々変えてみたりregister_on_destroy
でキャッシュの削除やGCを試したりと色々やってみたんですが、シークを移動したり終了させようとするとハングアップするのが直らない・・・)
rifeの処理を入れない場合は特に問題ないため、今のところvsrife側のバグなような気がしているんですが・・・。
上手くいった方がいましたらぜひ教えて下さい。
Discussion