# 灰度对比测试工具

用于统一渲染引擎灰度发布期间的新旧引擎对比验证。

## 能力

- **像素对比**：基于 FFmpeg SSIM + PSNR 双指标，评估视频画质差异
- **音频对比**：基于差值音频 RMS，评估音频波形差异
- **批量对比**：10个预设场景覆盖 P0/P1/P2 优先级
- **HTML 报告**：可视化对比结果，包含画质、音频、性能三维度
- **两种切换方式**：支持 engine 参数直传 或 Feature Flag 白名单切换

## 目录结构

```
tests/render_compare/
├── __init__.py       # 包导出
├── README.md         # 本文档
├── video_diff.py     # 视频像素对比（SSIM + PSNR）
├── audio_diff.py     # 音频对比（差值 RMS）
├── scenarios.py      # 预定义对比场景（10个）
└── runner.py         # 批量对比执行器 + HTML 报告生成
```

## 快速开始

### 环境要求

- FFmpeg 4.4+（需带 ssim 和 psnr 滤镜）
- Python 3.10+
- httpx（API 调用）

### 配置环境变量

```bash
export STAGING_API_URL=https://api.staging.example.com
export STAGING_API_KEY=your_api_key
export STAGING_INTERNAL_API_KEY=your_internal_key  # 可选，Feature Flag 模式需要
```

### 运行对比

```bash
# 运行所有 P0 场景（最核心的5个）
python -m tests.render_compare.runner --priority P0 --output ./report/

# 运行 P0 + P1 场景
python -m tests.render_compare.runner --priority P1 --output ./report/

# 只跑指定场景
python -m tests.render_compare.runner --scenarios simple_pass_through,subtitle_rendering

# 使用 Feature Flag 方式切换引擎（需要 internal key）
python -m tests.render_compare.runner --priority P0 --flag-mode

# 自定义阈值
python -m tests.render_compare.runner --priority P0 --ssim-threshold 0.95 --psnr-threshold 30
```

## 对比场景

| ID | 名称 | 优先级 | 验证点 |
|----|------|--------|--------|
| simple_pass_through | 简单直通 | P0 | 直通优化路径正确性 |
| multi_clip_transition | 多clip转场 | P0 | 转场效果 + concat |
| subtitle_rendering | 字幕渲染 | P0 | ASS字幕渲染 |
| independent_audio_track | 独立音频轨 | P0 | 音频混音（amix） |
| no_audio_video | 无音轨视频 | P0 | 无音轨防御逻辑 |
| picture_in_picture | 画中画 | P1 | overlay 图层 |
| multi_layer_mix | 多图层混合 | P1 | 多图层复杂场景 |
| image_background | 图片背景 | P1 | background 层 + 无音频 |
| long_video_stress | 长视频压力 | P2 | 多clip性能 |
| vertical_portrait | 竖屏9:16 | P2 | scale 策略（铺满裁剪） |

## 验收标准（建议）

### 视频质量
- **平均 SSIM >= 0.90**：通过（有微小差异但视觉可接受）
- **平均 SSIM >= 0.95**：优秀（视觉几乎无差异）
- **平均 PSNR >= 25 dB**：通过
- **分辨率一致 + 时长差 < 0.1s**：通过

### 音频质量
- **相似度 >= 0.85**：通过
- **采样率/声道数一致**：通过

### 性能
- **平均性能差异在 ±10% 以内**：可接受
- **直通场景新引擎更快**（预期 +30%）

## API 约定

Runner 默认假设渲染 API 支持以下接口：

### 提交任务
```
POST /api/v1/render/compose
Authorization: Bearer {api_key}
Body: { ...plan_payload, "engine": "legacy" | "unified" }
Response: { "task_id": "xxx" }
```

### 查询状态
```
GET /api/v1/tasks/{task_id}
Response: { "status": "completed", "output_url": "...", "duration_sec": 5.2 }
```

### Feature Flag（flag-mode）
```
PUT /api/v1/internal/feature-flags/render_engine
X-API-Key: {internal_key}
Body: { "enabled": true, "percentage": 100 }
```

如果你的 API 接口不同，请修改 `StagingAPI` 类中的对应方法。

## 故障排查

### 对比失败定位指南

1. **像素差异大（SSIM < 0.90）**
   - 检查分辨率是否一致
   - 检查帧率是否一致
   - 用 `save_diff_frame` 生成差异帧可视化
   - 检查转场效果（slideup/slidedown 是新引擎独有）

2. **音频不一致**
   - 检查音频编码参数（码率、采样率）
   - 检查主音频源优先级（main > broll）
   - 用 ffprobe 对比两视频音频流参数

3. **渲染失败**
   - 检查日志：`[unified-render] render failed`
   - 检查素材是否完整下载
   - 检查 FFmpeg 命令是否正确
