- Runtime window icon: X11 takes the embedded 512px PNG up front
(_NET_WM_ICON), Wayland resolves it from oak.desktop via the app id,
Windows reads it from the exe's icon resource.
- assets/appicon: 512px PNG + 7-size ICO rasterized from Oak_Icon.svg.
- Windows: oak.rc (ICON resource ID 1, also the Explorer icon) compiled
by build.rs through embed-resource.
- Linux packaging (deb/rpm/PKGBUILD/oak.spec): install Oak_Icon.svg
into the hicolor scalable theme alongside the existing 512px PNG.
- macOS: no change needed - cargo packager already builds the .icns
from the CD-generated icons/icon.png (same source art).
Linux: 'libffnvcodec-dev' was dropped from Ubuntu noble — the NVDEC
headers are distribution-free, so install them from source
(nv-codec-headers git) like the Fedora branch already did; the
appimage step and install-deps.sh no longer apt-install the package.
Windows: ocio-sys is the GIT fork (pinned in the root manifest), so
the old crate-unpack + build.rs glob patch (registry/cache's
ocio-sys-0.2.1.crate) can never match — git dependencies don't ship a
.crate archive and unpack under registry/src/git/<hash>, hence the
"ls .../ocio-sys-0.2.1/build.rs: No such file" failure. The fork's
build.rs already carries the GNU-toolchain fix; the unpack/glob/sed
step is removed.
Policy change (supersedes the system-first probe): build OpenColorIO
from the vendored sources and link it statically on every platform
that can -- packaged binaries carry no OCIO runtime dependency. The
[patch.crates-io] ocio-sys now tracks shaloong/ocio-rs main
explicitly; its vendored yaml-cpp has the <cstdint> include that makes
the vendored build work on GCC >= 16 (verified on GCC 16.2.1).
Windows/MinGW stays the exception (the vendored source needs MSVC-only
constructs): tooling/ocio-env.sh probes the MSYS2 system OCIO there,
static when libOpenColorIO.a ships, dynamic otherwise. The Linux jobs
drop the system OCIO dev packages the system-first policy needed.
- Install ffnvcodec headers everywhere the project FFmpeg is built
(distro packages on Debian/Ubuntu/Arch/MSYS2, nv-codec-headers from
source on Fedora) so the FFmpeg build picks up NVDEC/NVENC.
- ocio-sys 0.2.1's vendored yaml-cpp misses <cstdint> and fails on
GCC >= 16 (measured on GCC 16.2.1); patch the dependency to the
fixed upstream tree (shaloong/ocio-rs, 933c65dc) until a fixed
release lands on crates.io.
- New tooling/ocio-env.sh decides the OCIO build env per job: system
OCIO >= 2.5 when present (static when the package ships
libOpenColorIO.a, dynamic otherwise), vendored static build as the
fallback. The Arch package gains an 'opencolorio' dependency only
when the binaries link the system OCIO (build-pkg.sh probes ldd).
- CI 'Build' steps switch from cargo build to cargo check: the Test
step links the test binaries anyway, and a full build would codegen
every workspace crate twice.
The sys crate's `static` feature copies the archives at BUILD time and
cargo does not track archive changes: after rebuilding the project
FFmpeg every binary silently keeps the previous objects until
`cargo clean -p ffmpeg-sys-next` (observed: an NVDEC-capable rebuild
never reached the binaries; av_hwdevice_ctx_create(CUDA) then failed
with ENOMEM because the old hwdevice table had no CUDA entry).
All crates take the oak-* kebab-case naming (oak-audio, oak-codec,
oak-common, oak-core, oak-ffmpeg-link, oak-node, oak-otio, oak-plugin,
oak-render, oak-storage, oak-task, oak-timeline, oak-undo), with the
lib identifiers rewritten (oakrender:: -> oak_render::, oakcore_rs:: ->
oak_core::, ...) across all 226 referencing files.
The GUI application moves from the workspace root into
crates/oak-app/: src/, build.rs (paths fixed for the new location) and
tests/ travel with it, the root Cargo.toml becomes workspace-only
([workspace] + workspace.package + profiles), and the app package
inherits the workspace version. The screenshots example becomes a
standalone crate examples/simple_player/ with its own Cargo.toml.
Every crate now inherits the single workspace version
(version.workspace = true), and the workflows' crate paths and the
build docs follow the renames.
Validated with a clean cargo check --workspace.
Windows: tooling/package/bundle-dylibs-windows.sh collects the MSYS2
runtime DLLs (libstdc++, libgcc, OpenColorIO, ...) with ntldd -R,
iterated to a fixpoint over freshly copied DLLs; a packager resources
glob places them next to the executables in the NSIS installer.
macOS: tooling/package/bundle-dylibs-macos.sh copies every non-system
dylib otool reports into Contents/Frameworks, rewrites the install
names to @executable_path/../Frameworks to a fixpoint, and ad-hoc
re-signs every modified Mach-O (rewriting invalidates the seal).
The CD package version no longer comes from the git tag: the root
Cargo.toml gains [workspace.package] version = "0.5.0", the oak
package inherits it (version.workspace = true — which cargo-packager
also picks up), and the Linux container packaging parses that field.
docs/build.md + docs/zh/build.md rewritten for the Rust workspace:
project-built FFmpeg 8.1 (.cargo/config.toml presets FFMPEG_DIR),
vendored static OCIO on Linux/macOS vs MSYS2 dynamic OCIO on Windows
(with the OCIO_INSTALL_DIR/OCIO_RS_LINK env), the Windows GNU toolchain
requirements (MSYS2 Rust, RUSTFLAGS=-C link-args=-lmsvcrt for the
mingw-w64 _assert forwarding, unset INCLUDE/LIB), Linux audio dev
packages and xvfb headless testing, container packaging, and a
troubleshooting section. The macOS-only guides gain a deprecation
pointer. Also correct two stale comments in tooling/install-deps.sh
(FFmpeg is built by tooling/ffmpeg/build-ffmpeg.sh, not by cargo).
- timeformat node: localtime_s/gmtime_s (reversed args, 64-bit time_t)
on Windows — MinGW has no localtime_r/gmtime_r
- the multithread suite test passed non-NUL-terminated property names
(str::as_ptr) to the C property suite — UB that resolved to garbage
lookups on the CI runner
- libsnappy off on the MinGW FFmpeg build (only feeds the hap encoder;
its pkg-config entry does not reach the static link)
- FFmpeg for Windows no longer enables libopenh264 (redundant with the
native h264 decoder + x264 encoder; its MinGW packaging does not
satisfy the static link — Wels* undefined references)
- suites_test's question-type call passed a 3-placeholder format with
one variadic arg — UB that vsnprintf turns into a SIGSEGV on glibc
(masked on macOS); use a placeholder-free format
Each distro package builds inside that distro's container so declared
dependencies always resolve to native names: hand-rolled deb via
dpkg-shlibdeps + dpkg-deb, rpm via rpmbuild's auto-requires, Arch via
makepkg (non-root builder user). git/curl install before checkout
(container jobs). AppImage keeps cargo-packager on the Ubuntu runner.
The release gates on all four package jobs plus macOS/Windows.
The distro OCIO is too old for the bridge's API floor where it matters
(Ubuntu 24.04 ships 2.1; the bridge uses 2.4+ APIs), and version drift
across platforms is a support hazard — enable ocio-rs' bundled feature
and drop the OCIO_INSTALL_DIR/system-package wiring from CI and CD so
Linux, macOS and Windows all build the same vendored OCIO. cmake/make/
diffutils added where the runners lack them (Windows FFmpeg build needs
make + cmp).
- Homebrew renamed libtheora->theora and libwebp->webp; the old names
no longer resolve, failing the macOS dependency step
- retry the MSYS2 pacman install (3 attempts, --needed resumes): CI
mirrors stall mid-download ("Operation too slow") often enough to
matter
FFmpeg 8 removed the standalone hardware decoders (h264_videotoolbox/
vaapi/nvdec/d3d11va no longer exist in its configure) — hardware decode
now only exists as a hwaccel attached to the software decoder. The new
oakcodec::hwdecode module therefore opens the regular decoder with the
platform's hardware device context attached (VideoToolbox on macOS,
VA-API then NVDEC on Linux, D3D11VA then NVDEC on Windows): FFmpeg
engages the matching hwaccel, decodes into hardware surfaces, and we
transfer them to system memory (NV12/P010) ahead of swscale.
- HardwareDecoding config switch, default ON by mandate; a checkbox in
Preferences > Rendering (EN/ZH); device creation failure skips to the
next candidate and finally to software; a decode-time failure on a
hardware session reopens it as software and retries once.
- hw_decoder_name() observability hook plus a HW_TRANSFERS counter so
tests can prove the hwaccel really engaged (not silently software).
- Verification: demo.mp4 H.264 decodes through VideoToolbox with a
transferred hardware surface, and the pixels match the software
decode within 0.05; switch off forces software.
- build-ffmpeg.sh also enables nvdec when ffnvcodec headers exist.
- screenshot example inits i18n and captures both zh-CN and en-US
(docs/screenshot-window{,-en}.png)
- dock tabs size to content (no more 64px truncation); viewer/panel
titles follow the design (素材查看器·name etc.)
- mock project carries V1/V2 video + A1/A2 audio clips rendered as
rounded green bars; timeline clip geometry/rounded corners match the
design; status bar visible with full content; audio meter strip
docked at the program viewer's right edge; project explorer rows
have icons
- tests/waveform_e2e.rs: waveform cache extracts real peaks and hits
cache on re-query (P4 acceptance)
- tooling/ffmpeg/build-ffmpeg.sh builds release/8.0 static+PIC into
.cache/ffmpeg: GPL/version3, every free-license external codec lib
probed via pkg-config (enabled when present), per-OS hardware
acceleration (VideoToolbox/AudioToolbox, VAAPI/VDPAU/libdrm,
D3D11VA/DXVA2/MediaFoundation, nvenc when ffnvcodec exists)
- tooling/install-deps.sh installs those libraries on Homebrew / MSYS2
UCRT64 / Debian-Ubuntu / Fedora / Arch; nothing in the build sudo's
- ffmpeg-next's own build feature is unusable (every crate-version to
FFmpeg-release pairing is broken upstream: 9.0.0->FF9 AVCodec fields,
8.1.0->FF8.1 new enum variants, 8.0.0->FF8 FF_PROFILE rename), so
ffmpeg-next 9 + FFmpeg 8.x headers via FFMPEG_DIR it is
- new links-crate oakffmpeg-link emits the static FFmpeg's transitive
link flags from its .pc files (cargo only propagates them from links
crates, and rustc prunes the flags unless the rlib is referenced —
hence the force_link statics)
- docs/build.md updated for the Rust workspace flow