Change project name;
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
---
|
||||
home: true
|
||||
title: Oak 视频编辑器
|
||||
heroImage: /images/oak-icon.png
|
||||
heroText: Oak 视频编辑器
|
||||
heroFullScreen: false
|
||||
tagline: 现代开源的非线性剪辑器,强调速度与清晰度。
|
||||
actions:
|
||||
- text: 阅读文档
|
||||
link: /zh/build.html
|
||||
type: primary
|
||||
- text: 查看工程文件
|
||||
link: /zh/project-file-reference.html
|
||||
type: secondary
|
||||
features:
|
||||
- title: 快速剪辑
|
||||
details: 响应式时间线、智能缓存与高效媒体管理。
|
||||
- title: 面向创作者
|
||||
details: 简洁界面、可配置快捷键与清晰的工程结构。
|
||||
- title: 开源透明
|
||||
details: 公开开发流程,欢迎社区参与。
|
||||
footer: Copyright © Oak Video Editor
|
||||
---
|
||||
|
||||
## 关于 Oak
|
||||
|
||||
Oak 视频编辑器是 Olive 的重命名分支,目标是打造更完善、更友好的剪辑体验。本网站提供构建说明、工程文件参考与测试计划等贡献者文档。
|
||||
|
||||
## 快速开始
|
||||
|
||||
- 按《构建指南》在 Windows/macOS/Linux 上从源码构建。
|
||||
- 在《工程文件参考》了解项目数据结构。
|
||||
- 按《测试计划》确保发布质量。
|
||||
@@ -0,0 +1,116 @@
|
||||
# 构建指南
|
||||
|
||||
本文档介绍如何从源码构建 Oak Video Editor。
|
||||
|
||||
## 依赖
|
||||
|
||||
- CMake 3.20+
|
||||
- Ninja(推荐)
|
||||
- Qt 6(含私有头文件)
|
||||
- FFmpeg 开发库
|
||||
- OpenImageIO
|
||||
- OpenColorIO(2.x)
|
||||
- OpenEXR
|
||||
- Expat
|
||||
- PortAudio
|
||||
- OpenGL 头文件
|
||||
- XKB common(Linux)
|
||||
|
||||
## Linux(Ubuntu/Debian)
|
||||
|
||||
安装依赖:
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
ninja-build pkg-config \
|
||||
qt6-base-dev qt6-base-dev-tools qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \
|
||||
libavcodec-dev libavformat-dev libavfilter-dev libavutil-dev libswscale-dev libswresample-dev \
|
||||
libopencolorio-dev libopenimageio-dev libopenexr-dev libexpat1-dev \
|
||||
portaudio19-dev libgl1-mesa-dev libxkbcommon-dev
|
||||
```
|
||||
|
||||
配置并构建:
|
||||
|
||||
```bash
|
||||
cmake -S . -B build -G Ninja -DBUILD_TESTS=ON -DBUILD_QT6=ON
|
||||
cmake --build build --config Release
|
||||
```
|
||||
|
||||
运行测试:
|
||||
|
||||
```bash
|
||||
ctest --test-dir build --output-on-failure -C Release
|
||||
```
|
||||
|
||||
## macOS(非官方支持)
|
||||
|
||||
说明:macOS **非官方支持**,目前只做 CI 自动化测试,不做人工测试。
|
||||
|
||||
安装依赖:
|
||||
|
||||
```bash
|
||||
brew update
|
||||
brew install ninja pkg-config qt@6 ffmpeg openimageio opencolorio openexr portaudio expat
|
||||
```
|
||||
|
||||
构建 OpenTimelineIO(可选,如需 OTIO 支持):
|
||||
|
||||
```bash
|
||||
git clone --depth 1 --branch v0.16.0 https://github.com/PixarAnimationStudios/OpenTimelineIO.git
|
||||
cmake -S OpenTimelineIO -B OpenTimelineIO/build -G Ninja \
|
||||
-DOTIO_SHARED_LIBS=ON \
|
||||
-DOTIO_PYTHON_BINDINGS=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX="${PWD}/otio-install"
|
||||
cmake --build OpenTimelineIO/build
|
||||
cmake --install OpenTimelineIO/build
|
||||
```
|
||||
|
||||
配置并构建:
|
||||
|
||||
```bash
|
||||
export PATH="$(brew --prefix qt@6)/bin:$PATH"
|
||||
export CMAKE_PREFIX_PATH="$(brew --prefix qt@6)"
|
||||
export OTIO_LOCATION="${PWD}/otio-install"
|
||||
export OCIO_LOCATION="$(brew --prefix opencolorio)"
|
||||
|
||||
cmake -S . -B build -G Ninja -DBUILD_TESTS=ON -DBUILD_QT6=ON \
|
||||
-DOTIO_LOCATION="${OTIO_LOCATION}" \
|
||||
-DOCIO_LOCATION="${OCIO_LOCATION}"
|
||||
cmake --build build --config Release
|
||||
```
|
||||
|
||||
运行测试:
|
||||
|
||||
```bash
|
||||
ctest --test-dir build --output-on-failure -C Release
|
||||
```
|
||||
|
||||
## Windows
|
||||
|
||||
Qt 6 请使用系统安装器或 CI action。其余依赖建议用 vcpkg。
|
||||
|
||||
```powershell
|
||||
choco install -y ninja
|
||||
$env:VCPKG_ROOT = "C:\vcpkg"
|
||||
& "$env:VCPKG_ROOT\vcpkg.exe" install ffmpeg openimageio opencolorio openexr expat portaudio --triplet x64-windows
|
||||
```
|
||||
|
||||
配置并构建:
|
||||
|
||||
```powershell
|
||||
cmake -S . -B build -G Ninja `
|
||||
-DBUILD_TESTS=ON `
|
||||
-DBUILD_QT6=ON `
|
||||
-DCMAKE_BUILD_TYPE=Release `
|
||||
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" `
|
||||
-DCMAKE_PREFIX_PATH="$env:Qt6_DIR"
|
||||
cmake --build build --config Release
|
||||
```
|
||||
|
||||
运行测试:
|
||||
|
||||
```powershell
|
||||
ctest --test-dir build --output-on-failure -C Release
|
||||
```
|
||||
@@ -0,0 +1,305 @@
|
||||
# Oak Video Editor 项目文件参考手册(详细版)
|
||||
|
||||
本文档基于当前源代码实现,描述 Oak Video Editor 的 XML 项目文件格式,目标是足够详细以实现兼容读写器。
|
||||
|
||||
> 代码来源:`app/node/project.cpp`、`app/node/node.cpp`、`app/node/value.*`、`app/node/keyframe.*`、`app/node/project/serializer/*`。
|
||||
|
||||
## 1. 根元素
|
||||
|
||||
```xml
|
||||
<olive version="230220" url="/path/to/project.ove">
|
||||
...
|
||||
</olive>
|
||||
```
|
||||
|
||||
- `version`:序列化版本号(`YYMMDD`)。
|
||||
- `url`:可选的项目文件路径。
|
||||
|
||||
## 2. 项目容器
|
||||
|
||||
完整保存时,会有 `project` 容器:
|
||||
|
||||
```xml
|
||||
<project>
|
||||
<project>...</project>
|
||||
<layout>...</layout>
|
||||
</project>
|
||||
```
|
||||
|
||||
- 内层 `<project>`:项目数据。
|
||||
- `<layout>`:界面布局(`MainWindowLayoutInfo::fromXml`)。
|
||||
|
||||
## 3. 项目数据(`Project::Save`)
|
||||
|
||||
```xml
|
||||
<project version="1">
|
||||
<uuid>...</uuid>
|
||||
<plugins>...</plugins>
|
||||
<nodes>...</nodes>
|
||||
<settings>...</settings>
|
||||
</project>
|
||||
```
|
||||
|
||||
### 3.1 `uuid`
|
||||
项目 UUID(QUuid 字符串)。
|
||||
|
||||
### 3.2 `plugins`
|
||||
项目中使用的 OpenFX 插件列表,用于加载节点前补充插件搜索路径。
|
||||
|
||||
```xml
|
||||
<plugins>
|
||||
<plugin id="com.vendor.Plugin" major="1" minor="2"
|
||||
bundle="/path/to/Plugin.ofx.bundle"
|
||||
file="/path/to/Plugin.ofx.bundle/Contents/MacOS/Plugin" />
|
||||
</plugins>
|
||||
```
|
||||
|
||||
属性:
|
||||
- `id`:OFX 插件标识符(与节点 `id` 相同)。
|
||||
- `major` / `minor`:插件版本。
|
||||
- `bundle`:插件 bundle 目录路径(优先使用)。
|
||||
- `file`:插件二进制路径(备用)。
|
||||
|
||||
加载策略:
|
||||
- 若存在 `<plugins>`,先把 `bundle`(或 `file`)加入 OFX 搜索路径并扫描,然后注册插件节点,再进入 `<nodes>` 解析。
|
||||
|
||||
### 3.3 `nodes`
|
||||
节点图,节点由 `Node::Save()` 写出:
|
||||
|
||||
```xml
|
||||
<nodes version="1">
|
||||
<node version="1" id="node.id" ptr="123456">
|
||||
<label>...</label>
|
||||
<color>...</color>
|
||||
<input>...</input>
|
||||
<links>...</links>
|
||||
<connections>...</connections>
|
||||
<hints>...</hints>
|
||||
<context>...</context>
|
||||
<caches>...</caches>
|
||||
<custom>...</custom>
|
||||
</node>
|
||||
</nodes>
|
||||
```
|
||||
|
||||
关键属性:
|
||||
- `id`:节点类型标识。OpenFX 节点为插件标识符。
|
||||
- `ptr`:序列化指针 ID,用于恢复连接与位置。
|
||||
- `version`:当前为 `1`。
|
||||
|
||||
### 3.4 `settings`
|
||||
项目设置,键值对形式保存:
|
||||
|
||||
已知键:
|
||||
- `cachesetting`
|
||||
- `customcachepath`
|
||||
- `colorconfigfilename`
|
||||
- `defaultinputcolorspace`
|
||||
- `colorreferencespace`
|
||||
- `root`
|
||||
|
||||
## 4. 节点序列化(`Node::Save` / `Node::Load`)
|
||||
|
||||
### 4.1 `label`
|
||||
节点显示名。
|
||||
|
||||
### 4.2 `color`
|
||||
节点覆盖颜色(整数索引)。
|
||||
|
||||
### 4.3 `input`
|
||||
每个输入:
|
||||
|
||||
```xml
|
||||
<input id="InputId">
|
||||
<primary>...</primary>
|
||||
<subelements count="N">
|
||||
<element>...</element>
|
||||
</subelements>
|
||||
</input>
|
||||
```
|
||||
|
||||
- `primary`:主元素(element = -1)。
|
||||
- `subelements`:数组输入,`count` 为数组长度。
|
||||
|
||||
#### 4.3.1 立即值结构(`primary` / `element`)
|
||||
|
||||
```xml
|
||||
<keyframing>0|1</keyframing>
|
||||
<standard>
|
||||
<track>...</track>
|
||||
</standard>
|
||||
<keyframes>
|
||||
<track>
|
||||
<key ...>...</key>
|
||||
</track>
|
||||
</keyframes>
|
||||
<csinput>...</csinput>
|
||||
<csdisplay>...</csdisplay>
|
||||
<csview>...</csview>
|
||||
<cslook>...</cslook>
|
||||
```
|
||||
|
||||
- `keyframing`:是否启用关键帧(仅在输入可关键帧时写出)。
|
||||
- `standard`:默认值(每条 track 一份)。
|
||||
- `keyframes`:仅当 `keyframing=1` 时写出。
|
||||
- `cs*`:仅用于 `kColor`,保存色彩管理信息。
|
||||
|
||||
#### 4.3.2 Track 数量
|
||||
由 `NodeValue::get_number_of_keyframe_tracks()` 决定:
|
||||
|
||||
| 类型 | Track 数量 |
|
||||
| --- | --- |
|
||||
| kVec2 | 2 |
|
||||
| kVec3 | 3 |
|
||||
| kVec4 | 4 |
|
||||
| kColor | 4 |
|
||||
| kBezier | 6 |
|
||||
| 其他 | 1 |
|
||||
|
||||
#### 4.3.3 标准值编码
|
||||
由 `NodeValue::ValueToString()` 写出,`NodeValue::StringToValue()` 读入:
|
||||
|
||||
- `kVec2`: `x:y`
|
||||
- `kVec3`: `x:y:z`
|
||||
- `kVec4`: `x:y:z:w`
|
||||
- `kColor`: `r:g:b:a`
|
||||
- `kBezier`: `x:y:cp1x:cp1y:cp2x:cp2y`
|
||||
- `kRational`: `num/den`
|
||||
- `kInt`: 整数文本
|
||||
- `kBinary`: Base64
|
||||
- `kText` / `kFont` / `kFile` / `kCombo` / `kStrCombo`: 纯文本
|
||||
- `kTexture` / `kSamples` / `kNone`: 无文本
|
||||
|
||||
特殊情况:
|
||||
- `kVideoParams` / `kAudioParams` 以子对象形式保存(见第 5/6 节)。
|
||||
- `kSubtitleParams` 在加载时被跳过(避免覆盖实际字幕数据)。
|
||||
|
||||
#### 4.3.4 关键帧(`NodeKeyframe::save`)
|
||||
|
||||
```xml
|
||||
<key input="InputId" time="num/den" type="0" inhandlex="0" inhandley="0" outhandlex="0" outhandley="0">value</key>
|
||||
```
|
||||
|
||||
- `input`:输入 ID。
|
||||
- `time`:理性时间。
|
||||
- `type`:关键帧类型枚举值。
|
||||
- `inhandlex` / `inhandley` / `outhandlex` / `outhandley`:贝塞尔控制点。
|
||||
|
||||
文本值使用 `NodeValue::ValueToString(data_type, value, true)`。
|
||||
|
||||
### 4.4 `links`
|
||||
节点间的“块”链接:
|
||||
|
||||
```xml
|
||||
<links>
|
||||
<link>ptr</link>
|
||||
</links>
|
||||
```
|
||||
|
||||
### 4.5 `connections`
|
||||
输入/输出连接:
|
||||
|
||||
```xml
|
||||
<connections>
|
||||
<connection input="InputId" element="-1">
|
||||
<output>ptr</output>
|
||||
</connection>
|
||||
</connections>
|
||||
```
|
||||
|
||||
### 4.6 `hints`(输入提示)
|
||||
|
||||
```xml
|
||||
<hints>
|
||||
<hint input="InputId" element="-1" version="1">
|
||||
<types>
|
||||
<type>...</type>
|
||||
</types>
|
||||
<index>0</index>
|
||||
<tag>...</tag>
|
||||
</hint>
|
||||
</hints>
|
||||
```
|
||||
|
||||
### 4.7 `context`(节点位置)
|
||||
|
||||
```xml
|
||||
<context>
|
||||
<node ptr="other_node_ptr">
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<expanded>0|1</expanded>
|
||||
</node>
|
||||
</context>
|
||||
```
|
||||
|
||||
### 4.8 `caches`
|
||||
|
||||
```xml
|
||||
<caches>
|
||||
<audio>uuid</audio>
|
||||
<video>uuid</video>
|
||||
<thumb>uuid</thumb>
|
||||
<waveform>uuid</waveform>
|
||||
</caches>
|
||||
```
|
||||
|
||||
### 4.9 `custom`
|
||||
节点自定义内容,默认实现为空;各子类可覆盖。
|
||||
|
||||
## 5. VideoParams
|
||||
`kVideoParams` 输入以子对象保存:
|
||||
|
||||
```xml
|
||||
<width>...</width>
|
||||
<height>...</height>
|
||||
<depth>...</depth>
|
||||
<timebase>num/den</timebase>
|
||||
<format>int</format>
|
||||
<channelcount>int</channelcount>
|
||||
<pixelaspectratio>num/den</pixelaspectratio>
|
||||
<interlacing>int</interlacing>
|
||||
<divider>int</divider>
|
||||
<enabled>0|1</enabled>
|
||||
<x>float</x>
|
||||
<y>float</y>
|
||||
<streamindex>int</streamindex>
|
||||
<videotype>int</videotype>
|
||||
<framerate>num/den</framerate>
|
||||
<starttime>int64</starttime>
|
||||
<duration>int64</duration>
|
||||
<premultipliedalpha>0|1</premultipliedalpha>
|
||||
<colorspace>string</colorspace>
|
||||
<colorrange>int</colorrange>
|
||||
```
|
||||
|
||||
## 6. AudioParams
|
||||
`kAudioParams` 输入以子对象保存:
|
||||
|
||||
```xml
|
||||
<samplerate>int</samplerate>
|
||||
<channellayout>uint64</channellayout>
|
||||
<format>string</format>
|
||||
<enabled>0|1</enabled>
|
||||
<streamindex>int</streamindex>
|
||||
<duration>int64</duration>
|
||||
<timebase>num/den</timebase>
|
||||
```
|
||||
|
||||
## 7. 部分保存
|
||||
序列化器支持写出部分数据:
|
||||
|
||||
- `<markers>`
|
||||
- `<keyframes>`
|
||||
- `<nodes>`(子集)
|
||||
|
||||
## 8. OpenFX 插件兼容
|
||||
|
||||
- OpenFX 节点 `id` 等于插件标识符。
|
||||
- `<plugins>` 记录插件路径,加载时会先扫描并注册插件节点。
|
||||
- 插件缺失时节点无法实例化并被跳过。
|
||||
|
||||
## 9. 版本兼容
|
||||
|
||||
- 根元素 `version` 决定使用哪个序列化器。
|
||||
- 若缺少对应版本,会报 `kProjectTooNew` 或 `kProjectTooOld`。
|
||||
@@ -0,0 +1,168 @@
|
||||
Oak Video Editor 项目结构概览(中文)
|
||||
==========================
|
||||
|
||||
这份文档是基于当前仓库目录组织的快速导航,便于后续查找代码位置。
|
||||
|
||||
顶层目录
|
||||
--------
|
||||
- app: 主应用源码入口,涵盖核心、渲染、UI、插件、节点系统等。
|
||||
- cmake: CMake 相关脚本与模块。
|
||||
- docker: 构建/运行相关的容器配置。
|
||||
- docs: 项目文档(你现在正在看的位置)。
|
||||
- ext: 可能包含外部依赖或子模块(按需查看)。
|
||||
- tests: 测试代码与用例。
|
||||
- third_party: 第三方库及其源码(如 OpenFX HostSupport)。
|
||||
- build、cmake-build-debug、test_compile: 构建产物或构建目录(通常不需要手动改)。
|
||||
|
||||
app 目录(核心模块)
|
||||
-------------------
|
||||
- app/core.*: 应用核心入口、初始化流程。
|
||||
- app/main.cpp: 程序入口点。
|
||||
- app/version.*: 版本信息与构建元数据。
|
||||
- app/common: 通用基础设施与工具类(日志、路径、字符串等)。
|
||||
- app/config: 配置加载与项目设置。
|
||||
- app/render: 渲染子系统(帧缓存、渲染管线、插件渲染桥接等)。
|
||||
- app/node: 节点系统,节点类型与图结构的核心逻辑。
|
||||
- app/widget: UI 控件与节点视图(节点图、参数面板等)。
|
||||
- app/panel: UI 面板组织与管理。
|
||||
- app/window: 窗口与主界面。
|
||||
- app/timeline: 时间线与剪辑管理。
|
||||
- app/tool: 交互工具(选择、裁剪等)。
|
||||
- app/undo: 撤销/重做系统。
|
||||
- app/task: 异步任务与后台作业。
|
||||
- app/audio: 音频处理与播放。
|
||||
- app/codec: 编解码相关支持。
|
||||
- app/shaders: 渲染着色器资源。
|
||||
- app/ts: 时间/时间轴相关通用类型。
|
||||
- app/dialog: 对话框与提示类 UI。
|
||||
- app/cli: 命令行工具入口或相关实现。
|
||||
- app/pluginSupport: OpenFX 插件 Host 侧实现(Clip/Image/Param/Host/PluginInstance 等)。
|
||||
- app/packaging: 打包或发布相关逻辑。
|
||||
|
||||
重点文件索引(按模块)
|
||||
----------------------
|
||||
下面列的是“常用/核心入口”文件,不是完整清单,但足够定位主要流程。
|
||||
|
||||
核心入口与全局
|
||||
-------------
|
||||
- app/main.cpp: 程序入口。
|
||||
- app/core.h、app/core.cpp: 应用生命周期与初始化总控。
|
||||
- app/version.h、app/version.cpp: 版本与构建信息。
|
||||
|
||||
渲染系统
|
||||
--------
|
||||
- app/render/renderer.h、app/render/renderer.cpp: 渲染主调度。
|
||||
- app/render/rendermanager.h、app/render/rendermanager.cpp: 渲染队列与任务管理。
|
||||
- app/render/renderticket.h、app/render/renderticket.cpp: 单次渲染请求。
|
||||
- app/render/renderprocessor.h、app/render/renderprocessor.cpp: 渲染处理管线。
|
||||
- app/render/texture.h、app/render/texture.cpp: 纹理/帧数据容器。
|
||||
- app/render/videoparams.h、app/render/videoparams.cpp: 视频格式参数。
|
||||
- app/render/job/pluginjob.h、app/render/job/pluginjob.cpp: 插件渲染作业。
|
||||
- app/render/plugin/pluginrenderer.h、app/render/plugin/pluginrenderer.cpp: OpenFX 插件渲染桥接。
|
||||
|
||||
节点系统
|
||||
--------
|
||||
- app/node/node.h、app/node/node.cpp: 节点基类与生命周期。
|
||||
- app/node/param.h、app/node/param.cpp: 节点参数与动画/关键帧。
|
||||
- app/node/value.h、app/node/value.cpp: 节点值与运行时数据。
|
||||
- app/node/factory.h、app/node/factory.cpp: 节点注册与创建。
|
||||
- app/node/traverser.h、app/node/traverser.cpp: 图遍历与求值。
|
||||
- app/node/plugins/Plugin.h、app/node/plugins/Plugin.cpp: OpenFX 插件节点。
|
||||
|
||||
OpenFX Host 侧实现
|
||||
------------------
|
||||
- app/pluginSupport/OliveHost.h、app/pluginSupport/OliveHost.cpp: OpenFX Host 入口与消息接口。
|
||||
- app/pluginSupport/OlivePluginInstance.h、app/pluginSupport/OlivePluginInstance.cpp: 插件实例生命周期与参数管理。
|
||||
- app/pluginSupport/OliveClip.h、app/pluginSupport/OliveClip.cpp: Clip 实例与图像读写桥接。
|
||||
- app/pluginSupport/image.h、app/pluginSupport/image.cpp: OpenFX Image 封装与数据映射。
|
||||
- app/pluginSupport/paraminstance.h、app/pluginSupport/paraminstance.cpp: 参数实例实现。
|
||||
- third_party/openfx/HostSupport/include/ofxhImageEffect.h: HostSupport 核心接口。
|
||||
|
||||
节点 UI(Node View)
|
||||
-------------------
|
||||
- app/widget/nodeview/nodeview.h、app/widget/nodeview/nodeview.cpp: 节点视图主控。
|
||||
- app/widget/nodeview/nodeviewitem.h、app/widget/nodeview/nodeviewitem.cpp: 节点渲染与交互。
|
||||
- app/widget/nodeview/nodeviewscene.h、app/widget/nodeview/nodeviewscene.cpp: QGraphicsScene 逻辑。
|
||||
- app/widget/nodeview/nodeviewedge.h、app/widget/nodeview/nodeviewedge.cpp: 连线显示。
|
||||
|
||||
参数 UI(Param View)
|
||||
--------------------
|
||||
- app/widget/nodeparamview/nodeparamview.h、app/widget/nodeparamview/nodeparamview.cpp: 参数面板主控。
|
||||
- app/widget/nodeparamview/nodeparamviewitem.h、app/widget/nodeparamview/nodeparamviewitem.cpp: 参数项容器与布局。
|
||||
- app/widget/nodeparamview/nodeparamviewwidgetbridge.h、app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp: 参数类型到控件的桥接。
|
||||
- app/widget/nodeparamview/nodeparamviewtextedit.h、app/widget/nodeparamview/nodeparamviewtextedit.cpp: 多行文本参数控件。
|
||||
|
||||
面板与窗口
|
||||
----------
|
||||
- app/panel/panelmanager.h、app/panel/panelmanager.cpp: 面板管理器与切换逻辑。
|
||||
- app/panel/timebased/timebased.h、app/panel/timebased/timebased.cpp: 时间基面板基类(时间轴/视图共享逻辑)。
|
||||
- app/panel/node/node.h、app/panel/node/node.cpp: 节点面板入口。
|
||||
- app/panel/param/param.h、app/panel/param/param.cpp: 参数面板入口。
|
||||
- app/window: 主窗口与窗口级 UI 结构。
|
||||
|
||||
时间线/播放核心
|
||||
--------------
|
||||
- app/node/output/viewer/viewer.h、app/node/output/viewer/viewer.cpp: Viewer 输出节点(播放头/长度/渲染请求)。
|
||||
- app/widget/viewer/viewer.h、app/widget/viewer/viewer.cpp: Viewer 面板与播放控制。
|
||||
- app/widget/timelinewidget/timelinewidget.h、app/widget/timelinewidget/timelinewidget.cpp: 时间线 UI 与交互主控。
|
||||
|
||||
进度与任务 UI
|
||||
------------
|
||||
- app/dialog/progress/progress.h、app/dialog/progress/progress.cpp: 通用进度对话框。
|
||||
- app/widget/taskview/taskviewitem.h、app/widget/taskview/taskviewitem.cpp: 任务进度条展示。
|
||||
|
||||
撤销/编辑分组
|
||||
------------
|
||||
- app/undo/undocommand.h、app/undo/undocommand.cpp: UndoCommand 与 MultiUndoCommand 的基础实现。
|
||||
- app/undo/undostack.h、app/undo/undostack.cpp: 撤销栈(无原生“批量编辑”接口)。
|
||||
- app/pluginSupport/OlivePluginInstance.h、app/pluginSupport/OlivePluginInstance.cpp: OpenFX editBegin/editEnd 触发时创建批量撤销分组。
|
||||
- app/pluginSupport/OlivePluginInstance.cpp: DeferredRedoCommand 包装已应用的命令,避免批量 push 时重复执行。
|
||||
- app/pluginSupport/paraminstance.h、app/pluginSupport/paraminstance.cpp: 参数 Set 走统一的 SubmitUndoCommand 接口,支持批量合并。
|
||||
|
||||
与 OpenFX 相关的主要位置
|
||||
-----------------------
|
||||
- app/pluginSupport: OpenFX HostSupport 的封装与 Olive 侧实现。
|
||||
- app/render/plugin: 插件渲染调度与帧处理逻辑。
|
||||
- app/node/plugins: 插件节点定义与 UI 参数桥接。
|
||||
- third_party/openfx: OpenFX HostSupport 源码与接口头文件。
|
||||
|
||||
构建与配置
|
||||
----------
|
||||
- CMakeLists.txt: 根构建配置入口。
|
||||
- cmake/: 自定义 CMake 模块与工具链脚本。
|
||||
|
||||
其他说明
|
||||
--------
|
||||
- README.md: 项目整体说明与开发入口。
|
||||
- TODO-zh.md: OpenFX 支持的中文 TODO 说明。
|
||||
|
||||
流程图/调用关系(ASCII)
|
||||
-----------------------
|
||||
OpenFX 插件渲染主流程(逻辑简化):
|
||||
```
|
||||
Node(Graph)
|
||||
-> app/node/plugins/Plugin.cpp
|
||||
-> app/render/plugin/pluginrenderer.cpp
|
||||
-> app/pluginSupport/OlivePluginInstance.cpp
|
||||
-> app/pluginSupport/OliveClip.cpp
|
||||
-> app/pluginSupport/image.cpp
|
||||
-> app/render/texture.cpp / AVFrame 映射
|
||||
```
|
||||
|
||||
OpenFX 参数 UI 生成流程(逻辑简化):
|
||||
```
|
||||
OFX Param Descriptor
|
||||
-> app/pluginSupport/OlivePluginInstance.cpp (newParam)
|
||||
-> app/node/plugins/Plugin.cpp (Node Input 生成)
|
||||
-> app/widget/nodeparamview/nodeparamview.cpp
|
||||
-> app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp (控件桥接)
|
||||
```
|
||||
|
||||
插件消息展示流程(逻辑简化):
|
||||
```
|
||||
OFX Host Message
|
||||
-> app/pluginSupport/OliveHost.cpp (保存消息)
|
||||
-> app/pluginSupport/OlivePluginInstance.cpp (发出消息数量变化)
|
||||
-> app/widget/nodeview/nodeviewitem.cpp (节点右上角徽标)
|
||||
-> app/widget/nodeparamview/nodeparamviewitem.cpp (面板顶部消息)
|
||||
```
|
||||
@@ -0,0 +1,93 @@
|
||||
# Oak Video Editor 测试策略与计划
|
||||
|
||||
本文档描述 Oak Video Editor 的自动化测试策略,包括单元测试、集成测试以及 CI 执行方式。
|
||||
|
||||
## 目标
|
||||
|
||||
- 尽量自动化,减少人工测试。
|
||||
- 覆盖所有模块(至少一个自动化测试)。
|
||||
- 集成测试保持无 GUI(头less)。
|
||||
- 在 Windows/macOS/Linux 上可重复运行。
|
||||
|
||||
## 测试层级
|
||||
|
||||
### 1) 单元测试(GoogleTest)
|
||||
- 目标:小范围、确定性、无 GUI。
|
||||
- 目录:`tests/gtest/`。
|
||||
- 执行:`ctest` 里的 `olive-gtest`。
|
||||
|
||||
### 1.5) 模块冒烟测试(GoogleTest)
|
||||
- 目标:对 GUI 相关模块做编译期/链接期覆盖,不实例化控件。
|
||||
- 目录:`tests/gtest/module_smoke_test.cpp`。
|
||||
- 执行:`ctest` 里的 `olive-gtest`。
|
||||
|
||||
### 2) 集成测试(GoogleTest)
|
||||
- 目标:跨模块流程但不依赖 GUI(例如序列化→反序列化)。
|
||||
- 目录:`tests/gtest/`(如 `ProjectSerializer`、`TaskManager`)。
|
||||
|
||||
### 3) 现有测试(Olive 宏测试)
|
||||
- 目录:`tests/general`、`tests/timeline`、`tests/compositing` 保持不变。
|
||||
|
||||
## 模块覆盖映射
|
||||
|
||||
每个顶层模块至少有一个测试用例。
|
||||
|
||||
- `app/common`:`common_current_test.cpp`、`common_xmlutils_test.cpp`
|
||||
- `app/config`:`config_test.cpp`
|
||||
- `app/node`:`node_value_test.cpp`、`node_keyframe_test.cpp`、`node_serialization_test.cpp`
|
||||
- `app/node/project/serializer`:`project_serializer_test.cpp`
|
||||
- `app/render`:`render_videoparams_test.cpp`、`render_audioparams_test.cpp`
|
||||
- `app/timeline`:`timeline_marker_test.cpp`
|
||||
- `app/undo`:`undo_stack_test.cpp`
|
||||
- `app/task`:`task_taskmanager_test.cpp`
|
||||
- `app/codec`:`codec_frame_test.cpp`
|
||||
- `app/pluginSupport`:`plugin_support_test.cpp`
|
||||
- `app/audio`、`app/cli`、`app/dialog`、`app/panel`、`app/tool`、`app/ui`、`app/widget`、`app/window`:`module_smoke_test.cpp`
|
||||
|
||||
若模块包含 GUI 依赖,则测试聚焦于其非可视逻辑/数据结构。
|
||||
|
||||
## 集成测试说明
|
||||
|
||||
### 项目序列化回归
|
||||
- 创建最小项目并添加内置节点。
|
||||
- 使用 `ProjectSerializer::Save` 写出 XML。
|
||||
- 再用 `ProjectSerializer::Load` 读回。
|
||||
- 验证节点恢复。
|
||||
|
||||
### 任务管理器执行
|
||||
- 向 `TaskManager` 添加一个 DummyTask。
|
||||
- 使用事件循环等待完成。
|
||||
- 验证任务确实执行。
|
||||
|
||||
## 单元覆盖重点(已扩展)
|
||||
|
||||
- `app/undo`:`undo_stack_test.cpp` 覆盖空栈状态、模型数据、redo 区域颜色、jump 行为、空 MultiUndoCommand 忽略逻辑。
|
||||
- `app/timeline`:`timeline_marker_test.cpp` 覆盖列表排序、最近 marker 查询、含未知元素的保存/加载、marker 增删改命令。
|
||||
- `app/pluginSupport`:`plugin_support_image_test.cpp` 覆盖 OFX 属性映射(bounds/ROD、像素深度、通道、预乘)及分配/清理行为。
|
||||
- `app/render`:`render_videoparams_branch_test.cpp` 覆盖自动 divider、像素宽高比校验、方形像素宽度、Save/Load 回归。
|
||||
|
||||
## 无 GUI 运行
|
||||
|
||||
- 测试避免使用 QWidget。
|
||||
- CI 中设置 `QT_QPA_PLATFORM=offscreen` 防止 GUI 初始化问题。
|
||||
|
||||
## 持续集成
|
||||
|
||||
CI 在 Windows/macOS/Linux 上执行:
|
||||
|
||||
1. 安装依赖(Qt、FFmpeg、OpenImageIO、OpenColorIO、OpenEXR、PortAudio、Expat)。
|
||||
2. `-DBUILD_TESTS=ON` 配置。
|
||||
3. 使用 CMake + Ninja 构建。
|
||||
4. 运行 `ctest` 输出失败信息。
|
||||
|
||||
### 依赖安装说明
|
||||
- Linux:优先使用发行版系统包(Ubuntu 上用 `apt`)安装 Qt6、FFmpeg、OpenImageIO、OpenColorIO、OpenEXR、PortAudio、Expat、OpenGL 头文件。
|
||||
- macOS:使用 Homebrew 安装 Qt6 和图像/色彩/多媒体相关库。
|
||||
- Windows:尽量使用系统安装器(Qt 通过 `install-qt-action`),其余 C/C++ 库通过 vcpkg 安装。
|
||||
|
||||
## 新增测试规范
|
||||
|
||||
- 新测试放在 `tests/gtest`。
|
||||
- 使用 GoogleTest 规范。
|
||||
- 尽量保持确定性与无外部依赖。
|
||||
- 新模块至少增加 1 个单元测试 + 1 个集成场景(可合并)。
|
||||
Reference in New Issue
Block a user