# 機能設計書 35-AviSynth+連携

## 概要

本ドキュメントは、StaxRipアプリケーションにおけるAviSynth+フレームサーバーとの連携機能の設計を記述する。

### 本機能の処理概要

AviSynth+連携機能は、AviSynth+スクリプト（.avs）を使用してソース映像のデコード、フィルタリング、フレーム処理を行う機能である。StaxRipはAviSynth+スクリプトを自動生成し、フィルタプロファイルの管理、プラグインの自動ロード、フレームサーバーとしてのフレーム供給を行う。

**業務上の目的・背景**：AviSynth+は長年にわたり映像処理の標準的なフレームサーバーとして使用されており、豊富なフィルタプラグインエコシステムを持つ。既存のAviSynthスクリプト資産を活用しつつ、StaxRipのGUIから簡単にフィルタ設定ができる環境を提供する。

**機能の利用シーン**：
- ソース映像のデコード（LWLibavVideoSource、FFVideoSource等）
- クロップ、リサイズ等の基本フィルタ処理
- QTGMCによるデインターレース
- DFTTestによるノイズ除去
- カスタムAviSynthスクリプトの適用

**主要な処理内容**：
1. ScriptEngine.AviSynthの設定とスクリプト生成
2. フィルタプロファイル（AviSynthProfiles）の管理
3. プラグイン自動ロードコード（LoadPlugin/Import）の生成
4. Synchronize()によるスクリプト同期と検証
5. フレームサーバーファクトリーを通じたフレーム取得

**関連システム・外部連携**：AviSynth+ランタイム（avisynth.dll）、各種プラグイン（LSMASH、ffms2、QTGMC等）。

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | MainForm | 主画面 | lgbFiltersでフィルタ一覧表示、フィルタ追加・編集 |
| 3 | CropForm | 参照画面 | クロップ値の設定（AviSynthスクリプトに反映） |
| 8 | PreviewForm | 参照画面 | AviSynthスクリプトのプレビュー表示 |
| 22 | CodeEditor | 参照画面 | スクリプトの直接編集 |

## 機能種別

フレームサーバー連携 / スクリプト生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| p.Script.Engine | ScriptEngine | Yes | AviSynthを指定 | ScriptEngine.AviSynth |
| p.Script.Filters | List(Of VideoFilter) | Yes | フィルタのリスト | Source フィルタが必須 |
| s.AviSynthProfiles | List(Of FilterCategory) | No | フィルタプロファイル | - |
| s.LoadAviSynthPlugins | Boolean | No | プラグイン自動ロードの有効化 | デフォルト: True |

### 入力データソース

- p.Script: プロジェクトのビデオスクリプト設定
- s.AviSynthProfiles: アプリケーション設定のフィルタプロファイル
- AviSynthFilterProfileDefaults.txt: 埋め込みリソースのデフォルトプロファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| .avs ファイル | テキストファイル | 生成されたAviSynthスクリプト |
| ServerInfo | オブジェクト | フレームサーバーから取得した映像情報 |

### 出力先

- p.TempDir/{base}.avs: 生成されたスクリプトファイル

## 処理フロー

### 処理シーケンス

```
1. スクリプトエンジン確認
   └─ p.Script.Engine = ScriptEngine.AviSynth

2. フィルタリストからスクリプト生成
   └─ GetScript(): Filtersからスクリプト文字列を構築

3. マクロ展開
   └─ Macro.Expand(): %crop_left%等のマクロを実際の値に変換

4. プラグインロードコード追加
   └─ ModifyAVSScript(): LoadPlugin/Import行を自動追加

5. スクリプトファイル書き出し
   └─ WriteFile(): エンコーディングはEncodingOfProcess

6. フレームサーバー起動
   └─ FrameServerFactory.Create(): フレーム情報取得

7. 検証と情報取得
   └─ Synchronize(): エラーチェックとServerInfo更新
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{Engine = AviSynth?}
    B -->|No| C[VapourSynth処理へ]
    B -->|Yes| D[Filters取得]
    D --> E[GetScript実行]
    E --> F[各フィルタのScriptを連結]
    F --> G[Macro.Expand]
    G --> H[ModifyAVSScript]
    H --> I[プラグインロードコード生成]
    I --> J[AddAutoloadDir処理]
    J --> K[スクリプト書き出し]
    K --> L[FrameServerFactory.Create]
    L --> M{エラー?}
    M -->|Yes| N[エラー情報設定]
    M -->|No| O[ServerInfo取得]
    N --> P[終了]
    O --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-35-01 | Sourceフィルタ必須 | 最初のフィルタはSourceカテゴリであること | スクリプト検証時 |
| BR-35-02 | プラグイン自動ロード | s.LoadAviSynthPlugins=Trueの場合、使用フィルタに応じてLoadPlugin追加 | スクリプト生成時 |
| BR-35-03 | AutoLoadDir | ポータブルモード時は追加のプラグインフォルダを指定 | FrameServerHelp.IsPortable=True |
| BR-35-04 | ファイルエンコーディング | AviSynthスクリプトはEncodingOfProcessで保存 | WriteFile時 |
| BR-35-05 | 関数名検出 | スクリプト内の関数呼び出しを検出してプラグインをロード | ModifyAVSScript時 |

### 計算ロジック

特になし

## データベース操作仕様

### 操作別データベース影響一覧

データベース操作なし（ファイルベースの処理）

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | スクリプトエラー | AviSynthスクリプトの構文エラー | GetError()で取得、UIに表示 |
| - | プラグイン不在 | 必要なプラグインがインストールされていない | LoadPlugin行をコメントアウト |
| - | AbortException | Package.AviSynth.VerifyOK = False | 処理中断 |

### リトライ仕様

リトライ処理なし

## トランザクション仕様

ファイル操作のためトランザクション管理なし

## パフォーマンス要件

- スクリプト同期は必要に応じて実行（LastCode比較による最適化）
- フレームサーバーはUsing文で適切に破棄

## セキュリティ考慮事項

- スクリプト内のパスは適切にエスケープ
- プラグインパスはPackage管理システムで検証済みのもののみ使用

## 備考

- AviSynth+は32bit/64bitの両方に対応
- ポータブルモードでは追加のプラグインフォルダを設定可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

VideoScriptクラスとVideoFilterクラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | VideoScript.vb | `Source/Video/VideoScript.vb` | VideoScriptクラス定義（12-784行目） |
| 1-2 | VideoScript.vb | `Source/Video/VideoScript.vb` | VideoFilterクラス定義（841-887行目） |
| 1-3 | VideoScript.vb | `Source/Video/VideoScript.vb` | ScriptEngine列挙体（1230-1233行目） |

**読解のコツ**: VideoScriptは複数のVideoFilterを持ち、各フィルタがCategory、Path、Script、Activeプロパティを持つ。

#### Step 2: スクリプト生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | VideoScript.vb | `Source/Video/VideoScript.vb` | GetScript()メソッド（51-75行目） |
| 2-2 | VideoScript.vb | `Source/Video/VideoScript.vb` | GetFullScript()メソッド（77-79行目） |

**主要処理フロー**:
- **58-59行目**: p.CodeAtTopの追加
- **62-67行目**: アクティブなフィルタのScript連結
- **70-72行目**: p.CodeAtBottomの追加

#### Step 3: プラグインロードコード生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | VideoScript.vb | `Source/Video/VideoScript.vb` | ModifyAVSScript()メソッド（671-710行目） |
| 3-2 | VideoScript.vb | `Source/Video/VideoScript.vb` | GetAvsLoadCode()メソッド（468-572行目） |
| 3-3 | VideoScript.vb | `Source/Video/VideoScript.vb` | FindFunctionsAVS()メソッド（624-652行目） |

**主要処理フロー**:
- **671行目**: ModifyAVSScript開始
- **675-676行目**: GetAvsLoadCodeでプラグインロードコード取得
- **694-704行目**: AddAutoloadDir処理（ポータブルモード時）
- **624-652行目**: FindFunctionsAVSで関数名を検出

#### Step 4: スクリプト同期を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | VideoScript.vb | `Source/Video/VideoScript.vb` | Synchronize()メソッド（194-319行目） |

**主要処理フロー**:
- **199行目**: Path空チェック
- **204行目**: GetScript()でスクリプト取得
- **289-295行目**: ファイル書き出し（AviSynth用のエンコーディング）
- **305-313行目**: FrameServerFactory.Createでフレームサーバー起動

#### Step 5: フィルタプロファイルを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | VideoScript.vb | `Source/Video/VideoScript.vb` | FilterCategory.GetAviSynthDefaults()（922-928行目） |
| 5-2 | VideoScript.vb | `Source/Video/VideoScript.vb` | GetDefaults()でスクリプトテンプレート（742-764行目） |

**主要処理フロー**:
- **922-928行目**: 埋め込みリソースからデフォルトプロファイル読み込み
- **745-752行目**: AviSynthのデフォルトスクリプト（Source, Crop, QTGMC, DFTTest, Resize）

### プログラム呼び出し階層図

```
MainForm
    │
    ├─ FiltersListView
    │      ├─ Load(): Filtersをリストに表示
    │      ├─ AddClick(): フィルタ追加
    │      └─ ReplaceClick(): フィルタ置換
    │
    └─ p.Script (VideoScript)
           │
           ├─ GetScript()
           │      └─ 各フィルタのScript連結
           │
           ├─ GetFullScript()
           │      └─ Macro.Expand() + ModifyScript()
           │
           ├─ ModifyAVSScript()
           │      ├─ GetAvsLoadCode()
           │      │      └─ FindFunctionsAVS()
           │      └─ AddAutoloadDir追加
           │
           └─ Synchronize()
                  ├─ WriteFile()
                  └─ FrameServerFactory.Create()
                         └─ ServerInfo取得
```

### データフロー図

```
[入力]                          [処理]                              [出力]

p.Script.Filters ───────────────▶ GetScript() ──────────────────▶ スクリプト文字列
      │                               │
      ▼                               │
VideoFilter.Script                    │
      │                               ▼
      │                         Macro.Expand()
      │                               │
      │                               ▼
      │                      ModifyAVSScript()
      │                               │
      │                    ┌──────────┴──────────┐
      │                    ▼                     ▼
      │            GetAvsLoadCode()    AddAutoloadDir
      │                    │                     │
      │                    ▼                     ▼
      │            LoadPlugin行追加      ポータブルDir追加
      │                    │                     │
      │                    └──────────┬──────────┘
      │                               │
      │                               ▼
      └────────────────────────▶ WriteFile()
                                      │
                                      ▼
                                .avs ファイル
                                      │
                                      ▼
                          FrameServerFactory.Create()
                                      │
                                      ▼
                                ServerInfo
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| VideoScript.vb | `Source/Video/VideoScript.vb` | ソース | VideoScript、VideoFilter、FilterCategoryクラスの定義 |
| FiltersListView.vb | `Source/Controls/FiltersListView.vb` | ソース | フィルタ一覧UIコントロール |
| FrameServerHelp.vb | `Source/Video/FrameServerHelp.vb` | ソース | フレームサーバーヘルパー |
| Package.vb | `Source/General/Package.vb` | ソース | AviSynthパッケージ定義 |
| Macro.vb | `Source/General/Macro.vb` | ソース | マクロ展開処理 |
| AviSynthFilterProfileDefaults.txt | `埋め込みリソース` | リソース | デフォルトフィルタプロファイル |
