# 機能設計書 18-チャンクエンコード

## 概要

本ドキュメントは、StaxRipのチャンクエンコード機能の設計書である。ビデオを複数のチャンク（断片）に分割して並列エンコードを行い、エンコード時間を短縮する機能を定義する。

### 本機能の処理概要

入力ビデオを複数のチャンクに分割し、各チャンクを並列または順次エンコードすることで、全体のエンコード時間を短縮する機能である。特にマルチコアCPUを活用したソフトウェアエンコーダー（x265、AV1等）で効果を発揮する。

**業務上の目的・背景**：
ソフトウェアエンコードは高品質だが時間がかかる。チャンクエンコードにより、複数のエンコードプロセスを並列実行することで、マルチコアCPUの性能を最大限に活用し、エンコード時間を大幅に短縮できる。

**機能の利用シーン**：
- 長時間動画のエンコード時間短縮
- マルチコアCPUの効率的活用
- バッチ処理での大量ファイル変換
- 時間制約のあるエンコード作業

**主要な処理内容**：
1. 総フレーム数の取得
2. チャンク数に基づいた分割計算
3. 各チャンクの開始/終了フレーム決定
4. 各チャンクのエンコード実行
5. チャンクの結合（Muxer処理時）

**関連システム・外部連携**：
- x265Enc: チャンクエンコード対応
- AOMEnc: チャンクエンコード対応
- SvtAv1Enc: チャンクエンコード対応
- mkvmerge: チャンク結合

**権限による制御**：
本機能に特別な権限制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | MainForm | 主画面 | エンコーダー設定でチャンク数を指定 |
| 18 | CommandLineForm | API連携 | Chunksパラメータの設定 |

## 機能種別

データ変換処理 / 並列処理 / 高速化機能

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Chunks | Integer | Yes | 分割するチャンク数 | 1以上128以下 |
| Seek | Integer | No | 開始フレーム | 0以上 |
| Frames | Integer | No | エンコードするフレーム数 | 0より大きい（0は全フレーム） |

### 入力データソース

- AviSynth/VapourSynthスクリプト
- フレーム数情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| チャンクファイル | File | 各チャンクのエンコードファイル（_chunk1, _chunk2, ...） |
| 結合ファイル | File | 全チャンクを結合した最終出力 |

### 出力先

- 一時ディレクトリ（p.TempDir）に各チャンクを出力
- Muxer処理時に自動結合

## 処理フロー

### 処理シーケンス

```
1. チャンク数の確認
   └─ CanChunkEncode()でチャンクエンコード可否判定
2. 総フレーム数の取得
   └─ p.Script.GetFrameCount()
3. チャンク範囲の計算
   └─ 開始フレーム、終了フレーム、チャンク長の計算
4. 各チャンクのActionリスト生成
   └─ GetChunkEncodeActions()
5. 各チャンクのエンコード実行
   └─ 順次またはジョブキュー経由で実行
6. チャンクの結合
   └─ Muxer処理時にAppendファイルとして結合
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{チャンクエンコード可能?}
    B -->|No| C[通常エンコード]
    B -->|Yes| D[総フレーム数取得]
    D --> E[チャンク範囲計算]
    E --> F[Actionリスト生成]
    F --> G[チャンク1エンコード]
    G --> H[チャンク2エンコード]
    H --> I[...]
    I --> J[チャンクNエンコード]
    J --> K[Muxer処理時に結合]
    C --> L[完了]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-18-01 | Dolby Vision制限 | Dolby Vision使用時はチャンクエンコード不可 | IsDolbyVisionSet = True |
| BR-18-02 | 最小チャンク数 | Chunks > 1でチャンクエンコード有効 | Chunks設定時 |
| BR-18-03 | 均等分割 | 総フレーム数をチャンク数で均等分割 | 常時 |
| BR-18-04 | 端数処理 | 最後のチャンクに端数フレームを含める | 常時 |

### 計算ロジック

```vb
' チャンク範囲の計算
chunkLength = length \ chunkCount
chunkStart = startFrame + (chunk * chunkLength)
chunkEnd = If(chunk <> chunkCount - 1, chunkStart + (chunkLength - 1), endFrame)
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR-18-01 | 設定エラー | Dolby Vision使用時にチャンクエンコード | エラーメッセージ表示、チャンク無効化 |
| ERR-18-02 | エンコードエラー | チャンクエンコード中にエラー | エラーログ表示 |

### リトライ仕様

リトライ機能なし。

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

ファイル操作のみ。一部チャンクが失敗した場合、不完全なファイルが残る可能性がある。

## パフォーマンス要件

- チャンク数に応じてCPU使用率が増加
- 理想的にはチャンク数 = CPUコア数/エンコーダースレッド数

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

- 一時ファイルが大量に生成されるためディスク容量に注意

## 備考

- チャンクの結合はMuxer処理時に自動的に行われる
- 2パスエンコードの場合、各チャンクで2パスが実行される

---

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | x265Enc.vb | `Source/Encoding/x265Enc.vb` | Chunksパラメータ、チャンク関連プロパティ |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | x265Enc.vb | `Source/Encoding/x265Enc.vb` | CanChunkEncode()メソッド（322-324行目） |
| 2-2 | x265Enc.vb | `Source/Encoding/x265Enc.vb` | GetChunks()メソッド（326-328行目） |
| 2-3 | x265Enc.vb | `Source/Encoding/x265Enc.vb` | GetChunkEncodeActions()メソッド（330-368行目） |

**主要処理フロー**:
- **322-324行目**: CanChunkEncode() - チャンクエンコード可否判定（Dolby Vision制限）
- **330-368行目**: GetChunkEncodeActions() - チャンク範囲計算とActionリスト生成

#### Step 3: チャンク処理の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AOMEnc.vb | `Source/Encoding/AOMEnc.vb` | GetChunkEncodeActions()の実装 |

**主要処理フロー**:
- **118-149行目**: チャンク範囲計算と各チャンクのエンコードAction生成
- **133-146行目**: 2パスモード時のチャンク処理

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

```
MainForm (エンコード開始)
    │
    └─ VideoEncoder.CanChunkEncode()
           │
           ├─ Return True → GetChunkEncodeActions()
           │                      │
           │                      ├─ チャンク範囲計算
           │                      │
           │                      └─ List(Of Action)生成
           │                              │
           │                              └─ 各チャンクのEncode()
           │
           └─ Return False → 通常Encode()
```

### データフロー図

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

総フレーム数 ───▶ チャンク範囲計算
                       │
                       ▼
              ┌────────────────┐
              │ チャンク1 (0-999) │───▶ output_chunk1.hevc
              │ チャンク2 (1000-1999) │───▶ output_chunk2.hevc
              │ チャンク3 (2000-2999) │───▶ output_chunk3.hevc
              │ ...                 │
              └────────────────┘
                       │
                       ▼
                 Muxer結合 ───▶ output.mkv
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| x265Enc.vb | `Source/Encoding/x265Enc.vb` | ソース | x265のチャンクエンコード実装 |
| AOMEnc.vb | `Source/Encoding/AOMEnc.vb` | ソース | AOMEncのチャンクエンコード実装 |
| SvtAv1Enc.vb | `Source/Encoding/SvtAv1Enc.vb` | ソース | SVT-AV1のチャンクエンコード実装 |
| VideoEncoder.vb | `Source/Encoding/VideoEncoder.vb` | ソース | CanChunkEncode基底実装 |
| Muxer.vb | `Source/General/Muxer.vb` | ソース | チャンク結合処理 |
