Veyra-NRVideo 1.0.0 Remote Play 构建与对应源码交付指南
Veyra-NRVideo 1.0.0 Remote Play 构建与对应源码交付指南
本篇技术指南以 Veyra-NRVideo 1.0.0 的串流(PS5 Remote Play)构建说明为主线,完整拆解 VEYRA_ENABLE_REMOTEPLAY 这一显式开关背后的构建链路:从固定 chiaki-ng 提交、打补丁、准备静态依赖,到 build-native.ps1 与 build.ps1 的两段式构建,再到 RemotePlay-source 对应源码包的组织方式与 AGPL-3.0-only(含上游 OpenSSL 例外)许可边界。读完后你将能独立复现一条“源码级可审计”的串流构建路径,并清楚知道哪些结论有证据、哪些仍是未验证边界。
一、这条构建路径的核心前提:串流是显式可选项
1.0.0 的 portable 包启用了 VEYRA_ENABLE_REMOTEPLAY;不带该选项的默认构建不包含 PS5 串流能力。这一点在当前仓库的顶层构建脚本中有明确落点:该选项默认关闭,且只有在开启时才会引入串流后端与相关源码:
option(VEYRA_ENABLE_REMOTEPLAY "Build PS5 Remote Play with pinned Chiaki source" OFF)
默认 OFF 并非“功能未完成”的暗示,而是一种工程约束:串流组合会引入一个由外部协议库派生并带 AGPL 义务的二进制,只有当构建者显式提供固定版本的 Chiaki 源码树、审查过的补丁和匹配工具链的静态依赖时,组合才应成立。
开启后,顶层构建会做三件事:
| 位置 | 动作 |
|---|---|
| CMakeLists.txt | include(cmake/VeyraRemotePlay.cmake),定义 VEYRA_ENABLE_REMOTEPLAY=1,加入 RemotePlaySource.cpp 与 RemotePlaySessionSource.cpp |
| CMakeLists.txt | 链接 SDL3 3.4.14(find_package(SDL3 3.4.14 EXACT CONFIG REQUIRED))、加入 RemotePlayPanel.cpp 与 ControllerInput.cpp,并注册 PS5 边界/画质/配置存储测试 |
| CMakeLists.txt | 生成无 GUI 的 veyra_remoteplay_probe,可用保存的配置对比编解码/码率组合 |
命令行的显式开关在 scripts/build.ps1 中:-RemotePlay 一旦缺省,configure 行就写 -DVEYRA_ENABLE_REMOTEPLAY=OFF;一旦给出,则强制要求五个路径参数全部存在,缺一个即抛错,绝不会“悄悄降级”成预编译库:
if ($RemotePlay) {
foreach ($path in @($ChiakiCheckout,$ChiakiStage,$RemotePlayPrefixPath,$ProtocPath,$PkgConfigPath)) {
if (-not $path -or -not (Test-Path -LiteralPath $path)) { throw "Remote Play requires existing ChiakiCheckout, ChiakiStage, RemotePlayPrefixPath, ProtocPath and PkgConfigPath." }
}
}
二、上游源码与许可证事实
1.0.0 构建所对应的上游与许可信息如下(保持原文事实):
- 应用本体:Veyra-NRVideo,标签
v1.0.0。 - Chiaki:chiaki-ng,固定提交
0e16950165f06e5c3291537c2eeba6e852be7120,并附加scripts/remoteplay/patches/0001与0002两个补丁。 - 许可:AGPL-3.0-only,附上游 OpenSSL 例外。组合后的程序同样受该许可约束,同时保留各组件原有声明;Veyra 原始源码仍为 GPLv3。
仓库中该固定版本被记录为可校验的契约,而不只是文档里的一行文字。在 scripts/remoteplay/dependency-lock.json 中写明了 chiaki_commit、recursive_submodules(必须与固定树中的 gitlink 一致)、native_api(CHIAKI_VEYRA_VIDEO_METADATA_API=1)、补丁清单,以及交付时的原生构建状态标记 WINDOWS_PRODUCT_LINKED_OFFLINE_TESTS_PASS_PS5_PENDING,并显式声明包内不含任何运行时 DLL 与厂商 SDK。
许可原文与各组件声明分别落在:
- licenses/remoteplay/CHIAKI_AGPL3_OPENSSL.txt
- licenses/remoteplay/SDL3_NOTICES.txt
- licenses/remoteplay/curl-LICENSE.txt、nanopb-LICENSE.txt、jerasure-LICENSE.txt、gf-complete-LICENSE.txt
- 各静态依赖目录(
json-c、libevent、miniupnpc、openssl、opus、sdl3),每个目录内含copyright与vcpkg.spdx.json
这意味着:只把 Veyra 根目录的 GPL 文件当作“整套程序的许可记录”是不充分的,组合程序的许可记录必须包含上游 notices 与补丁的派生说明。仓库的 THIRD_PARTY_NOTICES.md 也对此做了明确表述。
三、构建环境与前置条件
原文要求:Visual Studio 2022 x64 工具链、CMake、Ninja、Python 与 protobuf 工具;FFmpeg 与增强 SDK 的要求仍在 BUILD.md(本仓库现路径为 docs/history/reports/BUILD.md)。
需要注意的隐含环境条件(来自实际脚本与 CMake):
- 必须使用 x64 的 MSVC 开发者终端。只需普通用户权限即可,不需要管理员权限。
- CMake ≥ 3.24:CMakePresets.json 与 services/remoteplay-probe/CMakeLists.txt 均要求 3.24。
- 协议库用 C,Veyra 新基础库用 C++20:串流核心目标显式声明
cxx_std_20并关闭编译器扩展(CXX_EXTENSIONS OFF)。 - 运行时库一致:
build-native.ps1传入-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded,即静态/MT。这一点不能和动态 CRTs 的依赖混搭,也不要拿 MinGW 的.a充当 MSVC 的.lib。 - Python 用于源码树校验:共享 CMake 会
find_package(Python3 REQUIRED COMPONENTS Interpreter),在 configure 阶段就调用校验脚本,校验失败直接FATAL_ERROR。
四、步骤 1:获取应用源码
克隆 Veyra 并检出 v1.0.0:
git clone --branch v1.0.0 --depth 1 https://gitcode.com/GitHub_Trending/ve/Veyra-NRVideo.git Veyra-NRVideo
后续所有命令都在该仓库根目录执行。仓库本身是只读的参考实现,构建产物应写入被忽略的 out/ 目录(脚本默认行为即如此)。
五、步骤 2:克隆并固定 chiaki-ng,更新递归子模块
按文档要求,克隆 chiaki-ng 到上述固定提交,并递归更新子模块:
git clone --no-checkout https://github.com/streetpea/chiaki-ng.git C:/veyra-deps/chiaki-source
git -C C:/veyra-deps/chiaki-source checkout --detach 0e16950165f06e5c3291537c2eeba6e852be7120
git -C C:/veyra-deps/chiaki-source submodule update --init --recursive
git -C C:/veyra-deps/chiaki-source status --short
关键点:
--no-checkout+--detach组合避免了在任意分支上就地打补丁,保证“干净检出”与“打补丁的暂存树”是两个独立对象。- 递归子模块必须落实:发布时间包中提供的干净固定树与子模块清单,就是离线复现这份精确源码的参考。
- 最后一条
git status --short应保持干净;scripts/remoteplay/build-native.ps1 会对未提交改动直接报错Chiaki source checkout must be clean。
六、步骤 3:准备静态依赖与 vcpkg 三元组
原文要求:使用发布时对应的 vcpkg port 版本与 x64-windows-static 三元组;1.0.0 发布使用的是 C:/veyra-deps/remoteplay-installed/x64-windows-static;版本与来源记录在源码归档的 installed-status.txt 与 port recipes 中,路径需按本机调整。
依 dependency-lock.json,原生依赖集合为:
| 依赖 | 说明 |
|---|---|
| Opus | 音频编解码(CHIAKI_LIB_ENABLE_OPUS=ON) |
| OpenSSL | 加密与握手 |
| nanopb / protobuf tooling | 需真实 protoc.exe |
| Jerasure / gf-complete | FEC |
| curl | HTTP |
| json-c | PSN/OAuth 相关 JSON 处理(CMake 中经 pkg_check_modules 查找) |
| libevent | 事件循环 |
| miniupnpc | NAT 穿透 |
| SDL3 3.4.14(静态) | 仅用于手柄输入 |
SDL3 的版本被双重固定:lock 文件记录版本 3.4.14 与归档 SHA-512,而 CMake 侧用 find_package(SDL3 3.4.14 EXACT CONFIG REQUIRED) 强制精确匹配。这条 EXACT 约束非常实用——它能防止本机已安装的其它 SDL3 版本悄悄参与链接。
一个易踩的坑写在共享 CMake 里:关闭 RUDP 并不会移除 curl/json-c/libevent/miniupnpc。
# Disabling RUDP does NOT remove curl/json-c/libevent/miniupnpc in the pinned lib.
# Provision their REAL matching-toolchain dev libraries; never replace them with
# empty imported targets or remove FEC to force the native gate green.
也就是说,不要为了“让配置通过”而去伪造空 imported target、删 FEC 源码或忽略链接错误——那会让后续所有验证失去意义。
七、步骤 4:运行 build-native.ps1 建立原生门禁
这是原文第 4 步的核心命令,参数含义如下:
powershell.exe -NoProfile -File scripts/remoteplay/build-native.ps1 `
-ChiakiCheckout C:/veyra-deps/chiaki-source `
-StageDirectory out/remoteplay/chiaki-msvc-stage `
-BuildDirectory out/remoteplay/native `
-PrefixPath C:/veyra-deps/remoteplay-installed/x64-windows-static `
-ProtocPath C:/veyra-deps/remoteplay-installed/x64-windows/tools/protobuf/protoc.exe `
-PkgConfigPath C:/veyra-deps/vcpkg/downloads/tools/msys2/<hash>/mingw64/bin/pkg-config.exe
| 参数 | 作用 | 默认值 |
|---|---|---|
-ChiakiCheckout |
干净固定检出,用于 pin 校验与来源比对(必填) | — |
-Root |
Veyra 仓库根 | 脚本上两级目录 |
-StageDirectory |
打补丁的独立 git worktree | out/remoteplay/chiaki-msvc-stage |
-BuildDirectory |
原生 probe 的构建目录 | out/remoteplay/native |
-PrefixPath |
静态依赖前缀(传给 CMAKE_PREFIX_PATH) |
空 |
-ToolchainFile |
可选 vcpkg 工具链文件 | 空 |
-ProtocPath |
真实 protoc,传给 -DPROTOC= |
空 |
-PkgConfigPath |
真实 pkg-config,传给 -DPKG_CONFIG_EXECUTABLE= |
空 |
-Generator |
生成器 | Ninja |
脚本内部做了四件值得关注的事:
1)pin 与干净度硬校验。 脚本把固定提交写死在 $PinnedCommit,用 git rev-parse HEAD 比对,并用 git status --porcelain --untracked-files=no 拒绝脏树。
2)用 git worktree 而非复制;拒绝覆盖未知目录。
Invoke-Checked "git" @("-C",$ChiakiCheckout,"worktree","add","--detach",$StageDirectory,$PinnedCommit)
Invoke-Checked "git" @("-C",$StageDirectory,"submodule","update","--init","--recursive")
若 $StageDirectory 已存在但不是 worktree,脚本直接抛 Refusing to replace an existing non-worktree stage,避免误删别人的工作目录。
3)两个补丁的“幂等应用”。 先做反向检查判断是否已打过,未打过才正向 apply --check 再 apply:
& git -C $StageDirectory apply --reverse --check $patch 2>$null
$alreadyApplied = $LASTEXITCODE -eq 0
这允许在同一个已验证的 base stage 上重复运行脚本,同时下面的全量内容校验会拒绝任何无关改动。
4)全量内容验证,而不是“补丁能反打就算过”。 校验脚本 scripts/remoteplay/verify-chiaki-stage.py 的检查粒度相当细:
- 两棵树(clean 与 stage)的
HEAD都必须等于 pin; - 暂存区必须无改动(
git diff --cached --name-only为空); git submodule status --recursive每行首字符必须是空格(首字符非空格代表子模块缺失或 pin 不符);- 每个递归子模块内部都要
git diff --exit-code、git diff --cached --exit-code且无未跟踪文件; - 在临时
GIT_INDEX_FILE中从 pin 重建索引、依次apply --cached两个补丁、write-tree得到期望树,再用git diff --exit-code --ignore-submodules=none <expected>把实际工作区内容与期望树逐字节比较; - clean 检出本身必须是干净的。
全部通过后打印 CHIAKI_STAGE_EXACT_PATCHES_VERIFIED。这正是把“只凭文件名与 reverse-apply 判断”升级为内容级证明的关键。
随后脚本配置并构建探针目标,并只跑原生标签的测试:
cmake -S services/remoteplay-probe -B <BuildDirectory> -G Ninja `
-DCMAKE_BUILD_TYPE=Release -DVEYRA_RP_BUILD_NATIVE=ON `
-DVEYRA_RP_CHIAKI_SOURCE_DIR=<StageDirectory> -DVEYRA_RP_CHIAKI_VERIFY_DIR=<ChiakiCheckout> `
-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded
cmake --build <BuildDirectory> --config Release --target veyra_remoteplay_native_probe
ctest --test-dir <BuildDirectory> -C Release -L native-core --output-on-failure --timeout 30
探针目标定义在 services/remoteplay-probe/NativeChiaki.cmake,同时链接适配层 veyra_remoteplay_chiaki 与真实上游 chiaki-lib,测试标签为 native-core;not-ps5,从标签名就写明了它不覆盖 PS5。
脚本结束时会打印一句边界声明:原生初始化门禁通过,但 PS5 连接、解码器与 GPU 仍未被该探针测试。这与探针实际输出一致:
REAL_CHIAKI_CORE_INITIALIZED metadata_api_available=1 session_started=0 video_callbacks_observed=0
PS5_CONNECTION_NOT_TESTED VIDEO_DECODE_NOT_TESTED WINDOWS_PLAYER_NOT_TESTED
注意 session_started=0 与 video_callbacks_observed=0:这说明探针没有启动会话、也没有观测到视频回调。看到这行输出时,不要把“初始化成功”误读成“串流跑通”。
八、步骤 5:用 build.ps1 -RemotePlay 构建真实产品
原文第 5 步:
powershell.exe -NoProfile -File scripts/build.ps1 -Root . -Preset x64-release -RemotePlay `
-BuildDirectory out/build/release-1.0.0 `
-ChiakiCheckout C:/veyra-deps/chiaki-source `
-ChiakiStage out/remoteplay/chiaki-msvc-stage `
-RemotePlayPrefixPath C:/veyra-deps/remoteplay-installed/x64-windows-static `
-ProtocPath C:/veyra-deps/remoteplay-installed/x64-windows/tools/protobuf/protoc.exe `
-PkgConfigPath C:/veyra-deps/vcpkg/downloads/tools/msys2/<hash>/mingw64/bin/pkg-config.exe
build.ps1 会自行用 vswhere 定位 VS2022 的 vcvars64.bat,在一个临时的 .cmd 批处理里串起 call vcvars64 → cmake --preset → cmake --build,从而保证 C 与 C++ 编译器环境一致。失败码是分段的:找不到 VS 返回 3,configure 失败 5,构建失败 6,便于在 CI 中区分。
构建成功后,脚本还会把 FFmpeg 的五个动态库复制到输出目录,这与原文“保留既有五个动态 FFmpeg 库”的说法对应(当前脚本列表为 avcodec-63.dll、avformat-63.dll、avutil-61.dll、swresample-7.dll、swscale-10.dll)。若所选 FFmpeg 前缀带 dav1d.dll 则一并复制;若前缀不带而构建目录里残留旧 dav1d.dll,脚本会将其移除,避免“静默带入无关运行时”。
共享 CMake 里的三个硬性约束
cmake/VeyraRemotePlay.cmake 是产品与探针共用的唯一串流构建入口,它带来三条必须理解的约束:
(1)源码树存在性检查先于一切。
if(NOT EXISTS "${VEYRA_RP_CHIAKI_SOURCE_DIR}/lib/include/chiaki/session.h")
message(FATAL_ERROR "VEYRA_RP_BUILD_NATIVE needs the pinned chiaki-ng source tree")
endif()
(2)configure 阶段就校验来源,失败即中止。 校验脚本的 stdout/stderr 会拼进 FATAL_ERROR 文本,所以错误信息会直接告诉你 stage 与 clean 的差异点。
(3)把上游裁剪到“只做库”。 明确关闭 GUI/CLI/测试/Android/Borealis/FFmpeg 解码器/Pi 解码器/setsu/SteamDeck/Steam 快捷方式/Speex/RUDP/mbedTLS,打开 Opus,并强制 chiaki-lib 目标必须被创建(否则 FATAL_ERROR)。
这里还藏着 vcpkg 静态 miniupnpc 的经典陷阱,注释写得很清楚:
# vcpkg's static miniupnpc headers default to dllimport on Windows unless the
# caller opts into the static ABI. Without this definition the static library
# is found correctly but Chiaki emits unresolved __imp_* references.
target_compile_definitions(chiaki-lib PRIVATE MINIUPNP_STATICLIB)
如果你看到大量 __imp_* 未解析符号,而库文件确实被找到了,第一反应应当是检查这个宏,而不是换库。
另外 pkg_check_modules(... IMPORTED_TARGET json-c) 说明 pkg-config 是必需项而非可选美化——这也是 -PkgConfigPath 不可省略的原因。
九、运行时形态:静态的主体,动态的 FFmpeg
原文明确:1.0.0 使用静态 MSVC 运行时 + 静态 Chiaki/SDL/依赖,仅保留既有的五个动态 FFmpeg 库;系统网络、WinHTTP、DPAPI、WASAPI、DirectX 与驱动库不重分发。
逐项对应到仓库实现:
- 静态 MSVC 运行时:
-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded。 - 静态 SDL3:CMake 用
SDL3::SDL3-static的TARGET_LINKER_FILE加SDL3::Headers;QML 前端也复用同一路径把 PC 手柄转发给 PS5(见 CMakeLists.txt 的注释,其中说明只取 SDL 库文件与头文件,避免把 SDL 自带的系统库列表塞进的链接行,从而触发响应文件与 UTF-8 路径的兼容问题)。 - DPAPI:配对凭据的加密存储走 Windows DPAPI,src/remoteplay/ProfileStore.cpp 用
CryptProtectData/CryptUnprotectData并带CRYPTPROTECT_UI_FORBIDDEN,描述串为Veyra PS5 pairing;解密失败会映射为明确的ProfileLoadError::Decrypt,而不是静默返回空配置。 - WASAPI/DirectX/驱动库:来自操作系统,不随包分发。
因此“portable”在这里的含义是不依赖额外 VC 运行库、不依赖 Chiaki 的 DLL,而不是“完全无外部文件”——五个 FFmpeg DLL 仍是必需的。
十、RemotePlay-source 对应源码包到底装了什么
原文描述该 ZIP 提供:干净固定的 Chiaki 树与递归子模块文件、经审查的补丁、已安装依赖的 SPDX 记录、打过补丁的源码目录,以及 json-c、libevent、miniupnpc、OpenSSL、Opus、SDL3 的 vcpkg port recipes;还包括既有静态光流后端所用的本地 FidelityFX 源码;不包含任何 NVIDIA/Intel SDK、运行时、模型、私有配置或凭据;FFmpeg 源码是单独资产。
这些都能在生成脚本 scripts/package-remoteplay-source.py 中找到一一对应的实现:
| 归档内路径 | 来源与作用 |
|---|---|
chiaki-clean/ |
从干净固定树及其递归子模块逐个 git ls-files 收集;子模块清单另存为 chiaki-submodules.txt |
veyra/scripts/remoteplay/ |
补丁、锁文件、校验脚本等可审查改动数据 |
veyra/cmake/VeyraRemotePlay.cmake、veyra/scripts/build.ps1、veyra/CMakePresets.json、veyra/docs/...、veyra/THIRD_PARTY_NOTICES.md |
构建入口与许可声明 |
licenses/remoteplay/ |
保留的全部 notices |
dependencies/<dep>/source、/port、/installed-share |
每个依赖的实际源码 .clean、vcpkg port 与已安装 SPDX 记录 |
vcpkg-port-scripts/ |
port helper 源码、scripts/buildsystems/vcpkg.cmake、triplets/x64-windows-static.cmake、LICENSE.txt |
installed-status.txt |
实际安装状态,用于还原确切版本组合 |
fidelityfx/ |
仅开源 FidelityFX 源码 |
source-manifest.json |
每个文件的 path/size/sha256 |
excluded-development-binaries.json |
被排除项清单(便于审计“确实没夹带二进制”) |
同名 .sha256 |
归档摘要 |
脚本中的排除清单体现了“对应源码”而非“开发快照”的取舍:
bad={'.dll','.exe','.lib','.pdb','.obj','.o','.a','.so','.dylib','.onnx','.pth','.pt','.zip','.7z','.mp4','.log','.addon64'}
同时,它对 port 文件做了双重校验:读 vcpkg.spdx.json 中每个 SPDXRef-port-file- 项,用 SHA256 与实际 ports/<dep>/<fileName> 内容比对,不一致即 Port mismatch;每个依赖的源码目录必须恰好一个 .clean,否则报 Ambiguous source。符号链接也会被显式拒绝(Source symlink needs explicit review),避免归档出现指向归档外的引用。
校验归档完整性的推荐做法(与 source-manifest.json 配套):
Get-FileHash .\Veyra-1.0.0-RemotePlay-source.zip -Algorithm SHA256 # 与同名 .sha256 比对
Expand-Archive .\Veyra-1.0.0-RemotePlay-source.zip .\rp-src
# 逐文件比对 source-manifest.json 中的 size 与 sha256
对于普通用户:这份源码包不是运行所需,原文亦明确“不需要下载”。它服务于许可合规与可复现构建。
十一、两个补丁分别解决什么
补丁 0001:MSVC 下的变长数组兼容。 它覆盖五个文件:lib/src/ctrl.c、lib/src/regist.c、lib/src/remote/holepunch.c、lib/src/remote/rudp.c、lib/src/session.c——与 dependency-lock.json 的 msvc_compatibility_scope 完全一致。代码层面的实质是把栈上 VLA 改成堆分配并补齐错误路径。例如 ctrl_message_send 中:
if(payload_size > SIZE_MAX - sizeof(header)) { free(enc); return CHIAKI_ERR_INVALID_DATA; }
size_t buf_size = sizeof(header) + payload_size;
uint8_t *buf = malloc(buf_size);
if(!buf) { free(enc); return CHIAKI_ERR_MEMORY; }
以及 ctrl_connect 中先检查 message.data_size < 8 再计算 init_response_size,并在零长度时跳过分配。这些不只是“让 MSVC 编过”:它们同时消除了整数溢出与零长分配两个边界问题。
补丁 0002:视频样本元数据扩展。 它在 lib/include/chiaki/session.h 中定义 CHIAKI_VEYRA_VIDEO_METADATA_API 1、ChiakiVeyraSampleKind(CONFIG/FRAME)与结构体 ChiakiVeyraVideoSampleInfo(含 frame_index_valid、frame_index、width、height、frames_lost、reference_recovered),新增 chiaki_session_set_veyra_video_sample_cb;并在 lib/src/videoreceiver.c 中让 profile 切换时的配置头与每帧样本都能携带真实尺寸/帧号。
这一步的产品意义很直接:没有它,适配层拿不到真实帧号与实际 profile 元数据。Veyra 侧对这些信息的消费点可在 include/veyra/remoteplay/VideoIngress.h 看到——VideoQueueStats 里的 waitingForIdr、epoch、recoveries、dropped、highWaterDepth 等统计,以及 requireKeyframe()、takeIdrRequest() 这类恢复动作,都依赖“这一帧是不是关键帧、有没有丢参考”的可靠信号。
补丁 0002 还带来一条二进制层面的纪律(在 docs/remoteplay/NATIVE_GATE.md 中有记录):启用元数据扩展时,新 header 与库必须共同重建,不得混用旧二进制。混用会导致结构体布局不一致,而这类错误在 C 边界上往往表现为难以定位的内存问题。
十二、构建后的验证清单
原文第 4 步给出的“真实通过标准”是:链接实际 chiaki-lib,执行 chiaki_lib_init、上游 profile 预设与手柄 idle 契约检查;记录 CMakeCache、编译器、架构、依赖版本、完整命令与退出码。
按此可整理为一套可直接执行的检查表:
- 来源可信:校验脚本输出
CHIAKI_STAGE_EXACT_PATCHES_VERIFIED;VEYRA_RP_CHIAKI_VERIFY_DIR指向的 clean 树git status干净。 - 链接真实:
NativeChiaki.cmake中探针链接的是veyra_remoteplay_chiaki与chiaki-lib,没有用空 imported target 顶替。 - 初始化真实执行:
ctest -L native-core退出码 0,且日志里出现运行时打印的REAL_CHIAKI_CORE_INITIALIZED。字符串出现在源码里不算执行。 - 离线核心用例:
ctest -L offline-core覆盖 Annex B 处理、时间线、入队/丢帧统计、会话信箱等纯逻辑。注意 services/remoteplay-probe/CMakeLists.txt 的原话:这里刻意不含 NVIDIA/FFmpeg/Win32 依赖,“这里通过不代表原生 Chiaki 编译、视频解码、PS5 连接或延迟”。 - 配置存储:
rp.dpapi_profile用例验证 DPAPI 往返。 - 产品边界:
veyra_remoteplay_boundary_tests与veyra_remoteplay_profile_tests(链接veyra_remoteplay_chiaki),以及 PS5 硬件镜像/画质用例。
十三、Scope:这些证据能说明什么、不能说明什么
原文的范围声明必须原样保留其严谨性:
- PS5 连接与常规 USB 手柄路径有用户测试证据;
- 构建/离线 GPU 测试不能证明 Sony 授权、物理 HDR 输出、所有设备上的蓝牙支持,或长时间不中断会话;
- README 与发布说明保留这些限制。
把这句话翻译成工程语言:仓库里能证明的是“可构建、可链接、可初始化、离线逻辑正确”;而“这个组合是官方认可的客户端”“在你的电视上 HDR 真的亮了”“蓝牙手柄在你的主板上不丢包”“连续 6 小时不断流”都属于未被这些测试覆盖的命题。这也是为什么 dependency-lock.json 把交付状态写成 WINDOWS_PRODUCT_LINKED_OFFLINE_TESTS_PASS_PS5_PENDING,以及 THIRD_PARTY_NOTICES.md 明确称其为“非官方客户端,不代表 Sony 认可”。
十四、常见故障与定位路径
| 症状 | 最可能原因 | 定位点 |
|---|---|---|
Chiaki source pin mismatch: <head> |
检出不在固定提交 | build-native.ps1 |
Chiaki source checkout must be clean |
clean 树被就地修改 | 同上 L27-L28 |
Refusing to replace an existing non-worktree stage |
stage 目录存在但不是 worktree | 同上 L29-L34 |
Chiaki source verification failed: ... |
补丁未全量应用、子模块缺失,或同文件被额外改动 | verify-chiaki-stage.py |
Could not find protoc |
未传 -ProtocPath |
build-native 的 -DPROTOC= 分支 |
__imp_* 未解析符号 |
静态 miniupnpc 缺少 MINIUPNP_STATICLIB |
cmake/VeyraRemotePlay.cmake |
Could not find package configuration file ... SDL3 或版本不符 |
SDL3 不是 3.4.14 精确版本 | CMakeLists.txt 的 EXACT |
| json-c 找不到 | pkg-config 未提供或路径错误 | pkg_check_modules(... json-c) 与 -PkgConfigPath |
Upstream chiaki-lib target was not created |
上游裁剪选项导致目标未生成 | cmake/VeyraRemotePlay.cmake |
| Remote Play 相关参数缺失即报错 | build.ps1 -RemotePlay 要求五个路径全部存在 |
scripts/build.ps1 |
关于“删掉某个开关能不能过”:CHIAKI_ENABLE_RUDP 被关闭,但 curl/json-c/libevent/miniupnpc 仍在依赖图中;这一条已由 CMake 注释显式警告,不要用裁剪依赖来“修”配置失败。
十五、把 1.0.0 的构建契约对上当前仓库
以 1.0.0 文档为骨架,可以在当前仓库中逐一找到它的落地形态,这也是复核这份历史文档最有效的方式:
| 1.0.0 文档中的承诺 | 当前仓库中的对应实现 |
|---|---|
默认构建不含 PS5,VEYRA_ENABLE_REMOTEPLAY 开启 |
CMakeLists.txt、CMakeLists.txt |
| 固定 chiaki-ng 提交 + 两个补丁 | scripts/remoteplay/dependency-lock.json、patches/0001、patches/0002 |
build-native.ps1 创建独立 stage、应用补丁、验证完整内容 |
scripts/remoteplay/build-native.ps1、verify-chiaki-stage.py |
build.ps1 ... -RemotePlay 显式启用真实后端 |
scripts/build.ps1 |
| 共享 CMake、无 stub 回退 | cmake/VeyraRemotePlay.cmake |
| 静态运行时 + 静态 Chiaki/SDL + 五动态 FFmpeg | -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded、SDL3::SDL3-static、build.ps1 的 FFmpeg 复制列表 |
| 静态依赖 SPDX 与 port recipes 随源码归档 | scripts/package-remoteplay-source.py |
保留的 notices 在 licenses/remoteplay/ |
licenses/remoteplay |
| 源码包非普通用户必需 | 同上脚本生成的 README.txt 与发布说明 |
| PS5/手柄有用户证据,其余边界未证 | docs/history/releases/REMOTEPLAY_BUILD_1.0.0.md、docs/remoteplay/NATIVE_GATE.md |
若你要复核 1.0.0 之后的演进,发布对应源码说明在 docs/history/releases 下按版本排列(如 REMOTEPLAY_BUILD_1.0.1.md、REMOTEPLAY_BUILD_1.0.2.md),路径迁移关系记录在 docs/history/PATH_MAP.json。这样可以确认当前代码与 1.0.0 构建契约是否仍然一致,而不必依赖任何口头承诺。
结语
1.0.0 的串流构建路径本质上是一份可验证的构建契约:pin 到具体提交、两个可审查补丁、内容级校验而非“补丁可反打”、静态依赖与 SPDX 全程留痕、许可边界显式声明、测试结论严格限定在“构建/链接/初始化/离线逻辑”之内。这套做法值得借鉴的地方不在于某个具体命令,而在于它把“能不能编过”和“能不能声称支持”彻底分成了两个问题——前者由脚本与 CI 回答,后者由真机证据回答。