- riir.md: split project file read/write into standalone oakstorage
module (pluggable backend, DB-replaceable); add Mermaid data flow
diagram of all modules; adjust batch table and milestones
- riir/04-interfaces.md: new provides/consumes contract matrix for
all modules
- riir/M10-oakstorage.md: new manual with frozen C API (typed opaque
handles, manual vtable for storage backends, URI addressing)
- riir/01: codify pure-C OO interface rules (typed handles instead of
void*, init/free pairs, manual vtables, no C++ objects or member
calls across shared library boundaries); upper layers issue commands
only, no module-to-module event subscriptions (async task callbacks
excepted)
- sync 00/02/03 and M2-M9 manuals: remove subscribe APIs, replace
void* with typed handles, update tests accordingly
New app/playback/playbackcontroller.{h,cpp}: a lazily created
process-wide singleton whose set_playhead() forwards to
oakengine_viewer_set_playhead and re-broadcasts playhead_changed as a
plain Qt signal. Every app-side oakengine_viewer_set_playhead call site
(17 across viewer, timelinewidget, timelineview, import tool,
timebasedwidget, keyframecontrol, export dialog, mainwindow) now goes
through it.
Migrate the first four playhead subscribers off the raw C event
subscription / EngineEventBridge to the controller signal:
- TimeBasedView (issue 1)
- NodeParamViewWidgetBridge (issue 2)
- NodeParamViewKeyframeControl (issue 3)
- NodeParamViewConnectedLabel (issue 4)
Each stores a QMetaObject::Connection filtered on its viewer node and
disconnects on teardown; the viewer_sub_ members are gone. Plan docs
mark issues 0c and 1-4 as done.
Closes#30, closes#31, closes#32, closes#51, closes#52.
Compiler hygiene (all platforms):
- Silence warnings across the tree: missing override, -Wreorder ctor
init, -Wshadow, -Wsign-compare, missing switch cases, unused
functions/captures, Qt 6.11 deprecations (QMouseEvent/QDropEvent
accessors, qAsConst, Q_FOREACH over non-shared containers,
AA_UseHighDpiPixmaps) and the .bak/ backup tree removal.
- Fix regressions from the cleanup: missing clip decls in
capi/timeline.cpp, plugin.cpp rename fallout, panel setFocus
ambiguity, QGraphicsItem::pos vs event->position(), duplicate
k_push_button case, boolean test variable.
Windows:
- Qt portability: CommandLineParser is_set/add_option, QTimeZone
systemTimeZone (QTimeZone::LocalTime is 6.11-only), k_progress_* enum.
- Linking: stop adding oakengine to OLIVE_LIBRARIES (import lib plus
oakengine-obj caused multiple definitions); add OAKENGINE_STATIC so
internal consumers no longer reference __imp_* stubs.
- oakengine.ver: export olive::Renderer typeinfo so liboakgl.so can be
dlopened (Linux), DynamicRenderer no longer dlcloses backend libraries
(crash in RenderManager's dtor calling into unmapped memory).
- OTIO runtime: copy DLLs next to every binary on Windows instead of
relying on PATH (0xc0000135 in gtest discovery).
- Headless GL: the runner only has GDI OpenGL 1.1, killing every render
worker. Deploy Mesa llvmpipe as opengl32sw.dll (Qt's software-GL
channel) with QT_OPENGL=software, and let QT_OPENGL override the
AA_UseDesktopOpenGL default. ExportTask fails fast after 8 consecutive
undelivered frames instead of segfaulting or grinding forever;
FFmpegEncoder::write_frame tolerates null frames.
- Tests: GetTempPathA+PID temp dirs, GetLongPathNameA for 8.3 names,
forward-slash normalization when comparing project filenames.
Linux:
- Install libshaderc-dev so oakvulkan compiles GLSL (Vulkan tests).
- Accept UNORM floor-or-round (63/64) in the blit ping-pong test.
- Skip MainWindow construction test on the offscreen QPA (cannot paint
QOpenGLWidget).
Also: oak_cli_transcode gets a 300s ctest timeout, worker logs GL
context version and LoadGraph/render_frame stages, and
docs/plans/eliminate-event-bridge-issues.md (English translation).
- capi: oakengine_node_output_connection_at/_at_ex returned the source
node as the connection destination; the actual destination is
conn.second.node(). Out-edge enumeration was useless, so the node
view could only draw in-edges and randomly lost whichever edges
needed the out-edge path (random per context build order).
Regression test in oakengine_node_test
- project teardown: Project::clear() pre-notifies node removal while
nodes are fully constructed (observers used to crash on
half-destroyed nodes); childEvent suppresses the removal dance while
clearing; Node::disconnect_all/disconnect_edge get a silent mode for
teardown so no invalidation/events touch dying members
(is_being_cleared); ClipBlock marker disconnect guarded against
dead viewer/markers; ProjectCopier and PreviewAutoCacher drop
project references on Project::destroyed instead of disconnecting
dead objects at shutdown
- preview: add oakengine_preview_request_get_audio_sample_count; the
viewer queried sample count by passing nullptr to get_audio_samples
which rejects it, so all playback audio was silently dropped
- app: fix unterminated input-id memcpy in ResolveGroupInput
(nodeparamviewitem, widgetbridge) that corrupted every parameter id
- app: unsubscribe raw C-API event subscriptions in destructors of
NodeParamViewKeyframeControl, NodeParamViewConnectedLabel and
ExportDialog; playhead events used to fire into dead widgets
(crash when dragging the playhead)
- tests: preview request roundtrip (video frame + audio range) and
free-while-active teardown coverage; env-gated OAK_DEBUG_EDGES /
OAK_DEBUG_INVALID_INPUT diagnostics
- docs: investigation notes in docs/zh/
- app/ no longer includes engine C++ headers nor holds engine C++ types:
engine access goes through the oakengine C ABI plus C++ wrappers
(oakutil/oaknode.h, oakutil/oakvideo.h) and app-local mirror types
(tooltypes, trackreferencehandle, timelinecommonapp, keyframetypes,
subtitleapp, serializedlayoutinfoapp, nodevaluehandle, sliderdisplaytypeapp)
- engine: new C ABI functions for block/track/clip/transition navigation
and predicates, links, caches, waveform/playback, disk folder,
sequence_track_list, node_free, footage_is_valid, block_get_track,
get_brush; loadotio/saveotio ported to the current engine API
- OTIO is now a required dependency: CI and CD build it on every
platform, FindOpenTimelineIO fixed for OTIO 0.16/0.19 (the old deps
include requirement silently disabled OTIO everywhere), runtime
libraries are bundled into packages and copied next to macOS binaries
(oak_copy_otio_runtime)
- fix ProjectViewModel drag&drop mime read/write size mismatch (segfault)
- unify color label naming (k_olive -> "Oak") in the app-side mirror
- docs: OTIO required, FFmpeg minimum corrected to 6.0 (en/zh)
- gtest suite: 1925 passed, 0 failed
Move the pure-header utilities shared by app/ and engine/ out of
engine/common/ into a new shared/include/oakutil/ layer (define, lerp,
decibel, digit, range, crashpadutils, autoscroll, qtutils, filefunctions
declarations, and a trimmed xmlutils exposing a CancelAtom-free void*
overload). engine/common/ keeps forwarding headers so internal include
paths are unchanged; app/ now includes oakutil/* directly.
engine/node/project.h gains an explicit NodeGroup forward declaration
previously obtained transitively through the old xmlutils.h.
Move the finished migration campaign docs (handoffs v3-v6, roadmap,
R5 guides, R6 cleanup, R7 pure-ABI) from docs/zh/ into
docs/zh/plans/completed/ with an archive README; fix all
cross-references; refresh plans/README.md index (active plans now
marked unlocked).
R7-A (Qwen 3.8 Max): oakengine/display.h rewritten to the POD contract
from r7-pure-abi-plan.md - oak_video_params everywhere, opaque
texture/frame handles with retain/free protocol (engine-heap control
blocks), OakSharedBuffer refcounted wrapper for the QVariant playback
path. All TexturePtr/FramePtr gone from app (47 sites).
R7-B (Qwen 3.8 Max): liboakengine.so exports 3486 -> 19 C++ symbols
(version script oakengine.ver: oakengine_* plus the documented
oakgl/oakvulkan dlopen plugin ABI). oakengine-obj OBJECT library feeds
both the shared lib and the test binaries (-rdynamic so dlopen'd
backends resolve engine objects).
Fix (Kimi K3): producer/consumer type mismatch - viewerdisplay
unpacks OakSharedBufferPtr but viewer.cpp pushed raw void* handles,
so no frame ever reached the display widget (all 5 vulkan viewer
tests timed out with 'never received a texture'). Producers now wrap
with oak_make_shared_frame / oak_make_shared_texture(retain).
Verified: build 0 errors, ctest 45/45, nm U _ZN5olive = 0 in
oak-editor/oak-render-worker/oak-cli, 19 exported C++ symbols in
liboakengine.so (all documented plugin ABI).
Complete documentation set for the facade migration (B1-R6) and beyond:
facade-migration-roadmap, handoffs v3-v6, R5 guides, R6 cleanup plan,
R7 pure-ABI plan, long-term plans (riir/ai-agent/gtest/ui-redesign),
updated Chinese README draft, UI design mockups, and the Google Test +
struct-typedef rules in CONTRIBUTING.
- media color primaries/transfer tags now flow from the FFmpeg probe
through VideoParams into Footage::get_colorspace_to_use(); precedence
is user override > media tags > project default
- export nclc tags derive from the output colorspace (PQ/HLG/BT.2020,
P3, sRGB, Rec.601, Rec.709) instead of hardcoded BT.709
- new OCIO Color Grading (Log) node (lift/gamma/gain) and White Balance
node (kelvin temperature + tint, HDR-safe)
- LUT whitelist extended to 9 OCIO-supported formats
- waveform scope gains an RGB parade mode (GPU and software paths)
- tests updated for the new colorspace precedence
- FootageJob::should_use_proxy() centralizes the proxy decision; worker
pre-decode now honors the render mode so exports always decode the
original media (previously every frame was pre-decoded from proxies)
- global Tools > Use Proxy Media toggle with footage invalidation
- ffmpeg -progress parsing for real percentage feedback while generating
- divider mode (1/2, 1/4, 1/8 of source resolution) with UI, proxy
filename tags and per-footage persistence (pdivider)
- Media Offline warning slat rendered for missing footage
- regression tests: export isolation, relink invalidation, offline slat,
progress parsing, divider arguments
- Linux CD builds no longer disable Vulkan: the AppImage, deb, rpm and
Arch packages now build and ship liboakvulkan (the AppImage deploys
it via linuxdeploy --library so libvulkan is bundled too, and the
verify step checks both backend libraries); deb/rpm dependencies gain
libvulkan1/vulkan-loader; the Arch PKGBUILD gains vulkan-headers
- macOS CD installs vulkan-loader and exports VULKAN_SDK so
find_package(Vulkan) locates the Homebrew loader (previously the
Vulkan backend silently never built there)
- ffmpeg_bridge now installs to the standard lib directory with
/../lib RPATH instead of the non-standard ffmpeg_bridge/bin
layout (verified: editor, worker, oakgl and oakvulkan all resolve it)
- build guides (EN/ZH) document the macOS Vulkan backend dependencies
and the VULKAN_SDK variable
- File inputs marked with the 'lut_library' property (currently the
OCIO LUT node) now show a combo box populated from the global LUT
library above the path field: pick a library LUT directly, or use
'Other (Custom File)...' with the regular path field; selections go
through the standard undoable input-change path
- Refresh zh_CN translations with lupdate and translate all strings
introduced by the proxy dialog, LUT library, LUT picker, waveform
sync and footage start time work
- Document the new per-footage custom <proxy> attributes and the
'manual' source-start-time origin in the project file reference
- Add LutFileField UI tests
- Rename macOS bundle output from Olive.app to Oak.app.
- Rename editor binary to oak-editor and render worker to oak-render-worker.
- Rename crash handler output to oak-crashhandler.
- Update worker lookup, NSIS installer, Linux desktop/AppRun, crashhandler
symbol paths, and documentation for the new binary names.
- Update CD workflow paths and add -qmldir flags to macdeployqt so QtQuick
/ QML plugins required by KDDockWidgets are bundled, fixing the launch
crash on macOS.
- Update user-facing GitHub URLs to OakVideoEditorCommunity/oak.
- English and Chinese build.md now list macOS as a fully supported
platform and point to the dedicated macOS build guide.
- Chinese build.md Fedora dependency list synced with English: use
ffmpeg-free-devel and add bzip2-devel.
- Update CI badge URL to OakVideoEditorCommunity in README.
- Remove outdated TODO files, vcpkg.json, patch file and stale log.
- Clean up obsolete docs and move ofx-pluginrenderer-functions-zh.md
into docs/zh/.
Expand docs/project-file-reference.md to cover the full .ove format
implemented in the current codebase, including:
- Root document and project container structure
- Project data: uuid, plugins, nodes, settings
- Detailed Node serialization (inputs, keyframes, connections, hints,
context, caches)
- Node-specific custom data: Footage proxy/sourcestarttime, ViewerOutput
workarea/markers, Track height, NodeGroup passthroughs
- VideoParams and AudioParams field lists
- MainWindowLayoutInfo layout block
- Partial documents (markers, keyframes, nodes/timeline)
- Versioning and OpenFX notes
All sections are provided in English with Chinese translations.
- Document that Vulkan now passes an end-to-end upload/blit/download test
on real hardware.
- List recently landed fixes: shared vertex/fragment UBO, descriptor set
layout, render pass dependencies, image layout transitions, framebuffer
and sampler caching, grayscale swizzle, texture-enable uniforms.
- Add remaining gaps: iterative/pin-pong multi-pass Blit, 1/3-channel
upload/download alignment, and full viewer/proxy/export smoke tests.
- dynamic plan: mark that RenderManager::backend() now syncs with
DynamicRenderer's actual loaded backend after internal fallback.
- manual test plan: add checks in 10.2/10.3 that RenderManager reports
the actual runtime backend (OpenGL after Vulkan fallback).
No code changes; ctest passes 4/4.
- Add PickRenderableFormat / IsColorAttachmentSupported so 3-channel
Vulkan formats fall back to 4-channel when unsupported.
- Make oakvulkan target and C ABI check conditional on Vulkan_FOUND;
skip liboakvulkan build/dependencies when Vulkan headers/libs are
absent.
- Update Preferences tooltip to reflect Vulkan is an experimental
prototype that may fall back to OpenGL.
- Revise dynamic backend plan doc: phase 3/4/5 described as prototype
frameworks with runtime validation pending, and list recent Vulkan
fixes (init idempotency, descriptor/sampler lifetime, dynamic
viewport/scissor, render pass clear, format probing).
Both OAK_ENABLE_DYNAMIC_RENDER_BACKEND=ON and OFF configurations
build and pass ctest (4/4).
- Extract libolive-rendercore static library to minimize backend link boundary.
- Add DynamicRenderer adapter with C ABI (oakgl/oakvulkan shared libs).
- Make OAK_ENABLE_DYNAMIC_RENDER_BACKEND default ON with OpenGL fallback.
- Implement VulkanRenderer prototype (textures, shaders, UBO blit, readback).
- Add backend-neutral viewer readback path (offscreen -> QImage -> QPainter).
- Refactor PluginRenderer to be renderer-agnostic; OFX plugins fall back to CPU
path on non-OpenGL backends while preserving OpenGL render path.
- Add Renderer::AttachOutputTexture/DetachOutputTexture and C ABI forwards.
- Update docs/zh/render-backend-dynamic-plan.md for Phase 3/4/5.