Commit Graph
402 Commits
Author SHA1 Message Date
Mike-Solar 17888a2dc1 change: remove UB in core.h 2026-07-27 08:26:13 +08:00
Mike-Solar a84e75ef47 change: UI and migrate to gtest 2026-07-27 05:27:32 +08:00
Mike-Solar eb634b53ef R7: pure C ABI display boundary + engine visibility closure
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).
2026-07-27 00:54:46 +08:00
Mike-Solar 0aa5879f35 app: migrate all engine access to the C ABI facade (nm U _ZN5olive = 0)
Every app module now reaches liboakengine exclusively through
oakengine_* C calls, EngineEventBridge subscriptions and app-side
handle headers (cliphandle/keyframehandle/nodevaluehandle/oakvaluehelper).
Direct C++ command construction, engine signal connect()s, and engine
type usage in MOC-visible signatures are gone: 557 -> 0 undefined
olive:: symbols in oak-editor.
2026-07-26 22:43:21 +08:00
Mike-Solar 1384ad1e95 app: migrate the viewer panel to the facade playback engine 2026-07-20 18:55:04 +08:00
Mike-Solar 5109dd2995 refactor: move the ratio input dialog out of engine common/ into dialog/
get_float_ratio_from_user() is pure UI (QInputDialog/QMessageBox);
common/ stays dialog-free.
2026-07-20 01:04:57 +08:00
Mike-Solar a7ddc0f114 audio: master-clock playback timing, output clock compensation, buffer config, interpolated speed
- playback timer uses the audio output device as its master clock: the
  PortAudio callback counts consumed frames (including underrun
  zero-fill) so video cannot drift away from what is heard; wall clock
  remains as fallback when no clocked output is running
- output clock compensates for device output latency; new Preferences >
  Audio buffer size setting (0 = auto)
- SampleBuffer::speed() now uses linear interpolation instead of
  nearest-neighbor sampling
- regression tests: audio-clock driven timer (fwd/rev/speed), wall
  clock fallback, interpolation correctness
2026-07-19 21:44:34 +08:00
Mike-Solar bb40b4923e style: unify identifier naming per updated conventions
Automated with clang-tidy readability-identifier-naming (config added to
.clang-tidy) plus scripted passes, per the updated rules now documented
in CONTRIBUTING.md:

- types (class/struct/enum/alias/template params): PascalCase
- functions, variables, members: snake_case (incl. rational -> Rational)
- private/protected members: trailing underscore; static member
  variables likewise (instance_, available_themes_)
- constants and enum values: snake_case (kLinear -> k_linear,
  F32P -> f32p); ALL_CAPS reserved for macros
- macros: OAK_ prefix (OLIVE_ADD_TEST/OLIVE_ASSERT/OLIVE_CONFIG ->
  OAK_ADD_TEST/OAK_ASSERT/OAK_CONFIG, GL_PREAMBLE -> OAK_GL_PREAMBLE,
  include guards -> OAK_*)
- file names: all lowercase (Current/Plugin/OliveHost/OliveClip/
  OlivePluginInstance -> current/plugin/olivehost/oliveclip/
  oliveplugininstance)
- getters share the member name sans underscore, setters set_foo()
- Qt and third-party (OpenFX) virtual overrides and framework callbacks
  keep their original names (exempt in .clang-tidy)

Manual follow-ups required where automation could not reach:
- string-based QMetaObject/SIGNAL/SLOT references updated to renamed
  methods (AddTask, CreatedFile, DeleteSpecificFile, moveSelectionUp, ...)
- macro bodies referencing renamed methods (OLIVE_CONFIG,
  NODE_DEFAULT_DESTRUCTOR, MANAGEDDISPLAYWIDGET_*)
- self-shadowing locals renamed where signals/methods became same-named
  (size_changed, worker_count, selected_items, import param, filters)
- third_party OFX member/namespace usages restored (OFX::Host::*,
  _created, _clipPrefsDirty, createInstance, clearPersistentMessage)
- STL protocol aliases restored (const_iterator) with .clang-tidy
  ignore rules; qHash overloads restored

Full build and test suite pass: ctest 4/4, ~1960 gtest cases green.
2026-07-19 16:10:54 +08:00
Mike-Solar 6229381426 version: derive from git tag/commit hash; drop audio playback debug logs
Version is no longer hardcoded: at configure time CMake uses the tag
name when HEAD is exactly on a tag (leading "v" stripped), otherwise
the first 8 hex digits of the commit hash. When git is unavailable
(e.g. source tarball) it falls back to the contents of version.txt,
which is now the single place to bump the release version.

Also remove the temporary qDebug() flood in the audio playback path
(ViewerWidget::QueueNextAudioBuffer / ReceivedAudioBufferForPlayback,
AudioManager::PushToOutput).
2026-07-17 21:10:13 +08:00
Mike-Solar 3a3ead6fc0 app: route all FFmpeg access through the ffmpeg_bridge C API
Replace every direct FFmpeg call in the editor and the render worker
with the pure C ffmpeg_bridge API, wrapped in thin C++ adapters that
preserve the original interfaces:

- avframeptr.h: olive::AVFrame adapter around FBFrame handles
- ffmpegutils: format conversion helpers on FB_* constants; the int
  overload is renamed GetCompatibleBridgePixelFormat to avoid a silent
  overload-resolution trap with the PixelFormat enum
- ffmpegdecoder/ffmpegencoder: rewritten as handle-based adapters over
  FBDecoder/FBProbe/FBEncoder/FBScaler/FBResampler
- audioprocessor: FBAudioGraph push/pull adapter
- pluginrenderer/OliveClip: sws/pixdesc usage converted to FBScaler and
  fb_pix_fmt_* queries
- AudioParams/channel layouts are plain uint64_t masks everywhere

Build integration: the root project no longer links FFMPEG directly;
only ffmpeg_bridge does. Binaries resolve the bridge library at runtime
via @loader_path inside the macOS app bundle (copied there post-build)
and via $ORIGIN/../ffmpeg_bridge/bin on Linux; on Windows the DLL is
installed next to the executables, so packages on all three platforms
ship the bridge library.

ffmpeg_bridge gains the extra API the adapters need:
fb_frame_make_writable, fb_decoder_get_format_duration,
fb_resampler_convert_frame, FB_PIX_FMT_YUV440P, SRT validation in
fb_probe_read_subtitle_stream, packed/planar fixes in
fb_encoder_write_audio, and a component-size fix in
fb_pix_fmt_component_size.
2026-07-15 23:00:06 +08:00
Mike-Solar 7cde0b0f1a Fix invalid channel layout (0x0) in audio processor and add playback diagnostics
- Add FixChannelLayout() helper to AudioProcessor::Open() to fall back to a
  default native channel layout when the input/output layout is unspecified,
  custom, or has a zero mask. This prevents FFmpeg's abuffer/aformat filters
  from rejecting 'channel_layouts=0x0' on Linux.
- Log audio processor open parameters, viewer audio queue state, and
  AudioManager::PushToOutput device/stream status to help diagnose silent
  playback on Linux.
2026-07-13 17:46:15 +08:00
Mike-Solar e5eeaddf2f format: reformatting files 2026-07-13 15:30:43 +08:00
Mike-Solar 468b6f1d1b Fix playback backup timer interval and waveform-only prequeue
- The playback backup timer was using timebase_dbl() in seconds as its
  QTimer interval, which truncated to 0 ms for normal frame rates. This
  caused the timer to fire continuously and starve the event loop when
  the video display was hidden, e.g. in Show Waveform Only mode, freezing
  the UI and stopping the playhead. Multiply by 1000 to use milliseconds.
- If PlayInternal has neither video nor audio to prequeue, call
  FinishPlayPreprocess immediately so the backup timer starts and the
  playhead advances even in waveform-only mode with no audio.
2026-07-13 10:19:30 +08:00
Mike-Solar 094f4a8e44 Fix audio waveform view scene rect and timebase refresh
- AudioWaveformView now uses the video frame rate as its timebase
  (falling back to the default sequence frame rate), preventing the
  enormous scene rect that froze the UI when it previously used the
  audio sample rate.
- Call UpdateSceneRect() after changing the waveform timebase so the
  QGraphicsScene bounds are recomputed immediately.
- Refresh the waveform view's viewer/timebase whenever the waveform
  visibility mode changes, ensuring the correct timebase is applied
  even if the node was connected earlier with a different setting.
2026-07-13 10:19:30 +08:00
Mike-Solar f6211f97a5 Fix render worker reuse and stabilize out-of-process video rendering 2026-07-13 10:19:30 +08:00
Mike-Solar 2a84027ff9 fix(renderer): macOS TBDR cross-context sync and OFX instance thread-safety
This commit fixes crashes (SIGSEGV in CImg blur_bilateral) and black-frame
corruption artifacts during playback and scrubbing on macOS Apple Silicon.

Root cause analysis:
1. macOS uses Tile-Based Deferred Rendering (TBDR). glFlush() does not
   guarantee tile memory writeback, causing glReadPixels to read incomplete
   tiles (black/corrupted frames) and cache them to disk.
2. Olive uses multiple shared OpenGL contexts (RenderProcessor contexts vs.
   thread-local PluginRenderer context). glFinish() only waits for the
   current context, not the shared context that produced the texture. CPU
   readback in PluginRenderer could read partially-rendered tiles.
3. OlivePluginInstance and OliveClipInstance are not thread-safe. Concurrent
   RenderProcessors could corrupt internal QMap/images_ and params_ via
   setInputTexture/renderAction races.

Fixes:
- OpenGLRenderer::Flush() on macOS now uses glFinish() unconditionally.
- OpenGLRenderer::DownloadFromTexture() and OpenGLRenderer::Blit() insert
  glFinish() before readback/detach to ensure tile writeback completes.
- PluginRenderer::RenderPlugin() now acquires a per-instance mutex to
  serialize concurrent OFX render calls.
- Before CPU readback in PluginRenderer, flush the renderer that originally
  produced each input texture, ensuring cross-context synchronization.
- RenderProcessor::ProcessVideoFootage() flushes after BlitColorManaged.
- Add black-frame detection in ProcessVideoCacheJob() to auto-purge TBDR-
   corrupted cache files.
- Add diagnostic qDebug() logging in viewer, decoder, renderer, and plugin
  paths to aid future debugging.
2026-05-17 14:54:49 +08:00
Mike-Solar 3845c31b37 perf(plugin): eliminate GPU↔CPU ping-pong in OFX render path
This commit removes redundant readbacks and uploads in the OpenFX
  plugin pipeline, achieving zero-copy rendering for GL-capable
  plugins and reducing CPU path overhead.

  PluginRenderer (OpenGL path):
  - Skip ReadbackTextureToFrame + ConvertFrameIfNeeded + Upload after
    plugin render. The destination texture is already valid on GPU.
  - Pass readback_cpu=false to setInputTexture() so input textures are
    provided via loadTexture() (GL texture IDs) instead of being
    downloaded to CPU Image buffers.
  - Remove duplicate ReadbackTextureToFrame block between
    getClipPreferences and the second setInputTexture call.

  OliveClipInstance:
  - Add optional bool readback_cpu=true to setInputTexture(). When
    false, only params and input_textures_ are updated; CPU readback
    and memcpy into Image are skipped.
  - Add pruneImagesCache() to prevent unbounded growth of images_.
    Input clips are limited to 8 cached frames; output clips are
    left untouched.

  Micro-optimizations:
  - Replace per-row memcpy loops with single block memcpy when
    src/dst strides are contiguous (common case in Olive pipeline).
  - Remove dead GL_PREAMBLE macro definition.

  fix(viewer): resolve playback head lag, frozen frames, and pause delay

  Three playback pipeline behavioral issues are fixed:

  1. Prequeue blocked playhead start:
     Reduce kVideoPlaybackInterval from 0.5s to 0.1s. This lowers
     prequeue length from 15–30 frames to 3–6 frames, so the
     playback timer starts much sooner after pressing Play.

  2. Frozen display during playback:
     Relax the hard frame-drop logic in RendererGeneratedFrameForQueue.
     When the queue has fewer than 2 frames, keep late frames instead
     of dropping them, preventing the viewer from freezing entirely
     when rendering cannot keep up with playback speed.

  3. Delayed frame update after pause:
     Cancel in-flight render tickets in PauseInternal() before
     deleting queue watchers. Previously the render thread continued
     processing stale playback frames, blocking the single-frame
     render requested by UpdateTextureFromNode().
2026-05-16 16:45:13 +08:00
Mike-Solar 43ba1c4642 fix ofx plugin bug 2026-05-14 20:26:17 +08:00
Mike-Solar eb79be87a4 add smoke test 2026-04-12 01:26:41 +08:00
Mike-Solar bfb1b2fce4 update copyright back 2026-01-16 21:22:05 +08:00
Mike-Solar e851653fa3 尝试修复粉紫屏未果 2026-01-16 21:11:24 +08:00
Mike-Solar 8ed5660faf solve some bugs 2026-01-05 18:01:13 +08:00
Mike-Solar b8669f6a11 Change project name; 2026-01-05 16:22:26 +08:00
Mike Solar 22fd521951 Merge branch 'refs/heads/dev' into plugin
# Conflicts:
#	.gitmodules
#	CMakeLists.txt
#	ext/core
2025-12-13 21:45:46 +08:00
Mike-Solar 1e33a31b73 Update FFmpeg handling and focus management
Refactor FFmpeg frame processing and improve focus management in panels. Add memory sanitization for debug builds and update KDDockWidgets integration.
2025-11-23 16:35:09 +08:00
Mike Solar 6fdfd03ffd update: update copyright 2025-08-05 17:12:49 +08:00
Mike Solar 74f73ab3be change: change code style to Linux style except indent. 2025-08-03 03:09:40 +08:00
Mike Solar 65ab76edc8 fix: fix exceptions when import video 2025-08-03 02:06:45 +08:00
itsmattkc e9c97407aa viewer: improve visual appearance of scrubbing 2023-03-20 10:41:47 -07:00
itsmattkc 2c2df99963 name every undo command 2023-03-12 00:49:03 -08:00
itsmattkc 019f095ee4 implement history panel 2023-03-11 22:26:21 -08:00
itsmattkc 82454c09c9 viewer: force valid sample type
Fixes #2183
2023-02-27 18:12:13 -08:00
itsmattkc 060c3b0883 viewersizer: use float for all calculations, center manual zoom 2023-02-22 10:41:17 -08:00
itsmattkc 11e4e051c3 move undo files around for better organization 2023-02-20 16:09:22 -08:00
itsmattkc 9745b536f6 nodes: remove graph and merge into project 2023-02-17 14:13:03 -08:00
itsmattkc aa5c2f0541 viewer: remove note, we'll find another way to implement this later 2023-02-08 18:16:05 -08:00
itsmattkc 5da72e4d35 Squashed commit of the following:
commit dec7ca6b96c58decf2c5e5194b665fa2342951b2
Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com>
Date:   Wed Feb 8 12:32:12 2023 -0800

    moved previewautocacher to rendermanager

commit d289d74d82c3911f3fdaa707abe9994c7363594d
Merge: a8a049a28 70d34c674
Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com>
Date:   Wed Feb 8 12:15:31 2023 -0800

    Merge branch 'master' into move-cacher-to-renderman

commit a8a049a2857c438cbab0f1ab21e3299fdfbf1fa1
Author: itsmattkc <34096995+itsmattkc@users.noreply.github.com>
Date:   Wed Feb 8 11:18:25 2023 -0800

    initial work
2023-02-08 12:40:19 -08:00
itsmattkc c1c6893713 various: moved more to core lib 2023-01-19 16:01:31 -08:00
itsmattkc dd9c52ab59 start moving core frameworks to external libraries 2023-01-19 09:51:47 -08:00
itsmattkc 328efac841 viewer: allow viewing export color spaces 2022-11-29 18:32:01 -08:00
itsmattkc f6cbcf8ef9 viewer: respond to wheel events for moving and zooming 2022-11-11 11:06:31 -08:00
itsmattkc 6a394b4e48 viewer: only detect multicam nodes if a viewer is connected
Fixes null ref crash
2022-11-06 21:04:53 -08:00
itsmattkc c357b04e82 viewer: don't attempt to update still image
Fixes crash when playing audio with muxed still
2022-11-05 10:13:04 -07:00
itsmattkc 451de7030b Merge branch 'move-time-to-viewer' 2022-11-01 18:20:22 -07:00
itsmattkc 4d80044d6d upgrade to qt 6 compliance 2022-10-28 19:42:14 -07:00
itsmattkc bdbfb56879 shift timelineview scroll code into base classes
Fixes #2060
2022-10-24 12:01:47 -07:00
itsmattkc f81445527f timebasedwidget: automatically connect scale and scrollbars 2022-10-24 11:18:42 -07:00
itsmattkc d1545745d8 various: moved time from viewer UI to viewer node 2022-10-23 20:56:04 -07:00
itsmattkc 906f802422 viewer: only render sequence waveforms when waveform view is visible 2022-10-04 21:51:05 -07:00
itsmattkc 42ba84bf5f multicam: finished UI implementation 2022-10-03 17:24:09 -07:00