Commit Graph
7 Commits
Author SHA1 Message Date
Mike-Solar 06f47235b2 feat(engine,app): source-monitor frames + real audio meter
source monitor:
- new facade exports oakengine_renderer_create_for_node (render any
  node, not just sequences) and oakengine_project_footage_at (fetch a
  footage node by index); it_render covers the e2e render plus the
  NULL/illegal matrix
- RealEngine renders the selected footage's real frames to the source
  viewer (per-node renderer slot, frame cache invalidated on selection
  change, synthetic fallback kept)
- known gap (documented): pixels stay transparent black until
  oakrender's footage decode hook lands — the render surface itself is
  real end to end

audio meter:
- oakaudio manager can now report per-channel linear peaks of the
  buffered output (PreviewAudioDevice::peek_tail + levelmeter analysis
  of the newest 8192 frames, packed/planar F32)
- new facade export oakengine_audio_output_levels (negative codes pass
  through); RealEngine's AudioMeterDataSource reads it instead of
  returning hardcoded silence
- tests: module peak readback + facade validation/readback matrix
2026-08-12 14:19:18 +08:00
Mike-Solar 18ff60f147 feat(engine): clip move, clip effect_input, mandatory static FFmpeg
- oakengine_sequence_move_clip implemented for real (oaktimeline
  TrackMoveBlockCommand; fixes the graph-ownership/gap-anchor/ripple
  trim bugs the stub was hiding); same-track via the frozen C ABI,
  cross-track supported by the module command
- oaknode clip blocks now declare a tex_in texture input and set
  effect_input to it, so timeline clips can host effect chains; facade
  test covers effect insert/remove on a real clip
- oakffmpeg-link: FFMPEG_DIR is now mandatory with a clear panic (a
  Homebrew upgrade left the system ffmpeg .pc pointing at a deleted
  dav1d Cellar path, breaking links); reads a git-ignored workspace
  .env for IDEs that cannot inject env vars (RustRover); links the C++
  stdlib for C++ codec libs (svt-av1)
- oakengine re-exports oaknode so tests share one crate instance;
  it_node uses the direct instance's value type where it calls the
  module FFI (the --workspace dev-dependency feature split builds
  oaknode twice)
2026-08-11 23:04:48 +08:00
Mike-Solar cdda643d64 feat(engine,app): effect chain facade + app effect stack wiring
facade (oakengine/oaknode, API only extended):
- oaknode_node_get_effect_input / oaknode_node_get_flags module exports
- oakengine_clip_as_node, oakengine_node_effect_count/at/insert/remove/
  move/set_enabled, oakengine_node_identity/is_enabled/get_type_id,
  oakengine_node_factory_id_at — chain edits wrap disconnect/reconnect
  into single undo groups; insert/move/remove validated against the
  factory and the host's effect input
- it_node covers enumeration/insert/remove/move/toggle/undo-redo and
  the NULL/illegal-input matrix

app:
- RealEngine binds the selected clip's effect chain to the inspector's
  effect stack (cards, enable, reorder, remove, expansion state), all
  edits undoable through the facade
- AppEngine gains set_selected_clips / addable_effects / add_effect
  (default no-ops keep the mock untouched); the timeline selection
  drives the stack target; the inspector gets a small add-effect menu
- known module gap (documented): ClipBlockBehavior sets no effect_input
  yet, so timeline clips cannot host effects until oaknode grows tex_in
2026-08-11 20:04:44 +08:00
Mike-Solar 26009a5ea5 refactor(oakaudio): drop ffmpeg_bridge fb_* imports, call ffmpeg-next in-process
- processor.rs: resample/channel-convert/time-stretch now runs an
  in-process FFmpeg filter graph (abuffer -> atempo -> aformat ->
  abuffersink) via ffmpeg-next
- waveform.rs: extraction decodes through oakcodec's FFmpegDecoder
  (interleaved f32) instead of the fb_decoder/fb_audio_graph pair
- bridge/ffmpeg.rs and the null fb_* test stubs deleted;
  oakcommon::ffmpegutils bridge constants become plain ints
- liboakengine.dylib no longer imports any fb_* symbol (nm -u clean);
  the remaining runtime imports are the host-provided oakcore_* symbols
- real decode/resample tests added (generated PCM input, no network)
2026-08-11 16:10:14 +08:00
Mike-Solar aa5fcef66e fix(oakengine): facade bugs found by integration tests
undo:
- NULL/empty label no longer crosses to oakundo as a dangling 0x1
  pointer (push, group_begin/end) — fixed SIGSEGV
- group_abort now undoes each executed child in reverse order

task:
- create_project_import addrefs the borrowed project handle instead of
  freeing it under the async task — fixed UAF/SIGSEGV

timeline:
- toggle_enabled/delete_clips guard NULL+0 slices — fixed SIGABRT
- BlockSplitCommand halves placed correctly (oaktimeline undosplit)
- PreservingLinks / ripple remove / ripple delete-gaps commands
  self-prepare on first redo — fixes silent no-op split/ripple
- trim_clips_to targets the block containing the point, not the track
- delete_empty_tracks applies the live track removal
- ripple facades no longer free borrowed track handles still referenced
  by commands — fixed UAF

node:
- project_add_node releases the factory handle — fixes per-call leak
- inputs_from(recursive=0) matches direct feeders (BFS off-by-one)
- group passthrough id/resolve treat two-stage string length as success
- node_connect(_command) reject duplicate connects with E_STATE
- folder_add_child enforces one-folder-per-node
- value_split_to_tracks splits vector/color per component
- set_context_position/expanded establish the first entry
- node_get_flags on an empty box returns 0, not u64::MAX
- footage_borrow addrefs its wrapper — fixes double-free

render:
- renderer_create rejects invalid pixel formats (real range check)
- render_frame forwards renderer width/height to the ticket

tests: repro #[ignore]s removed, bug-behavior assertions corrected,
it_undo global-stack tests serialized with a shared lock
2026-08-11 01:30:18 +08:00
Mike-Solar 3110e5cc3a test(oakengine): rename integration test families to English names
it_*族.rs -> it_audio/codec/common/node/plugin/render/task/timeline/undo.rs;
also fixes a pre-existing racy assertion in it_task.
2026-08-11 00:24:57 +08:00
Mike-Solar 013a175707 refactor: workspace layout — crates/, app at root, legacy C++ removed
Single mechanical restructure commit:
- root Cargo.toml = oakapp bin + workspace; one cargo build produces
  oakapp, oak-cli, oak-worker, liboakengine.dylib
- app/rust/src -> src/ (app at repo root, no rust/ nesting)
- src/<mod>/rust -> crates/oak<mod>; src/oakcore-rs -> crates/oakcore;
  src/bindings/oakotio -> crates/oakotio; src/engine/rust ->
  crates/oakengine (keeps cdylib+staticlib+rlib)
- public C headers include/<mod>/ -> crates/oakengine/include/<mod>/
- OFX SDK headers vendored into crates/oakplugin/ofx/ (HostSupport gone)
- legacy deleted: old src/ C++ modules, engine/, core/, ffmpeg_bridge/,
  app/ (Qt), cli/worker C++, root CMakeLists, third_party/KDDockWidgets
  submodule, otio-install, all build-* output (~40GB)
- oakstorage kept but excluded from the workspace (skeleton w/ todos);
  gpui excluded (own workspace)
- verified: cargo build green, cargo test --workspace 1845/0
  (with the documented OCIO_RS_* env override for the homebrew OCIO)
2026-08-10 20:24:25 +08:00