Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
57b9c45
feat: YAML config preset loading (#5)
TheAutomatic Mar 24, 2026
5030f36
feat: configurable label_font_size for FPS/frametime plots
TheAutomatic Mar 24, 2026
38f7e9e
feat: real-time preview, seek rendering, HEVC, multi-video fixes, dar…
TheAutomatic Mar 24, 2026
5732edd
chore: update preset example from current yaml
TheAutomatic Mar 25, 2026
687a875
perf(gui): implement async export and profiler integration
TheAutomatic Mar 25, 2026
2149470
feat(gui): integrate trdrop.ico and finalize async performance profiling
TheAutomatic Mar 25, 2026
6929ccf
style(gui): adapt dock icon for macOS with squircle shape
TheAutomatic Mar 25, 2026
e4ac074
feat(video): fix HDR detection and implement 5-stage SDR tonemapping …
TheAutomatic Mar 25, 2026
d3151e0
feat(video): rewrite HDR→SDR tonemapping with 3D LUT and add docs
TheAutomatic Mar 25, 2026
7c62628
feat: add duplicate threshold control to GUI and fix engine analyzer …
TheAutomatic Mar 25, 2026
b65de27
fix(video): safely probe hardware encoders to prevent AMD GPU crashes
TheAutomatic Mar 25, 2026
bd1732c
feat(build): add PyInstaller single-file EXE packaging
TheAutomatic Mar 25, 2026
cabf08f
fix: dynamically handle video streams with missing total_frames metad…
TheAutomatic Mar 26, 2026
e8fd3b0
feat: polish Chinese translations and fix UI layout issues in main wi…
TheAutomatic Mar 26, 2026
a6afefb
ui: final layout polishing, cross-platform fonts, and version update …
TheAutomatic Mar 26, 2026
64726fc
fix(gui): improve dark mode compatibility and update version to 2.1.0
TheAutomatic Mar 26, 2026
0c32ee4
build: add mac .icns icon and auto-select icon per platform
TheAutomatic Mar 26, 2026
b089a74
ci: add tag-triggered cross-platform release workflow
TheAutomatic Mar 26, 2026
dd7916e
ci: fix lint issues and skip GUI-marked tests in headless CI
TheAutomatic Mar 26, 2026
2615fea
ci: exclude flaky GUI engine test module in headless runner
TheAutomatic Mar 26, 2026
1015f53
ci/release: force Node24 actions, mac zip-only artifact, and curated …
TheAutomatic Mar 26, 2026
a1721af
ci/release: upgrade actions to Node24-compatible major versions
TheAutomatic Mar 26, 2026
73f5235
release: add bilingual notes (EN first) for v2.1
TheAutomatic Mar 26, 2026
c9afab0
release: drop artifact actions and upload assets directly via gh cli
TheAutomatic Mar 26, 2026
3b37290
release: use softprops uploads per platform without artifact/gh cli s…
TheAutomatic Mar 26, 2026
388e075
release: switch to official gh CLI for create/edit/upload
TheAutomatic Mar 26, 2026
cf4b6db
release: fix gh CLI repo context by adding checkout and --repo
TheAutomatic Mar 26, 2026
fffc88c
fix(ui): remove duplicate UI content display in main window
TheAutomatic Mar 26, 2026
cb2a59c
fix(ui): DPI-independent font rendering, spinbox click area, and sync…
TheAutomatic Mar 26, 2026
fad94bd
release(notes): include latest UI fixes from recent commits
TheAutomatic Mar 26, 2026
dfc8287
feat: change plot label font size to be relative to output height
TheAutomatic Mar 30, 2026
67b9c58
Adjust overlay layout and GUI frametime controls
TheAutomatic Mar 30, 2026
0520dad
Fix frametime overlay layout and defaults
TheAutomatic Mar 31, 2026
bac98ad
Fix CI test environment and GUI typing
TheAutomatic Mar 31, 2026
494296b
Exclude GUI tests from default test target
TheAutomatic Mar 31, 2026
2ec31e4
release: update beta.3 notes
TheAutomatic Mar 31, 2026
31a2416
fix: improve hardware encoder detection on laptops and add HDR suppor…
TheAutomatic Apr 1, 2026
eb883fd
chore: ignore session scratch files
TheAutomatic Apr 1, 2026
e933b4c
fix: suppress PyAV type stub errors for codec context attributes
TheAutomatic Apr 2, 2026
d62503e
ci: add v2.1 branch to CI trigger
TheAutomatic Apr 2, 2026
10910c8
release: v2.1.0-beta.4
TheAutomatic Apr 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ name: CI

on:
push:
branches: [v2]
branches: [v2, v2.1]
pull_request:
branches: [v2]
branches: [v2, v2.1]

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5

- name: Install uv
uses: astral-sh/setup-uv@v4
uses: astral-sh/setup-uv@v7
with:
version: "latest"

Expand All @@ -36,27 +36,34 @@ jobs:
test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
env:
QT_QPA_PLATFORM: offscreen
strategy:
fail-fast: false
matrix:
python-version: ["3.12"]

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5

- name: Install uv
uses: astral-sh/setup-uv@v4
uses: astral-sh/setup-uv@v7
with:
version: "latest"

- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}

- name: Install Qt runtime dependencies
run: |
sudo apt-get update
sudo apt-get install -y libegl1

- name: Install dependencies
run: uv sync --all-extras

- name: Run tests
run: uv run pytest tests/ -v --tb=short
run: make test

all-checks-pass:
name: All Checks Pass
Expand Down
123 changes: 123 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: Release

on:
push:
tags:
- "v*"

permissions:
contents: write

jobs:
ensure-release:
name: Ensure Release + Notes
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5

- name: Prepare release notes
run: |
cat > RELEASE_NOTES.md <<'EOF'
## TRDrop v2.1.0-beta.3 Release Notes

### Major updates
- Improved FPS/frametime overlay readability across 1/2/3/4-video layouts.
- Fixed multi-video frametime placement so each frametime plot stays within its own video region and no longer overlaps or gets hidden behind the framerate plot.
- Fixed frametime plot rendering so the history curve is visible instead of appearing as an empty chart box.
- Tuned dense 3/4-video layouts by reducing frametime axis label size and making framerate axes/curves thicker for clearer readability.
- Enabled frametime overlay by default and enabled profile generation by default in the main UI/default preset.
- Aligned the default test path with CI by excluding GUI-marked tests from `make test` and adding a separate `make test-gui` target.
- Improved headless Linux CI stability for PyQt-based tests by adding the required Qt/EGL runtime setup.

### macOS usage (ZIP-only in this release)
1. Download and extract `TRDrop-macos-universal.zip`.
2. In Terminal, run:
`chmod +x TRDrop-macos-universal`
3. Start the app:
`./TRDrop-macos-universal`
4. If blocked by Gatekeeper, right-click → Open, or allow it in Privacy & Security.

---

## TRDrop v2.1.0-beta.3 更新说明

### 主要功能更新
- 优化了 1/2/3/4 视频布局下 FPS/frametime 图表的可读性。
- 修复多视频场景下 frametime 图表位置错误的问题,确保每个 frametime 图都显示在各自视频区域内,不再与 framerate 图重叠或被遮挡。
- 修复 frametime 图表“只有框没有曲线”的问题,历史曲线现在可以正常显示。
- 针对 3/4 视频密集布局,缩小了 frametime 坐标数字,并加粗了 framerate 坐标线和曲线,显示更清晰。
- 主界面与默认预设现在默认开启 frametime 图表,并默认勾选 profile 生成功能。
- 让默认测试路径与 CI 保持一致:`make test` 默认排除 GUI 测试,并新增 `make test-gui` 用于单独运行 GUI 测试。
- 为无头 Linux 环境下的 PyQt 测试补充了 Qt/EGL 运行依赖,提升 CI 稳定性。

### macOS 使用说明(本次仅提供 ZIP 包)
1. 下载 `TRDrop-macos-universal.zip` 并解压。
2. 终端进入解压目录后执行:
`chmod +x TRDrop-macos-universal`
3. 启动:
`./TRDrop-macos-universal`
4. 若被 Gatekeeper 拦截:右键应用选择“打开”,或在「系统设置 → 隐私与安全性」点击“仍要打开”。
EOF

- name: Create or update GitHub release (official gh CLI)
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
run: |
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
gh release edit "$TAG" --repo "$GITHUB_REPOSITORY" --title "$TAG" --notes-file RELEASE_NOTES.md
else
gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --title "$TAG" --notes-file RELEASE_NOTES.md
fi

build-and-upload:
name: Build (${{ matrix.os }})
needs: ensure-release
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, macos-latest]

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "latest"

- name: Set up Python
run: uv python install 3.12

- name: Install dependencies
run: uv sync --all-extras

- name: Build with PyInstaller spec
run: uv run pyinstaller trdrop.spec --noconfirm --clean

- name: Prepare artifact (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path out | Out-Null
Copy-Item dist/TRDrop.exe out/TRDrop-windows-x64.exe

- name: Prepare artifact (macOS)
if: runner.os == 'macOS'
shell: bash
run: |
mkdir -p out
cp dist/TRDrop TRDrop-macos-universal
chmod +x TRDrop-macos-universal
zip -9 out/TRDrop-macos-universal.zip TRDrop-macos-universal

- name: Upload build outputs to release (official gh CLI)
shell: bash
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ github.ref_name }}
run: |
gh release upload "$TAG" out/* --repo "$GITHUB_REPOSITORY" --clobber
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
__pycache__/
*.py[cod]
*.so
*.exe
.venv/
*.egg-info/
dist/
Expand All @@ -20,3 +21,24 @@ examples/*.csv

# macOS
.DS_Store
*.mp4
*.csv

# User preset (use trdrop_preset.example.yaml as template)
trdrop_preset.yaml

# AI and planning files
trdrop_profile.summary.txt
implementation_plan.md
task.md
walkthrough.md
diff.txt
head_version.py
.cursorrules
.claude/

# transient icon conversion workspace
a.iconset/
*.iconset/

!uv.lock
68 changes: 68 additions & 0 deletions HDR_PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# TRDrop HDR 支持方案 (HDR_PLAN.md)

当前 TRDrop 导入 HDR 视频输出泛白、呈灰色的问题,主要是因为视频为 10-bit BT.2020 广色域与 PQ/HLG 伽马曲线,而 TRDrop 整个底层管线在强行按 8-bit BT.709 线性读取与合成。

要实现对 HDR 视频的支持,以下是两套完整的技术评估与改造方案:

---

## 方案 A: HDR 转 SDR 映射(Tonemapping)—— 推荐 ✅

此方案投入产出比最高,不会破坏现有核心逻辑。只在视频“入口处”做一层滤镜拦截,将 HDR 色调映射(Tone Map)回通用的标准 8-bit SDR。

### 1. 适用场景
* 快速修复“灰屏”问题。
* 生成的测定视频只需要在普通的手机、显示器、B站上观看,不需要炫技展示原版 HDR 高光。
* 追求代码修改最小化、性能影响最小化。

### 2. 需要改动的代码
**文件位置**: `src/trdrop/video/reader.py`
**改动内容**:
* 在 PyAV 获取解码帧之前,引入 `av.filter.Graph` 构建一个 FFmpeg 的滤镜网络。
* 动态检测输入视频的像素格式(如 `yuv420p10le`)。
* 如果是 HDR 视频,则令其穿过类似 `zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=rgb24` (针对 PQ)的滤镜管道。
* 输出端直接吐出处理好的 `rgb24` 帧数据,喂给下游。

### 3. 后续影响
* **分析引擎 (`engine`)**: 无需改动,继续用 8-bit `np.uint8`。
* **合成器 (`compositor/OSD`)**: 无需改动,原本的 (255,255,255) 就是 SDR 体系下的纯白。
* **导出端 (`export`)**: 无需改动,继续输出 8-bit SDR 的 `yuv420p`。

---

## 方案 B: 全链路原生 HDR 透传处理(极高难度)

真正的专业极客向方案,保持原视频的 10-bit 甚至 12-bit 高光动态范围不变,将测评数据(FPS、Frametime、图表)直接在由 `0-65535` 重构出来的广色域空间中绘制进去。

### 1. 适用场景
* 想将最终生成的评测视频放在顶级的 HDR 电视或 OLED 显示器上展示。
* 保留画质原汁原味的高保真追求。

### 2. 大面积的底层重构
要达成全链路 HDR,以下四个模块全部需要重写:

#### ⚙️ 第一关:入水管道升维 (`reader.py`)
* 获取数据流时不能再强制转化为 `format="rgb24"`(8-bit)。
* 必须将其提取为 `rgb48le`(16-bit packed RGB)或是完整的 10-bit `gbrp10le` 平面源。
* NumPy 的数据结构全面升级为 `dtype=np.uint16`。
* 必须**提取并保存**原视频的 HDR 静态/动态元数据 (Mastering Display Color Volume, Content Light Level - MaxCLL/MaxFALL)。

#### 🔬 第二关:特征对比算法升级 (`analysis`)
* SSIM、MSE 差异比对、Template Matching 等 OpenCV 计算虽然支持 `uint16` 矩阵,但之前基于 `0-255` 取值范围所设定的 `duplicate_threshold`(重复帧阈值)等全部会失效,必须建立两套阈值系统去分别适配 SDR 和 HDR 视频。

#### 🎨 第三关:色彩管理与画布重绘 (`compositor`)
* **痛点**:这是最麻烦的地方,必须手动调配 HDR 色彩锚点。
* 以前你在画布上画一条绿线或写白字,给的颜色是 `(0, 255, 0)` 或 `(255, 255, 255)`。
* 现在画布变成了一张巨大无比的网 (`0-65535`),且它遵从并不是人眼线性的 PQ/HLG 曲线。
* 如果你在 PQ 伽马下给一条白线 `(65535, 65535, 65535)`,这根线在屏幕上会放射出极为刺眼的 `10,000 Nits` 光芒。
* 如果你维持给 `(255, 255, 255)`,那么这根线对应的大概只有 `0.02 Nits`,几乎是**纯黑**的。
* **改法**:必须依据 PQ Transfer 查表,将 OSD 的 UI 亮度锁定在 “Paper White”(常规漫反射白,约 200 nits)级别,推算出对应的 16-bit 色值(大概是 `~38000` 左右),用这个特调过的色彩常量进行 `cv2.putText` 或曲线绘制。

#### 📦 第四关:打包与元数据回填 (`export`)
* 输出部分的代码 `streaming_video.py` 必须将格式切换为 `yuv420p10le` 开始 10-bit 编码压制。
* 仅仅压制还不够,必须向新容器(Container)和流(Stream)中重新注入刚才第一关提取的 HDR Metadata(Color primaries: BT.2020,Color trc: SMPTE 2084,Color space: BT.2020nc)以及相关的 SEI 信息。如果不加这一步,即便视频有了高动态,所有的播放引擎依旧只会把它当成普通的 SDR 画面来强制暗化映射(继续灰蒙蒙)。

---

### 推荐落实步骤
如果你要着手改善工具,**强烈建议从方案 A 开始做起**,几行 PyAV 黑魔法就能搞定入城口的格式化转换;不仅开发极快,还能保证分析算法不会出现断崖式的兼容错误。当你真的有了全链路 C++ 级别重构的耐心,再考虑开启方案 B。
7 changes: 5 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
.PHONY: lint test check testvideos clean-testvideos benchmark examples clean-examples clean
.PHONY: lint test test-gui check testvideos clean-testvideos benchmark examples clean-examples clean

lint:
uv run isort --check-only src tests
uv run flake8 src tests
uv run basedpyright src tests

test:
uv run pytest tests/ --verbose --ignore=tests/benchmarks/
uv run pytest tests/ --verbose -m "not gui" --ignore=tests/benchmarks/

test-gui:
uv run pytest tests/ --verbose -m "gui"

test-all:
uv run pytest tests/ --verbose
Expand Down
Loading