うっかり使った Blender VSE
(aras-p.info)- Aras は Blender に Video Sequence Editor(VSE) があることすら知らなかったが、Blender HQ 訪問後の約2か月間、パートタイムで Blender 4.1 向けの性能・品質改善に貢献した
- 最も目立つ変化は タイムラインの応答性 で、約3000個の strip が表示される Sprite Fright プロジェクトでは、スクロール・パン UI が約15fpsから60fps超へ改善した
- ffmpeg ベースの RGB↔YUV 変換、Audaspace のオーディオリサンプリング、画像変換・フィルタリング、VSE エフェクト処理に マルチスレッド・SIMD・数式の単純化 が適用された
- 3つの Blender Studio データセットでは、筆者の PC 基準で VSE 映画の最終レンダー時間が 約2倍 高速化し、Sprite Fright のレンダリングは約13分から7分へ短縮された
- 合計 37件の pull request がレビュー・マージされ、Blender 4.1 には現在これらの変更が入り、その後の VSE 作業は Blender 4.2 から続く予定
Blender VSE に貢献することになった経緯
- Aras は Unity の Unite 2023 参加のため Amsterdam に行き、空き時間に Blender HQ を訪問した
- そこで Francesco と Sergey に VSE への貢献意思を尋ねられ、その後 Blender の Video Sequence Editor を触り始めた
- 動画編集、タイムライン、シーケンサー、カラーグレーディング、ffmpeg、オーディオミキシングには詳しくなかったが、まずは議論の余地が少ない 性能最適化 から進めた
- 約2か月のパートタイム作業の末、Blender 4.1 に入る改善のまとまりができた
- Blender 4.1 はベータになっており、通常の daily builds から入手できる
タイムライン描画と UI 応答性
- VSE タイムラインは画面下部の領域で、Sprite Fright edit の全プロジェクトをズームアウトすると約 3000個の strip が一度に見える
- 以前はこのタイムラインでスクロールやパンをするだけでも、UI 更新は約 15fps 程度にとどまっていた
- 変更後は 60fps超 で動作する
- 関連 PR: #115311
- ボトルネックは、グラフィックス API の draw call を三角形2枚単位で送る構造にあり、Superluminal プロファイラでは処理時間の大半が「quad 1枚の描画開始」と「quad 1枚の描画終了」関数の中で使われていた
- この過程で オーディオ波形表示 の不具合も修正し、UI も調整した。波形表示はデフォルトで有効になる
- 関連 issue: #115274
スコープ表示の品質と速度改善
- VSE は画像ヒストグラム、waveform、vectorscope といった一般的な スコープ(scope) 表示オプションを提供している
- ヒストグラムはピクセル化された画像で非常に強い彩度で描かれていたが、今ではより滑らかな polygon、grid、低い彩度で表示される
- 関連 PR: #116798
- Waveform の parade オプションは飽和が早すぎる問題があったが、マルチスレッド化によって 15倍 高速化した
- 関連 PR: #115579
- Vectorscope の外周の色付き六角形はピクセル化が激しかったため、画像エディタ vectorscope の更新された design をコピーして適用した
- 関連 PR: #117738
- 「露出オーバー領域表示」に相当する zebra stripes オプションも 2〜3 倍高速化した
- 関連 PR: #115622
- すべてのスコープと画像エディタのスコープは、いずれ GPU compute shader で処理されるべきだという考えも添えている
ffmpeg RGB↔YUV 変換の最適化
- Blender は音声・動画の読み書きに主として ffmpeg ライブラリを使用している
- Blender 内部では ffmpeg のコマンドラインツールではなく、libavcodec のようなコードライブラリを使い、
libswscaleが動画フレームの RGB↔YUV 変換 を担っている libswscaleはマルチスレッド変換をサポートしているが、単にsws_getContext()とsws_scale()を使うだけでは完全にシングルスレッドで動作してしまう- マルチスレッドを使うには初期化時に
"threads"パラメータを設定する必要があるため、sws_alloc_context()、av_opt_set_int()、sws_init_context()を直接使う必要があった - また
sws_scale()は内部でマルチスレッド化されないため、sws_scale_frame()を使う必要があり、その過程でAVFrameの生成方法にも問題があることが分かった - 結果として、動画ファイル書き出し時の RGB→YUV 変換 が大幅に高速化した
- 関連 PR: #116008
- 動画ファイル読み込みでもマルチスレッド YUV→RGB 変換 を使い、vertical flip を同じ処理に統合した
- 関連 PR: #116309
オーディオリサンプリング
- VSE で動画をレンダリングすると、「動画または音声フレームを生成する」時間のほぼ半分が、Blender が使うオーディオライブラリ Audaspace 内で費やされていることが確認された
- ボトルネックはオーディオエンコードではなく、エンコード前の ミキシング であり、その大半は 48kHz の動画に 44.1kHz などのオーディオ strip が混ざる際のリサンプリングに使われていた
- Audaspace には2種類のリサンプリングモードがあった
- Blender 内部再生: サンプル間を線形補間する Linear resampler
- 動画レンダリング: Julius O Smith’s algorithm ベースのリサンプラ
- リサンプラ品質は、単一周波数が上昇していく合成音をリサンプリングし、その後 spectrogram を見る方法で比較した
- 目標は Audacity の「best」設定のように、余計な周波数ができるだけ少ない結果だった
- Audaspace の preview リサンプリングは計算は速いものの多くの余計な周波数を生み、rendering リサンプリングは spectrogram 品質が良かった
- 新しい medium リサンプリング品質 を Audaspace に追加し、筆者の見る限りほぼ同等の結果を出しつつ、計算は約3倍高速になった
- Blender はレンダリング時にこの medium 設定を使うようになった
- Windows Ryzen 5950X PC での Sprite Fright 2000フレームレンダリングは 92秒から73秒 に短縮
- 関連 PR: #116059
画像変換とフィルタリング
- VSE では、画像、動画、テキスト、scene など視覚結果を作る strip に対して、位置、回転、スケール、crop を適用できる
- これらの変換は、strip が生成した画像を新しい画像へ 変換 する形で行われ、以前から CPU でマルチスレッド処理されていた
- GPU ではなく CPU で処理されるのは、まだ GPU 実装がなく、GPU のない render farm でレンダリングしたいユースケースのために、現時点では CPU fallback が必要だからである
-
Half-pixel 誤差の修正
- 既存コードには複数の half-pixel 分のずれ があり、多くの場合は相殺されるか見えなかったが、特定の状況では表面化していた
- 小さな画像を16倍に拡大すると、Bilinear フィルタが画像を元ピクセルの半分だけずらし、背景色である magenta が入り込む現象があった
- 逆に画像を正確に2倍縮小すると、Bilinear フィルタがまったくフィルタリングしない問題も起きていた
- Bilinear や他のフィルタにあった「少しずれている」系の誤差が修正された
- 関連 PR: #116628
-
Bilinear の透明境界処理
- Blender 4.0 以前の VSE には
Nearest、Bilinear、Subsampled3x3の3つのフィルタオプションがあり、このうち Bilinear だけが結果画像の周囲に元 texel 半分幅の 透明度 を追加していた - この挙動はメディアを拡大した際に目立ったが、なぜこうした違いが生じたのか覚えている人はいなかった
- VSE の Bilinear フィルタコードから「透明度とブレンドする」挙動を削除した
- ただし回転のみを適用する場合は、従来の透明度処理のおかげで edge に一種のアンチエイリアシングが生じていたため、代わりに destination 画像の edge pixel に transparency anti-aliasing を適用した
- 関連 PR: #117717
- Blender 4.0 以前の VSE には
-
Cubic、Box、Auto フィルタ
- 一般的な VSE strip transform には cubic フィルタオプションがなく、特殊な Transform Effect strip にしか存在しなかった
- Blender でいう「Bicubic」は実際には Cubic B-Spline フィルタを意味し、Mitchell-Netravali filter の B=1、C=0 係数と同じである
- 筆者はこれを「ringing はないが blur が強い」選択肢だとまとめている
- VSE には2種類の cubic filtering オプションが入る
- 関連 PR: #117100、#117517
- Blender 3.5 の「Subsampled 3x3」フィルタは、実際には 3x3 サイズにハードコードされた box filter であり、3x3 でない比率に縮小すると破綻し始めていた
- このフィルタは固定 3x3 ではない調整可能な Box filter に変わった
- 関連 PR: #117584
- ユーザーが選ぶべきフィルタが増えたため、VSE strip のデフォルトとして Auto filter option が追加された
- 関連 PR: #117853
- スケール・回転がなければ
Nearest - 2倍超の拡大なら
Cubic Mitchell - 2倍超の縮小なら
Box - それ以外は
Bilinear
-
フィルタリング性能の改善
- 画像フィルタリング処理自体も高速化した
- 内部ループから virtual function を除去し、Bilinear フィルタリングに SIMD を一部適用: #115653
- Cubic フィルタリングの単純化と SIMD 追加: #117100
- Box フィルタの数式単純化: #117125
- 画面全体を覆う solid image の下にある項目をスキップする最適化が、scale があるときに動作しなかった問題を修正: #117786
- 筆者の PC では、3840x2160 プロジェクトで 1920x1080 画像1枚を2倍に拡大して Bilinear フィルタリングを使った場合、sequencer preview 全体の描画が 36.8ms から 15.9ms に短縮された
- アップサンプルフィルタ比較用のインタラクティブページも提供している: aras-p.info/img/misc/upsample_filter_comp_2024
VSE エフェクト最適化
- Blender Studio の実際の映画データセットでは effect はあまり使われていなかったが、コード上で目についた部分を中心に VSE effect も最適化した
- 変化の大半は マルチスレッド化 である
最終レンダー時間の変化
- Blender Studio から受け取った3つのデータセット基準で、筆者の PC では VSE 映画の最終レンダー時間が 約2倍 高速化した
- Sprite Fright edit のレンダリングはほぼ 13分から7分 に短縮された
- 筆者はさらなる高速化を期待しており、「2倍の速度向上をあと3回やればかなり良い」というような表現をしている
作業の進め方と次の段階
- ユーザーに見える変更以外にも、テスト追加、リファクタリング、整理作業のための pull request があり、合計 37件の pull request が完了・レビュー・マージされた
- 筆者は、この程度の作業量は「実際の職場」では難しかっただろうと評価している
- Unity の 2015〜2022 年であれば、同じ時間で上記作業の約30%程度、あるいはそれ以下しかできなかっただろうとしている
- 2010年ごろの「ancient」Unity なら可能だったかもしれないとも付け加えている
- 会社の規模、プロセス、期待値、コミュニケーション、政治といった要因が絡むと、報酬を受ける企業環境ではむしろ同じ作業が遅くなったり途中で中止されたりする可能性があると見ている
- Blender が、プロセスが人を助けるどころか意欲を削ぎ、速度を落とすような規模・複雑さ・ワークフローには向かわないでほしいと願っている
- Blender 4.1 はベータになったため、機能面では完成状態であり、VSE 関連の 4.1 変更は現在 release notes に反映されている
- Blender 4.2 の作業が始まり、その後も明確な計画なしに VSE を引き続き触っていく考えである
- 進捗は Weekly Updates フォーラムセクションで確認できる
1件のコメント
Hacker Newsの意見
「実際の職場」だったら、こういうことはできなかったと思う
キャリアでうまくいかなかった点があるとすれば、まったく独自の数学を自分で解き明かす無給プロジェクトでは2カ月で普段の2年分以上をこなせる一方で、お金をもらってやるプロジェクトでは成果がたいてい平均的になる、というふうに分かれてしまったこと
本当に必死に試したのに、その中間を見つけられず、去年、無料でやっていたことに対して報酬を得られる可能性が出てきたら、結局まったく手を付けられなくなった
その後、Marxの疎外論に触れて、ずっと筋が通って見えるようになった。彼は、仕事は健康な人々が主に行う活動だという観察から出発したが、それを他人のために働き、自分の労働の産物から疎外されることと混同してはいけないと考えた
https://en.m.wikipedia.org/wiki/Marx's_theory_of_alienation
ある場所には、1〜2週間は何をしてもよいバッファ期間を設ける良い仕組みがあり、それがこうした問題を和らげてくれる
情熱プロジェクトでは報酬を受け取らないので期待値が低く、何かをしなければならない義務もなく、事実上やりたいことを自由にできる。だから、興味のある新技術やツールを探るような、自分にとって面白く影響のある仕事を選ぶことになる
お金が絡んだ瞬間に、支払う側の期待が入り込み、新しく馴染みのない試みは失敗する可能性が高いので、より難しくなる
結局、お金がかかると、人々は潜在的により良い解決策があってもリスクが大きければ避け、予測可能な結果を好むのだと思う
本当に印象的で、元記事の筆者がただ道端からBlender HQに歩いて入っていったわけではないことも明らか。Unityで積んだ長年の経験が、この領域を理解するのにかなり役立ったのだろう
この変更 [1] が特に良かった。画像処理ステップを最適化する中で、テーブルベースの「最適化」を大量に取り除き、単に浮動小数点計算に置き換えたところ、元記事筆者のマシンでは約4倍速くなった。素晴らしい
[1]: https://projects.blender.org/blender/blender/pulls/115801/fi...
return c * c;が本当に sRGBガンマの良い近似なのかは気になるArasがいろいろなオープンソースのグラフィックスプロジェクトにふらっと入り込み、ものすごい高速化や改善を実現して、また別の任意のグラフィックスプロジェクトへ移って同じことを繰り返す流れが、ここ数年でいちばん気に入っている
https://github.com/aras-p/UnityGaussianSplatting
自分が使っている音楽プレーヤー MusicBee でも、こういうことをやってみたい
オープンソースだったら、の話だが。作者は今ではほとんど手を入れておらず、完全に無料だったしずっとそうなのに、なぜオープンソースではないのか理解できない
ちょっとした気になる問題、壊れていたり遅かったり変だったりする細かな部分があまりに多く、余暇にぜひ直してみたい
そして今さらFooBarのような別のものへ移るのは手間が多すぎる。HQPlayerも試したが、UI/UXがひどすぎて移行できなかった
プロジェクトを続けたくなくなったときにソースコードを公開するのは検討する選択肢の一つだが、これはプログラミングが楽しくてやっている趣味プロジェクトであり、決して専門的な形で運営するつもりはないと言っていた
本業で人の管理に十分な時間を使っているので、ここでまでそうしたくはなく、「バスにひかれたらどうするのか」といった懸念がある人は別のアプリを使うべきだ、とも述べていた
https://web.archive.org/web/20170721042120/https://getmusicb...
メンテナンスされていたならWineで動かすことも考えただろうが、今では音楽マネージャーという概念自体を諦め、ただmpvで聴くアルバムを再生している。そしていつもアルバム単位で聴く。プレイリストはお断りだ
2020年からすべての動画編集にBlender VSEを使ってきたので、改善されていく様子を見るのは本当にうれしい
安定性と機能構成を考えれば、すでにLinuxで最高の動画エディタだと思っていた。Blenderの既存のアニメーションツールをすべて使えることも利点だ
VSEには本当に多くの愛が必要です。ポッドキャストではすべてのツールをオープンソースで使いたかったのですが、Blenderでクロマキー入りのmp4シーケンスをレンダリングしたところ、1.5時間の動画に10時間かかりました
結局、DaVinci Resolveの無料版に移行しました
また、再エンコードが不要な場合でもDaVinci Resolveのようにスキップできず、全フレームを1つずつレンダリングします。この部分が改善されれば、Blenderの性能と効率に大きく役立つはずです
以前、タイムラインの異なる位置で複数のレンダリング作業を別プロセスとして開始するプラグイン [1] を試したことがあり、レンダリングを大幅に高速化できました
今はLinuxでもResolveに移行しました。Blackmagicのカメラを使っているので、そちらのほうが合っているためです
[1] https://github.com/AkBKukU/blenderSubprocessRender
今は新バージョンをFinal Cut Proで作業しています
Blenderという3Dプログラムのどの部分であれ、さらに速くするのはかなり難しそうです。すでに圧倒的に起動が速い3Dアプリケーションで、GUIの反応も最速です
Houdiniが2番手ではありますが、僅差の2番手ではありません
数年前に「blobby」ジェネレータのコードを触っていて、マルチスレッド化を追加した結果、はるかに遅くしてしまったことがあります。マルチスレッドのオーバーヘッドを超えれば速くはなりましたが、記憶では一般的なユースケースにはあまり入らず、諦めました。きっとミスもいくつかあったはずです
例えばテクスチャペイントは、ピクセルごとにポインタの間接参照を3回ほど行うような形で、私のPCでもかなりもたつきます
「Blenderに動画編集ツール一式があることをご存じでしたか? 私は知りませんでした :)」とのことですが、Blenderでアニメーションを作る人の大半は知っていると思います
レンダリングしたフレームを動画ファイルにする基本的な方法だからです
コンポジターを使って、事前にレンダリングしたフレームシーケンスを動画ファイルにすることもできます
ただし多くの人はResolveのような別のプログラムで動画編集することを好むでしょうし、VSEは「基本的なカットは必要だが、変形、タイトル、エフェクトは不要」という狭い領域にあるため、あまり使われていない印象です
誰かが変形やエフェクトの改善を続け、いつか3点編集も追加してくれるとよいのですが
ああ、Arasだったのですね。彼はすごいです。本当にすごいArasがフルネームだったと記憶しています
グラフィックスコーディングなどに優れていて、コーディング時の良い没入フローもあるように思います
文章は読みやすく面白いです。人が話しているのを聞いている感じがします。途中の「However!」のような文もそうです
最後に、一般的な会社で標準的な文化やプロセス上の期待に押しつぶされると生産性が30%になるという部分にも共感します。従業員を「自分の仕事」に縛りつけるコストには、実際にはものすごい生産性低下が含まれています
こうした事例を見続けることで、技術者たちが人や活動をよりうまく組織する方法を学び、その学びを信じて、高生産性/高い没入を実際の組織方法に組み込み始めてほしいです
記事が示唆しているように、そうすればテック業界で働くことがもっと楽しくなるかもしれません。技術で遊ぶのとほとんど同じくらい楽しくなる可能性もあります
https://projects.blender.org/blender/blender/pulls/116089について付け加えると、
inlineは何よりまず単一定義規則に影響します簡単に言えば、ヘッダーに関数を定義して複数の
.ccファイルから呼び出すと、inlineとマークしない限りリンカーエラーになります実際のインライン最適化への効果は、「なし」から「コンパイラがリンク方法のために重み付けを変える場合がある」、「実際にヒントとして受け取る」までさまざまで、リンク時最適化でも同様の考慮があります
コンパイラにより強いインライン化のシグナルを与えたいなら、特に定義されたファイル内でだけ使う関数であれば、匿名名前空間内に定義するほうがよいです
もともとその関数に
inlineを付けた意図は、実際のインライン化を得ようとする試みだったのかもしれません。測定可能な利得は明確ではありませんが、不可能でもありません