# 機能設計書 46-ビデオプレビュー

## 概要

本ドキュメントは、StaxRipにおけるビデオプレビュー機能の設計を記述する。この機能は、処理前後のビデオをプレビュー表示し、フィルタ適用結果やエンコード前の確認を行う。

### 本機能の処理概要

ビデオプレビュー機能は、フレームサーバー（AviSynth+/VapourSynth）を介してスクリプト処理後の映像をリアルタイムに表示する機能である。

**業務上の目的・背景**：エンコード処理は時間がかかるため、事前にフィルタ適用結果を確認することで、設定ミスによる再エンコードを防止できる。プレビュー機能は、効率的なワークフローを実現するために不可欠である。

**機能の利用シーン**：
- フィルタ適用結果の確認
- クロップ範囲の確認
- 色調補正の確認
- フレーム位置の確認（カット操作）
- 解像度変更結果の確認

**主要な処理内容**：
1. VideoScriptからスクリプトファイルを生成
2. FrameServerFactory.Create()でフレームサーバーを初期化
3. VideoRendererでDirect2D描画
4. TrackBarでフレーム位置を移動
5. ShowInfoオプションでフレーム情報表示

**関連システム・外部連携**：
- AviSynth+フレームサーバー
- VapourSynth（vspipe）フレームサーバー
- Direct2D/DirectWrite（描画）
- VideoRenderer（レンダリング）

**権限による制御**：特になし（全ユーザーが利用可能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | PreviewForm | プレビュー画面 | フレーム表示、ナビゲーション、情報表示 |
| 5 | CropForm | クロップ画面 | クロップ範囲を含むプレビュー |
| 6 | VideoComparisonForm | 比較画面 | 複数映像の比較プレビュー |

## 機能種別

表示機能 / レンダリング / フレームサーバー連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| scriptPath | String | Yes | スクリプトファイルパス | .avs / .vpy |
| position | Integer | No | 表示フレーム位置 | 0 <= position < FrameCount |
| showInfo | Boolean | No | フレーム情報表示 | true/false |

### 入力データソース

- VideoScript（スクリプトファイル）
- プロジェクト設定（p.Script）
- ユーザー操作（TrackBar）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| renderedFrame | Direct2D Surface | 描画されたフレーム |
| frameInfo | String | フレーム情報テキスト |

### 出力先

- PreviewForm.pnVideoパネル（Direct2D描画）
- StatusStrip.laStatus（フレーム情報）

## 処理フロー

### 処理シーケンス

```
1. スクリプト同期
   └─ VideoScript.Synchronize()でスクリプトファイル出力
2. フレームサーバー初期化
   └─ FrameServerFactory.Create(scriptPath)
3. VideoRenderer初期化
   └─ New VideoRenderer(control, server)
4. フレーム取得
   └─ Server.GetFrame(position, pixelPtr, stride)
5. Direct2D描画
   └─ DeviceContext.DrawBitmap()
6. 情報表示（オプション）
   └─ DrawInfoText() でフレーム情報オーバーレイ
```

### フローチャート

```mermaid
flowchart TD
    A[プレビュー開始] --> B[スクリプト同期]
    B --> C[FrameServer作成]
    C --> D[VideoRenderer初期化]
    D --> E[初期フレーム描画]
    E --> F{ユーザー操作}
    F -->|フレーム移動| G[Position更新]
    G --> H[GetFrame]
    H --> I[Draw]
    I --> F
    F -->|終了| J[Dispose]
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-46-01 | フレーム境界 | Position は 0 から FrameCount-1 の範囲 | 常時 |
| BR-46-02 | スクリプトエラー | スクリプトエラー時はエラーメッセージ表示 | スクリプト読み込み時 |
| BR-46-03 | Direct2D使用 | レンダリングはDirect2Dで実行 | 常時 |

### 計算ロジック

タイムコード計算：
```
time = position / frameRate
timeString = Format(time, "HH:mm:ss.fff")
```

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

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| PREVIEW-001 | スクリプトエラー | AVS/VPYスクリプトの構文エラー | Server.Error表示 |
| PREVIEW-002 | フレーム取得失敗 | GetFrame戻り値が0以外 | エラーログ出力 |
| PREVIEW-003 | Direct2Dエラー | レンダリングリソース不足 | ReleaseGraphicsResources()で再初期化 |

### リトライ仕様

フレーム取得失敗時、次フレームで自動リトライ

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

該当なし（リアルタイム処理）

## パフォーマンス要件

- フレーム描画: 100ms以内（フィルタ複雑度による）
- フレーム移動応答: 200ms以内
- 96 DPIスケーリング対応

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

- スクリプトファイルのパス検証
- COM相互運用のリソース解放

## 備考

- VideoRendererはIDisposableを実装
- ThemeManager.CurrentThemeChangedでテーマ変更対応

---

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

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

### 推奨読解順序

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

VideoRendererクラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | VideoRenderer.vb | `Source/Video/VideoRenderer.vb` | クラス全体構造、プロパティ |

**読解のコツ**:
- **10-15行目**: CropLeft/Top/Right/Bottom、ShowInfo、Infoプロパティ
- **17-20行目**: Direct2D/DirectWriteファクトリ
- **26-41行目**: Position プロパティ（境界チェック含む）

#### Step 2: 描画処理を理解する

Draw()メソッドの詳細を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | VideoRenderer.vb | `Source/Video/VideoRenderer.vb` | Draw()メソッド（101-148行目） |

**主要処理フロー**:
- **101-103行目**: CreateGraphicsResources()でリソース初期化
- **108行目**: `Server.GetFrame(Position, pixelPtr, pitch)` でフレーム取得
- **112行目**: `DeviceContext.BeginDraw()` で描画開始
- **138-140行目**: DrawBitmap()でビットマップ描画
- **142行目**: DrawInfoText()で情報オーバーレイ
- **144行目**: `DeviceContext.EndDraw()` で描画終了

#### Step 3: 情報テキスト表示を理解する

DrawInfoText()メソッドを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | VideoRenderer.vb | `Source/Video/VideoRenderer.vb` | DrawInfoText()（150-194行目） |

**主要処理フロー**:
- **151-153行目**: ShowInfoフラグチェック
- **155-165行目**: IDWriteTextLayoutでテキストレイアウト作成
- **178行目**: FillRectangleで背景描画
- **189行目**: DrawTextでテキスト描画

#### Step 4: PreviewFormでの使用を理解する

PreviewFormでのVideoRenderer使用を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | PreviewForm.vb | `Source/Forms/PreviewForm.vb` | Open()、VideoRenderer初期化 |

**主要処理フロー**:
- スクリプト同期後にFrameServer作成
- VideoRenderer(pnVideo, FrameServer)で初期化
- TrackBarのValueChangedでPosition更新

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

```
PreviewForm / CropForm / VideoComparisonForm
    │
    ├─ VideoScript.Synchronize()
    │      └─ スクリプトファイル出力
    │
    ├─ FrameServerFactory.Create()
    │      └─ IFrameServer (AVS or VS)
    │
    └─ VideoRenderer
           ├─ Draw()
           │      ├─ GetFrame() ← IFrameServer
           │      ├─ CreateBitmap() → ID2D1Bitmap
           │      └─ DrawBitmap() → DeviceContext
           │
           ├─ DrawInfoText()
           │      ├─ IDWriteTextLayout
           │      └─ DrawText()
           │
           └─ Dispose()
                  └─ ReleaseGraphicsResources()
```

### データフロー図

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

VideoScript ───────▶ Synchronize() ────────▶ スクリプトファイル
    │                      │                         │
    │                      ▼                         │
    │               FrameServer ────────────▶ フレームデータ
    │                      │                         │
Position ──────────▶ GetFrame() ───────────▶ pixelPtr, pitch
    │                      │                         │
    │                      ▼                         │
    │               CreateBitmap() ────────▶ ID2D1Bitmap
    │                      │                         │
    │                      ▼                         │
    └──────────────▶ DrawBitmap() ─────────▶ 画面表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| VideoRenderer.vb | `Source/Video/VideoRenderer.vb` | ソース | Direct2D描画（全体） |
| PreviewForm.vb | `Source/Forms/PreviewForm.vb` | ソース | プレビューUI |
| CropForm.vb | `Source/Forms/CropForm.vb` | ソース | クロッププレビュー（285-287行目） |
| VideoComparisonForm.vb | `Source/Forms/VideoComparisonForm.vb` | ソース | 比較プレビュー |
| FrameServer.vb | `Source/Video/FrameServer.vb` | ソース | フレームサーバーインターフェース |
| VideoScript.vb | `Source/Video/VideoScript.vb` | ソース | スクリプト管理 |
