---
generated_at: 2026-01-23 10:30:00
metrics:
  claims_total: 60
  claims_with_evidence: 58
  claims_without_evidence: 2
confidence_derived: 0.97
---

# 根拠レポート：servers-movie_writer 単体テストケース一覧

## 本レポートについて

### 目的
本レポートは、生成された単体テストケース一覧の信頼性を検証し、人間レビュアーが効率的にレビューできるようにすることを目的としています。

### チェック方法
以下の観点でドキュメントの内容（Claim：主張）を検証しています：

1. **根拠の有無確認**：各主張に対して、ソースコード・既存設計書・要件定義書などの根拠（Evidence）が存在するか
2. **根拠との整合性**：主張の内容が根拠と矛盾していないか
3. **網羅性**：参照すべき情報源を適切にカバーしているか

### 信頼度スコアの算出
- **confidence_derived** = 根拠あり件数 / 総主張件数
- 状態「○」：根拠あり、「△」：根拠不足または要確認

### 本レポートの使い方
1. まず「サマリー」で全体の信頼度と優先レビュー項目を確認
2. 「Claims と根拠の対応」で △ の項目を重点的にレビュー
3. 「不足情報」で補完が必要な情報源を確認

---

## 1) サマリー（まず見るところ）
- 総合信頼度（derived）：**0.97**
  - 根拠あり：58 / 60、根拠なし：2
- 優先レビュー（高）
  1. **UT-MVW-010**：ディスク容量10GiB未満の警告条件 - 実際の閾値確認が必要
  2. **UT-MVW-035**：大文字拡張子の処理 - has_extension()の大文字小文字処理の確認が必要

## 2) 参照した情報（Evidence一覧）
> ここに「実在するもの」だけ列挙。抽出フェーズで付けたIDをそのまま出す。

- E-01: `servers/movie_writer/movie_writer.h` - MovieWriterクラス定義
- E-02: `servers/movie_writer/movie_writer.cpp` - MovieWriterクラス実装
- E-03: `servers/movie_writer/movie_writer_pngwav.h` - MovieWriterPNGWAVクラス定義
- E-04: `servers/movie_writer/movie_writer_pngwav.cpp` - MovieWriterPNGWAVクラス実装

## 3) Claims と根拠の対応（レビューの主戦場）
| Claim ID | 主張 | Evidence | 状態 |
|---|---|---|---|
| C-01 | add_writerでライターが登録される | E-02 L43-46: `writers[writer_count++] = p_writer` | ○ |
| C-02 | MAX_WRITERS超過時にエラー | E-02 L44: `ERR_FAIL_COND(writer_count == MAX_WRITERS)` | ○ |
| C-03 | MAX_WRITERS-1個目の登録 | E-01 L56-58: `MAX_WRITERS = 8` | ○ |
| C-04 | find_writer_for_fileで対応ライター検索 | E-02 L48-55: 後方から検索してhandles_fileで判定 | ○ |
| C-05 | 後から登録されたライターが優先 | E-02 L49: `for (int32_t i = writer_count - 1; i >= 0; i--)` | ○ |
| C-06 | 対応ライターなしでnullptr返却 | E-02 L54: `return nullptr` | ○ |
| C-07 | get_audio_mix_rateのデフォルト値48000 | E-02 L57-58: `uint32_t ret = 48000` | ○ |
| C-08 | get_audio_speaker_modeのデフォルト値STEREO | E-02 L63: `AudioServer::SpeakerMode ret = AudioServer::SPEAKER_MODE_STEREO` | ○ |
| C-09 | beginでの録画開始処理 | E-02 L98-132: 各種初期化処理 | ○ |
| C-10 | ディスク容量10GiB未満で警告 | E-02 L111-113: `dir->get_space_left() < 10 * Math::pow(1024.0, 3.0)` | △ |
| C-11 | mix_rate % fps != 0で警告 | E-02 L124-126: `if ((mix_rate % fps) != 0)` | ○ |
| C-12 | 相対パスのres://変換 | E-02 L107-109: `if (path.is_relative_path()) path = "res://" + path` | ○ |
| C-13 | add_frameでフレーム追加 | E-02 L181-245: フレーム追加処理全体 | ○ |
| C-14 | ビューポートサイズ異なる場合のリサイズ | E-02 L199-227: `if (vp_tex->get_size() != movie_size)` | ○ |
| C-15 | ソースがワイドの場合の水平クロップ | E-02 L214-218: `if (src_aspect > dst_aspect)` | ○ |
| C-16 | ソースが縦長の場合の垂直クロップ | E-02 L219-223: `else if (src_aspect < dst_aspect)` | ○ |
| C-17 | HDR2D使用時のsRGB変換 | E-02 L229-232: `if (RenderingServer::get_singleton()->viewport_is_using_hdr_2d(main_vp_rid))` | ○ |
| C-18 | ウィンドウタイトル更新 | E-02 L191-193: `main_window->set_title(...)` | ○ |
| C-19 | 時間フォーマット | E-02 L184-188: 時間計算とvformat | ○ |
| C-20 | endでの録画終了 | E-02 L247-282: 終了処理と統計出力 | ○ |
| C-21 | 相対パスの絶対パス変換 | E-02 L256-260: `if (movie_path.is_relative_path())` | ○ |
| C-22 | 統計情報の計算 | E-02 L278-280: CPU時間、GPU時間、エンコード時間の出力 | ○ |
| C-23 | set_extensions_hintで拡張子収集 | E-02 L160-179: 全ライターから拡張子を収集 | ○ |
| C-24 | handles_fileでGDVIRTUAL呼び出し | E-02 L84-88: `GDVIRTUAL_CALL(_handles_file, p_path, ret)` | ○ |
| C-25 | handles_file未オーバーライドでfalse | E-02 L85: `bool ret = false` | ○ |
| C-26 | get_supported_extensionsでGDVIRTUAL呼び出し | E-02 L90-96: `GDVIRTUAL_CALL(_get_supported_extensions, exts)` | ○ |
| C-27 | write_beginでGDVIRTUAL呼び出し | E-02 L68-72: `GDVIRTUAL_CALL(_write_begin, ...)` | ○ |
| C-28 | write_begin未オーバーライドでERR_UNCONFIGURED | E-02 L69: `Error ret = ERR_UNCONFIGURED` | ○ |
| C-29 | write_frameでGDVIRTUAL呼び出し | E-02 L74-78: `GDVIRTUAL_CALL(_write_frame, ...)` | ○ |
| C-30 | write_endでGDVIRTUAL呼び出し | E-02 L80-82: `GDVIRTUAL_CALL(_write_end)` | ○ |
| C-31 | MovieWriterPNGWAV::get_audio_mix_rate | E-04 L36-38: `return mix_rate` | ○ |
| C-32 | MovieWriterPNGWAV::get_audio_speaker_mode | E-04 L39-41: `return speaker_mode` | ○ |
| C-33 | get_supported_extensionsでpng追加 | E-04 L43-45: `r_extensions->push_back("png")` | ○ |
| C-34 | handles_fileでpng判定 | E-04 L47-49: `return p_path.has_extension("png")` | ○ |
| C-35 | 大文字PNG拡張子の処理 | E-04 L48: `has_extension` - 大文字小文字の動作は要確認 | △ |
| C-36 | png以外でfalse返却 | E-04 L48: `has_extension("png")` | ○ |
| C-37 | zeros_strで0のパディング | E-04 L51-60: ゼロパディングロジック | ○ |
| C-38 | zeros_strで任意数値のパディング | E-04 L51-60: 桁ごとの計算ロジック | ○ |
| C-39 | zeros_strの境界値 | E-04 L38-39: `MAX_TRAILING_ZEROS = 8` | ○ |
| C-40 | write_beginでWAVファイル作成 | E-04 L85-140: RIFFヘッダ書き込み処理 | ○ |
| C-41 | write_beginでの相対パス変換 | E-04 L66-68: `if (base_path.is_relative_path())` | ○ |
| C-42 | ディレクトリアクセス失敗 | E-04 L73-74: `ERR_FAIL_COND_V(d.is_null(), FAILED)` | ○ |
| C-43 | WAVファイルオープン失敗 | E-04 L85-86: `ERR_FAIL_COND_V(f_wav.is_null(), ERR_CANT_OPEN)` | ○ |
| C-44 | 既存PNGファイル削除 | E-04 L70-83: whileループでremove | ○ |
| C-45 | STEREOで2チャンネル | E-04 L101-103: `case SPEAKER_MODE_STEREO: channels = 2` | ○ |
| C-46 | SURROUND_31で4チャンネル | E-04 L104-106: `case SPEAKER_SURROUND_31: channels = 4` | ○ |
| C-47 | SURROUND_51で6チャンネル | E-04 L107-109: `case SPEAKER_SURROUND_51: channels = 6` | ○ |
| C-48 | SURROUND_71で8チャンネル | E-04 L110-112: `case SPEAKER_SURROUND_71: channels = 8` | ○ |
| C-49 | WAVフォーマットチャンク書き込み | E-04 L115-131: fmtチャンク、PCMフォーマット | ○ |
| C-50 | write_frameでPNG保存 | E-04 L146-149: `save_png_to_buffer`とFileAccess::WRITE | ○ |
| C-51 | write_frameでオーディオ書き込み | E-04 L150: `f_wav->store_buffer((const uint8_t *)p_audio_data, audio_block_size)` | ○ |
| C-52 | frame_countインクリメント | E-04 L152: `frame_count++` | ○ |
| C-53 | f_wavがnullでERR_UNCONFIGURED | E-04 L144: `ERR_FAIL_COND_V(f_wav.is_null(), ERR_UNCONFIGURED)` | ○ |
| C-54 | ファイル名連番 | E-04 L148: `base_path + zeros_str(frame_count) + ".png"` | ○ |
| C-55 | write_endでWAVサイズ更新 | E-04 L157-165: seekとstore_32 | ○ |
| C-56 | write_endでf_wav null安全 | E-04 L158: `if (f_wav.is_valid())` | ○ |
| C-57 | 位置4にRIFFサイズ書き込み | E-04 L161-162: `f_wav->seek(4); f_wav->store_32(total_size + datasize)` | ○ |
| C-58 | 位置0x28にdataサイズ書き込み | E-04 L163-164: `f_wav->seek(0x28); f_wav->store_32(datasize)` | ○ |
| C-59 | コンストラクタでmix_rate読み込み | E-04 L169: `mix_rate = GLOBAL_GET("editor/movie_writer/mix_rate")` | ○ |
| C-60 | コンストラクタでspeaker_mode読み込み | E-04 L170: `speaker_mode = AudioServer::SpeakerMode(int(GLOBAL_GET("editor/movie_writer/speaker_mode")))` | ○ |

## 4) 不足情報（Unknown / Missing）
- **UT-MVW-010（ディスク容量警告）**: ディスク容量10GiB未満という閾値は、実際のユースケースにおいて適切かどうかの検証が必要
  - 候補：ユーザードキュメント / 設計意図書 / コミット履歴
- **UT-MVW-035（大文字拡張子）**: `String::has_extension()`が大文字小文字を区別するかどうかは、Godotのcoreコードを確認する必要あり
  - 候補：`core/string/ustring.cpp` / Godot公式ドキュメント

## 5) リスクフラグ（レビュー観点）
- **0: 低リスク** - MovieWriterの基本機能（add_writer, find_writer_for_file）
- **0: 低リスク** - WAVファイル生成の基本フォーマット
- **1: 中リスク** - アスペクト比変換・クロップ処理（視覚的な品質に影響）
- **1: 中リスク** - HDR2D変換処理（色再現性に影響）
- **0: 低リスク** - 統計情報出力（デバッグ用途）

## 6) レビュアーチェックリスト（最小）
- [ ] `has_extension()`の大文字小文字処理を確認（UT-MVW-035）
- [ ] ディスク容量警告閾値10GiBの妥当性を確認（UT-MVW-010）
- [ ] WAVファイルの位置0x28が正しいdataチャンクオフセットか確認（UT-MVW-058）
- [ ] アスペクト比クロップのエッジケース（整数除算の丸め誤差）を確認（UT-MVW-015, UT-MVW-016）
- [ ] MAX_TRAILING_ZEROS=8の設計意図確認（60fps x 10日以上の録画想定？）（UT-MVW-039）
