Releases: routersys/YMM4-ProxyForge
v1.0.2
v1.0.2
YukkuriMovieMaker4 向けの動画プロキシ生成・管理プラグイン ProxyForge のパッチリリースです。
バグ修正
「プロキシを使用する」無効時のプラグイン干渉によるクラッシュの修正
「プロキシを使用する」設定をオフにした状態でも、本体のプラグイン機構が背後で稼働し続け、予期せぬタイミングで YMM4 のフル動画読み込みを傍受してしまう構造的な不具合を解消しました。
不適切だった挙動と修正内容:
旧バージョンでは、プロキシ機能が無効であるにもかかわらず、動画読み込み時に処理を横取りし、エラー発生時に ProxyForge 内蔵の軽量確認用デコーダー(プロキシプレビュー用途のもの)で重いオリジナル動画を強制的に開こうとする「無意味なフォールバック機構」が残存していました。これが Access Violation 等を引き起こし、YMM4プロセスそのものをクラッシュさせる原因となっていました。
本バージョンでは、プロキシが無効な場合および内部データベース等に異常が生じた場合は、ProxyForge が一切介入せず、直ちに処理を放棄(null 返却)するよう修正しました。これにより、無効時には確実に YMM4 標準の安全な動画デコーダーへと処理を引き継ぐようになり、意図しない巻き込みクラッシュが発生しなくなりました。
v1.0.1
v1.0.1
YukkuriMovieMaker4 向けの動画プロキシ生成・管理プラグイン ProxyForge のパッチリリースです。
変更点
キャッシュDBファイル名の変更
永続化ビデオキャッシュのDBファイル名を zerodiskproxy.vdb から proxyforge.vdb に変更しました。
既存キャッシュの自動マイグレーション: 起動時に旧ファイル(zerodiskproxy.vdb)が存在し、かつ新ファイル(proxyforge.vdb)が存在しない場合、自動的に移行処理を行います。移行はコピー → File.Move によるアトミック置換の手順で行われるため、途中で失敗してもデータが失われません。バックアップファイル(.bak)および残存する一時ファイル(.tmp)も合わせて移行・削除されます。移行に失敗した場合は処理をスキップし、既存のキャッシュデータはそのまま保持されます。
v1.0.0
v1.0.0 - ProxyForge for YMM4 初回リリース
YukkuriMovieMaker4 向けの動画プロキシ生成・管理プラグイン ProxyForge の初回リリースです。編集中の重い動画ファイルを低解像度のプロキシに差し替えてプレビューを軽くし、エクスポート時には自動的に元映像へ切り替える映像処理プラグインです。
新機能
1. 2種類のプロキシエンコーダー
用途・環境に応じて2つのエンコードバックエンドを使い分けます。
- WinRT トランスコーダー (
MfProxyEncoder): Windows のMediaTranscoderAPI を使用。ハードウェアアクセラレーションを試み、失敗時はソフトウェアへ自動フォールバックします。エンコード済みデータは指定された一時ディレクトリ(fallbackDirectory)にディスク書き出しします。 - ストリーミング MF エンコーダー (
StreamingMfEncoder):IMFSourceReader/IMFSinkWriterを直接操作する低レベル実装。出力先はIStream(COM メモリストリーム)であり、エンコード完了後にメモリへ展開します。メモリ予算が不足する場合はディスクへフォールバックします(EnableDiskFallbackが有効な場合)。
どちらのエンコーダーも H.264 / MP4 形式で出力し、ビットレートは 解像度 × FPS × 0.07 × BitrateFactor の式で自動算出します(最低 100,000 bps)。出力解像度は幅・高さともに 16 ピクセル境界にアライメントします(AlignTo16)。
2. ライトウェイト動画ソース
LightweightVideoFileSource は IMFSourceReader を用いてフレーム単位でデコードを行う軽量な映像ソース実装です。
- NV12 フォーマットを優先し、非対応環境では RGB32 へフォールバックします。
- NV12 の YUV → BGRA 変換はピクセルごとに BT.601 係数で手動計算し、
ID2D1Bitmapへ直接書き込みます。 - プロキシ生成が完了するまでの初期表示に利用され、完了後は
ProxyForgeVideoSource内でプロキシ映像ソースへホットスワップされます。
3. ノンブロッキングなプロキシへの切り替え
ProxyForgeVideoSource は Direct2D の AffineTransform2D エフェクトを介して映像を出力するラッパーです。
- プロキシ生成完了後、バックグラウンドスレッドで新ソースを取得し(
FetchUpgradeAsync)、次フレームの更新タイミングでアトミックにSetInputを差し替えます。再試行は 0.5 秒のクールダウンで抑制されます。 - スケールが 1.0 未満のプロキシ映像は
ProxyForgeVideoSourceWithScaleが逆スケール(1 / proxyScale)のMatrix3x2を適用して元解像度に復元します。
4. エクスポート検出による自動退避
ExportDetector は EnumWindows でプロセス内のウィンドウタイトルを走査し、YMM4 のエクスポート進捗ウィンドウ・動画書き出しウィンドウを検出します。
- 検出結果は 2,000 ms キャッシュされ(
CacheIntervalMs)、パックされた 64 bit 値(タイムスタンプ + 状態フラグ)をInterlocked操作で管理します。 - エクスポート中はプロキシ生成を開始せず、元ファイルをそのまま使用します。
5. メモリ予算管理
MemoryBudget は物理メモリ残量と割り当て済みバイト数を追跡し、プロキシをメモリに保持できるかどうかを判定します。
GlobalMemoryStatusExによる物理メモリ残量の取得結果は 100 ms キャッシュします(タイムスタンプ + KB 値を 64 bit にパックしてInterlockedで管理)。- 設定された
MemoryReserveMbをメモリ残量から差し引いた値とMaxCacheMemoryMbの小さい方が上限となります。 FallbackStreamはメモリ書き込み中に予算超過を検出すると、内容をそのままディスク上の一時ファイルへ転送し、MemoryStreamをシームレスにFileStreamへ切り替えます。
6. 永続化ビデオキャッシュ
VideoCacheDatabase は生成済みプロキシのメタデータを独自バイナリ形式(.vdb)で永続化します。
- ファイルはマジックナンバー
0x0042_4456_5F50_445A+ フォーマットバージョン + レコード数 + ヘッダー CRC32 のヘッダーで始まります。 - 各レコード(
VideoCacheRecord、固定長 656 バイト)はLayoutKind.Sequential, Pack = 1の構造体で、ファイルパスの SHA256 ハッシュ(32 バイト)・パス文字列(最大 260 文字)・スケール・解像度・ファイルサイズ・CRC32 を保持します。 - プライマリ DB の読み込みに失敗した場合、
.bakファイルからの自動復元を試みます。それも失敗した場合はキャッシュディレクトリ内の.mp4ファイルを列挙してレコードを再構築します。 - DB への書き込みは
.tmpファイルへ出力後にFile.Moveでアトミックに置換します。複数プロセスからの競合を防ぐため名前付きグローバルミューテックス(パスの SHA256 から生成)で保護されています。
7. インメモリ+ディスクのハイブリッドキャッシュ
ProxyCacheManager はインメモリキャッシュと永続化ビデオキャッシュを統合して管理します。
ConcurrentDictionaryによるインメモリキャッシュを一次キャッシュとして使用し、ヒットしない場合はVideoCacheDatabaseを参照します(EnableVideoCacheが有効な場合)。- プロキシ生成完了後、一時ファイルのパスが確認できる場合は
File.Moveでキャッシュディレクトリへ移動し、不要なコピーを回避します。 ConcurrentDictionary<CacheKey, CancellationTokenSource>で同一ファイル・スケールの二重生成を防ぎます。
8. プロキシ生成進捗ポップアップ
アクティブなプロキシ生成タスクを ObservableCollection<ProxyGenerationItem> で追跡し、画面右下に GenerationPopupView(ツールウィンドウ)として表示します。
- 進捗値はエンコードスレッドが
Interlockedでdoubleの bit 表現を書き込み(SetPendingProgress)、UI スレッドのDispatcher.BeginInvokeで読み出します。 - ウィンドウのクローズはキャンセルしてウィンドウを非表示にするだけで、アクティブタスクがある間は再表示されます(
ForceCloseが呼ばれた場合のみ実際に閉じます)。
9. 設定画面とキャッシュ管理 UI
ProxyForgeSettingsView は以下の設定グループを提供します。
- 基本設定: プロキシ使用の有効化・解像度スケール(10〜100%、デフォルト 50%)・プロキシ生成対象の最小ファイルサイズ(デフォルト 100 MB)。
- 品質設定: ビットレート係数(1〜200%、デフォルト 50%)・GOP サイズ(1〜300、デフォルト 30)。
- メモリ設定: メモリ予約量・最大キャッシュメモリ量・ディスクフォールバックの有効化。
- 自動化設定: 自動生成・終了時キャッシュ削除。
- 詳細設定: ハードウェアアクセラレーションの有効化(
UseAdvancedSettingが true のときのみ表示)。 - キャッシュ管理: インメモリキャッシュおよび永続化ビデオキャッシュのエントリ一覧表示・個別削除・一括削除。
10. テーマ対応
WindowThemeService が DWM API (DwmSetWindowAttribute) を通じてポップアップウィンドウのタイトルバーとボーダーの色をシステムカラーに追従させます。Windows 11(ビルド 22000)以降でのみ動作します。
技術的な実装詳細
- ゼロアロケーション設計:
ArrayPool<byte>.Sharedを薄くラップしたBufferPoolおよびChunkAllocator(ConcurrentBag<byte[]>ベースの独自プール)により、フレーム処理・ファイル I/O での GC ヒープ割り当てを抑制します。 - COM リソース管理:
ResourceRegistryが COM ポインタおよびIDisposableを一元追跡し、Marshal.Release/Disposeを保証します。MF セッションはMfSession(参照カウント方式)がMFStartup/MFShutdownのライフタイムを管理します。 - パス照合の高速化:
VideoCacheRecordはパス文字列の SHA256 ハッシュ(32 バイト)を先に比較してから実文字列照合を行い(大文字小文字無視)、不一致時の文字列比較コストを削減します。 - インターネット非通信: 本プラグインは外部への通信を一切行いません。