CD Code Digest Hub /GTA V

回放、编辑项目与视频导出

范围:control/replay/、replaycoordinator/,关联前端 VideoEditor、camera/replay、audio/replay 与 videorecording。总入口:Summary。

7 分钟阅读 8 个章节 1 张图

1. 两个层次的系统#

底层回放记录游戏对象和世界变化,并在播放时重建与控制世界;ReplayCoordinator 管理 clip、montage、编辑参数、音轨、效果与导出。视频文件是最后的呈现产物,不是整个回放系统唯一保存的数据。

ReplayPacketIDs 包含 camera、clock、weather、water simulation、game time、vehicle create/update/delete 等类型。它们证明回放记录状态/事件数据,不能将其理解为仅记录玩家输入、再完全确定性重演原始仿真。

2. 录制到导出的链路#

图中 packet 与底层压缩/文件封装是不同层。压缩格式、关键记录布局和插值策略需看具体 packet 类型与记录器,不能由“有 Compression 目录”推导统一编码算法。

3. 帧阶段与类型化记录#

CReplayMgr 暴露 StartFrame、PreProcess、Process、ProcessRecord、PostProcess、PostRender。CApp 和 CGame 在不同阶段调用这些接口,避免把所有状态混在任意时刻一次抓取。

control/replay 按 Entity、Ped、Vehicle、Camera、Game、Audio、Effects、Streaming、Preload 和 File 拆分;还有 attachment、interior、IPL、model、mesh set、lighting、RayFire 等管理器。回放需要记录或恢复的不仅是实体位置,还包括外观、附件、地图开关、天气和效果。

PacketBasics 提供向量与值表示辅助,ReplayInternal 的 RecordFx 路径检查 packet 是否应跟踪、是否有效,以及当前记录条件。持续存在的效果与瞬态事件有不同记录协议,不能把长期效果误当作一次性消息记录。

4. 播放需要接管世界#

IsReplayInControlOfWorld、ShouldUpdateScripts、IsEditModeActive 等接口控制普通游戏系统是否继续执行。PedIntelligence 在编辑模式可提前返回,脚本执行也有回放门控,过场查询可以改用录制帧标志。

这些分支防止原始 AI、脚本和回放同时写同一个对象。回放不是给正常游戏叠一台摄影机,而是在需要时接管某些世界状态;退出时又要将控制权交还。

对象身份不能直接保存内存地址。录制侧与播放侧通过 replay interfaces、tracking 和对象生命周期数据建立关联;create/update/delete、外观变化和附件关系必须一致。删除时仍被后续 packet 引用的对象,需要按回放协议处理。

5. 跳转、预加载与非线性时间#

ReplayPlaybackController 的 JumpToClip 保存 pending clip index 与 non-dilated time,而不是立即完成所有重建。播放还可预加载音频,世界侧有专门 Preload 和 Streaming 子目录。

在编辑器中跳到任意时刻,需要恢复当时持续状态,并准备相关模型、地图、动画和声音;不能简单从下一个事件继续执行。瞬态事件是否重新触发、持续效果是否保留、资源是否已就绪都影响结果。

非线性时间还会影响插值、天气过渡、灯光、粒子年龄和音轨 offset。维护新 packet 时应检查顺序播放与跳转两条路径,而不只检查录制后从头播放。

6. Montage 与编辑层#

storage 目录的 Clip、Montage、MontageMusicClip、MontageText 把录制素材与编辑决策分离。一个项目可以组织多个片段、音乐和文字,ReplayEditorParameters 与 PostFxRegistry 保存相关编辑配置。

Coordinator 负责 playback caching、自动生成项目、bake、取消与 cleanup;PlaybackController 通过接口查询导出状态与帧时长。前端 VideoEditor 操作的是这些编辑模型,不应直接修改底层录制缓冲的任意位置。

项目文件成功保存不代表所有引用的录制资源都仍存在;素材缺失、导出取消或切换 clip 都需要相应的错误与清理路径。本文未检查实际用户项目文件。

7. 视频与音频导出时间#

导出接口提供 IsExportReadyForReplay、IsExportingAudioFrameCaptureAllowed、HasExportErrored 和 GetExportFrameDurationMs。导出能使用固定帧步进,必须协调游戏画面、混音器与视频时间。

Core/app.cpp 在回放导出分支比较音频总时间与视频总时间,必要时额外触发音频更新或 mixer 更新。该机制避免低帧率/固定帧导出时声音数据跟不上画面,并说明“每输出一帧只做一次实时音频更新”的假设不成立。

控制器没有 recording data provider 时返回的 33 ms 是局部回退值,不应据此宣称所有回放固定为 30 FPS。实际导出节奏由 provider 和配置决定。

8. 成本、维护与源码依据#

成本包括记录缓冲、压缩/写盘、播放资源峰值、跳转重建、额外摄像机/效果与视频编码。固定帧导出与实时预览的性能指标不同,不能以导出慢直接推断正常游戏卡顿。

优先检查创建/删除跨时间点、天气与地图变更、持续特效、过场片段、第一人称、音轨预加载、跳转后恢复、取消导出和退出编辑器。本报告未执行录制、编码或回放工具。

源码重点
replay.h帧阶段、记录/播放控制门面
ReplayInternal.h世界接管、packet 记录和跟踪
ReplayPacketIDs.h记录数据类型
ReplayRecording.h录制、取消、前后时间范围
ReplayCoordinator.h项目、缓存、bake 与 cleanup
ReplayPlaybackController.cpppending jump、音频预加载、导出接口
Montage.h编辑项目数据
Core/app.cpp1387 行附近音视频追赶

关联:系统、音频、摄像机、持久化。