Skip to content

refactor: play everything through Vivid's own player bridge and Lucid Engine - #139

Merged
blurbery merged 105 commits into
mainfrom
experiment/vivid-player-bridge
Oct 14, 2026
Merged

blurbery merged 105 commits into
mainfrom
experiment/vivid-player-bridge

Conversation

@blurbery

@blurbery blurbery commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

Note

Every commit here carries [skip release]. I'll choose the release marker for the merge commit when I merge.

Problem and reproduction

Vivid's player rested on two pieces of other people's work. The Swift bridge between the player and libmpv was adapted from another app, and the engine underneath it (libmpv, FFmpeg and the libraries they use) came as a third-party prebuilt package. That package built mpv and FFmpeg as GPL with OpenSSL, and device builds needed an extra step to swap in a separately rebuilt libmpv carrying my audio patch. I couldn't rebuild exactly what shipped, and the player couldn't carry Vivid's own licence and Apple distribution permission all the way through.

There's no user-facing bug to reproduce. The goal is that every part of the player is mine or built by me from upstream source, with nothing from the previous bridge or package left in the tree.

Implementation and impact

  • Player bridge. A new Swift bridge, written from a behaviour specification (docs/playback/player-bridge-spec.md). VividPlayerCoreBase and VividPlayerCore own the mpv context, event loop, ordered delivery, requests and teardown. Conversion, requests, the video surface, Match Content and EDR, external displays and lifecycle observation sit beside them in iosApp/iosApp/Playback/MPV/. LucidTLS turns on certificate verification when FFmpeg is built with Secure Transport. The previous bridge files and their notice are removed.
  • Lucid Engine. My own pipeline in engine/ builds every library from pinned upstream source with my patch series: mpv 0.41.0 and FFmpeg 8.0.1 (both LGPL-2.1-or-later as built, Secure Transport instead of OpenSSL), libass 0.17.5, dav1d, libdovi, FreeType, FriBidi, HarfBuzz, libunibreak, Little CMS, shaderc, MoltenVK, libplacebo, uavs3d, libbluray and uchardet. The patches are:
    • mpv 0010 to 0016: Vivid's AVFoundation audio output (decoded PCM, the bounded tvOS mode, AC-3 and E-AC-3 passthrough, AirPlay start-up supervision and clock anchoring);
    • mpv 0020 to 0025: Vivid's AVFoundation video output (timing and pacing, the frame path, subtitles, layers and observers);
    • FFmpeg 0010 to 0012 and mpv 0040: decoder and Dolby Vision work for VideoToolbox;
    • libdovi 0001 (an error instead of an abort on malformed input), libbluray 0001 (building for iOS and tvOS) and uavs3d 0001 (its version without Git history);
    • FFmpeg 0001 and 0002 (Secure Transport without a private API, Metal-compatible pixel buffers) and mpv 0001 (an unchanged upstream spdif fix) and 0002 (building the audio output for iOS and tvOS);
    • libass parity: upstream commit 057a5334 and upstream pull request #951, both unchanged, plus my 0010, so static subtitles render and cache as before.
  • Package. blurbery/lucid-engine 0.1.0 (commit 53ebeac) serves the 21 frameworks and MoltenVK that run 38458337996 built at fcb6782, with NOTICE, LICENSES/ and a README naming that source commit.
  • Switch-over. Both app targets pin 0.1.0 in iosApp/project-ios.yml, iosApp/project.yml and Package.resolved. The previous package, its patches, its install script, its workflows and its licence texts are removed. Open Source Licences (and the website licences page built from the same files) and THIRD_PARTY_NOTICES.md now list every library as built from upstream source, each patch and its licence, and where the corresponding source lives: engine/ at fcb6782, and the package README.
  • CI. A new Player code checks workflow runs on every pull request and push and fails if the previous code or package comes back or the engine pin drifts. The Lucid Engine build workflow now also runs on pushes to main and on pull requests that change engine/ or the workflow.
  • Tests. New app tests: VividPlayerCoreTests, VividPlayerConversionTests, VividPlayerDisplayCriteriaTests, VividPlayerEngineTests, PlaybackEndRecoveryTests and VividEndOfStreamConfirmationTests (MpvPropertyCoalescingTests went with the old bridge). In the engine pipeline: audio output vectors, video output tests, decoder suites, a malformed Dolby Vision RPU corpus through patched and unpatched libdovi, and libass scenarios.

Affects playback on iPhone, iPad and Apple TV for every server. Deliberately unchanged: the player screens, controls, settings and design, the Silo, Emby and Jellyfin cores, and Vivid's driver options.

Risks: this replaces the whole playback stack in one go, and nothing has been played on a physical device yet. The areas most likely to differ are AirPlay and HDMI audio timing (the new audio output), Match Content, HDR and Dolby Vision on real displays, VideoToolbox decoding, long sessions, and libass cost with heavy styled subtitles now that rendering stays on one thread. Reverting this PR's merge brings the previous player back.

Validation

How parity was established:

  • Specifications first. The bridge and the engine patches were written from behaviour specifications of the previous bridge and engine (bridge, engine), and every review difference was either fixed or recorded there as a deliberate difference.
  • Side-by-side comparisons with the previous engine (patch spec 13.3, on the integrated build at 10faa2a): configuration and symbols match; the audio output gives the same results across 30 scenarios on iOS-like and tvOS-like host builds, apart from free log wording; the decoder matches across 49 scenarios against real macOS VideoToolbox; the video output's timing and picture path show 0 differences (11,744 picture checks); libass is pixel-identical on the parity corpus (23,280 renders), and the libass series added since restores the previous change reporting and font fallback behaviour. No regression was found. Behaviour reviews of the new bridge against the old one found nothing that would regress.
  • Engine host suites in run 38458337996 (the run 0.1.0 was published from): 683 of 683 checks per slice, 140 audio output vectors per slice, 1,920 video output cases, decoder suites of 534, 199,060 and 5,937 checks, 19,381 libdovi cases and 82 libass scenarios, all passing. Every library is checked on every run against the recorded configuration of the previous binaries.
  • CI on this head (1fc0705):
    • Player regression on this PR, run 38466062418: complete iOS suite 1,476 tests, 0 failures (2 skipped, the existing live-server tests); Apple TV suite 211 tests, 0 failures; unsigned Release builds of both apps for generic iOS and tvOS devices, linking 0.1.0's device slices, passed.
    • Optimised run, 38466061836: the iOS suite as a normal build and compiled with the Release optimiser, 1,476 tests each with 0 failures (2 skipped), and the Apple TV suite, 211 tests with 0 failures.
    • Player code checks: 38466062548 (pull request) and 38466056858 (push), both passed.
    • Lucid Engine build on this PR, 38466062631: every job passed with no dependency cache to reuse, so every library was built from source again, and its 22 xcframework zips match 0.1.0's SHA256SUMS byte for byte.

Performance

Not benchmarked. Host comparisons show the same timing and pacing behaviour, but frame times, CPU and memory on devices haven't been measured yet.

Testing status

  • Tested? Partly: CI and local simulators. No physical-device testing yet.
  • Environment: GitHub Actions: iOS and tvOS simulators on macos-15 with Xcode 26.3, unsigned Release device builds, and the engine pipeline on macos-26 with Xcode 26.6. Locally: Xcode 27.0 with the existing iPhone 18 Pro and Apple TV 4K simulators (iOS 27.0 and tvOS 27.0).
  • Revision: 1fc0705.
  • Checks and results: CI as listed under Validation, all passing. On both simulators:
    • testCompletionsCalledOffMainArriveLaterOnMain passed 200 of 200 iterations, the four VividPlayer*Tests classes passed 3 iterations (399 tests each), and the playback test classes passed (334 on iPhone, 116 on Apple TV, 0 failures).
    • Real playback through the engine of H.264, HEVC 8-bit and HEVC 10-bit HDR10 with AAC, AC-3, E-AC-3 and TrueHD, plus the repository's 8 container fixtures: every load played; A/V sync stayed at about 0 ms; no dropped frames in steady play; seeking, audio and subtitle track switches, the compressed audio output, speed changes across 1x and HDR10 detection all behaved.
    • Subtitles: a static boxed SubRip line and a static clipped ASS sign rendered once and were then reused; karaoke re-rendered every frame as it should.
    • The engine reports mpv 0.41.0, FFmpeg 8.0.1 and libass 0.17.5, and the app bundles contain none of the previous bridge's or package's names.
  • Limitations:
    • On the iPhone simulator, video sometimes paused for up to about 0.4 s after resuming from a pause while audio carried on (5 of 15 resumes). I've accepted that for now; the device test will show whether it happens on hardware.
    • On the 27.0 simulators FreeType cannot open the PingFang UI font, so some Simplified Chinese characters can fall back to missing glyphs, and emoji in subtitles show as boxes. These weren't compared against the previous build.
    • Everything hardware-specific is still to test on devices: VideoToolbox decoding and Dolby Vision, passthrough and Atmos, AirPlay, HDR and Match Content, Picture in Picture, external displays, background and lock, and long 4K sessions on Apple TV. That covers the bridge specification's device tests (16.3) and the engine specification's device checklist (9.5, with the checks that 12.7 and 13.7 add), including check 46 (heavy styled ASS on one rendering thread) and checks 65 to 69.

Design impact and approval

  • Design impact: No design changes. Open Source Licences keeps its layout; only its text changes.
  • Approval from blurbery: Not applicable, no design changes.

Documentation impact

  • New: docs/playback/player-bridge-spec.md, docs/playback/lucid-engine-patch-spec.md, docs/cores/lucid-engine-architecture.md, docs/cores/lucid-engine-build.md, docs/cores/lucid-engine-build-facts.md and docs/cores/lucid-engine-libs-build-facts.md.

  • Updated: docs/cores/player-engine.md, docs/README.md, docs/playback/README.md, docs/release/distribution.md, docs/release/versioning.md, CONTRIBUTING.md, AGENTS.md and THIRD_PARTY_NOTICES.md.

  • In-app licences: iosApp/Resources/OpenSourceLicenses/ (overview, every engine library's header, mpv and FFmpeg moved to their LGPL texts, OpenSSL and the previous bridge's licence removed), with scripts/tests/licence-texts-tests.py updated. The website licences page is generated from these files.

  • No privacy policy change: what the app sends and stores is unchanged.

  • I checked the docs this change affects and updated them in this PR, or explained above why none needed changes.

AI disclosure

I implemented these changes and used Claude Opus as a tool.

Specifies, by behaviour, the Swift bridge between Lucid Engine's adapter
and libmpv: the caller contract and exact payload types, threading and
locking, the mpv lifecycle and options, the video surface and the
engine's video-output contract, Match Content and HDR, external
displays, Picture in Picture, errors, constants, Vivid's own changes by
commit, deliberately omitted paths, known quirks, parity hazards and a
test checklist.

It is the only description of the current bridge that the Vivid-written
replacement is built from. It was written and audited by people who read
the current code, and the replacement is written by someone who has not.
… [skip release]

Adds a new Swift bridge between Lucid Engine's adapter and libmpv,
written from docs/playback/player-bridge-spec.md without reference to
the current bridge. It is organised as a centre (VividPlayerCoreBase and
VividPlayerCore: the mpv context, event loop, ordered delivery and
coalescing, requests and disposal) with separate parts for the video
surface, Match Content and HDR, external displays and app lifecycle.

Both bridges are compiled into every build. VividBridgeSelection.swift
picks one with the VIVID_OWN_BRIDGE compilation condition, which is off
by default, so shipped behaviour is unchanged. The adapter, the subtitle
inventory, the session recorder and the coalescing tests now reach the
bridge through those selection names.
… review [skip release]

Adds section 17 (internal component files, the wakeup guard nesting, the tvOS last-resort screen, answers to the implementer's questions, distinct start-up check locations and the order of the internal video observations) and corrects three video-output passages the engine rewrite no longer supports.
… release]

engine/lucid.py builds dav1d 1.5.3, libass 0.17.5, FFmpeg n8.0.1 and mpv v0.41.0 from pinned upstream archives plus the patch series under engine/patches, stages the interim prebuilt dependencies listed in engine/pins.ini, packages static xcframeworks and writes a provenance report. The FFmpeg series adds a patch that requests Metal-compatible VideoToolbox pixel buffers; the mpv series carries upstream commit 1388a453 unchanged.
… tvOS [skip release]

Upstream ao_avfoundation compiles the macOS-only CoreAudio device helpers whenever it is enabled, so -Davfoundation=enabled fails on tvOS. Add Vivid patch mpv/0002, which keeps that code to macOS, and keep ninja going after the first failing file so one run reports every error.
…[skip release]

The AVFoundation and AudioUnit outputs share ao_coreaudio_chmap.h, which also declared the macOS-only device queries. Extend mpv patch 0002 to guard those with CA_HAVE_HAL while keeping the layout helpers AVFoundation uses.
…lease]

The build facts list filters as the registry symbols Libavfilter defines, which include scale2ref because vf_scale.o defines it, although the configure line never enables it. Compare enabled filters without scale2ref, and compare the defined registry symbols with the facts list less delogo.
…es [skip release]

Widen the matrix to iOS device, iOS simulator, tvOS device and tvOS simulator, all arm64, and correct the framework count in the guide.
…kip release]

Rejects a non-finite frame rate before the early Match Content write,
gives each start-up check its own console location, registers the
internal video observations in the order the spec now fixes, keeps the
new host view on a repeated initialise, and picks the default Dolby
Vision compatibility id from the full profile. The shared teardown marks
the core terminal before it drains requests.

Also narrows what subclasses can override, marks the lock-protected
helpers as Sendable, adds tvOS test seams for the display criteria write,
moves the PiP subtitle option into the core, renames internal helpers,
corrects two comments and states exactly what has been tested.
Adds conversion, core, display criteria and engine tests that use the
new bridge types directly, so CI exercises them whichever bridge the app
selects. They cover value conversion and its budgets, ordered delivery
and coalescing, exactly-once request completions, the pause cache,
lifecycle, the video surface, Match Content derivations and the shared
tvOS request identity, the external display role test, the console
format, and real mpv playback in the simulator. The files are added to
both test targets.
…mpv [skip release]

The AVFoundation audio output calls cfstr_get_cstr() from osdep/utils-mac.c, which upstream meson only builds with the macOS cocoa feature, so the static libmpv could not be linked into an app. mpv patch 0002 now builds utils-mac.c with that output whenever cocoa is off. Its notification name log line is unchanged, and macOS builds with cocoa are unchanged.
…e [skip release]

lucid.py check now resolves every undefined symbol in the built and pinned archives against the link set, the compiler runtime and the SDK's .tbd stubs, and links a small program that calls mpv_create, mpv_initialize, mpv_terminate_destroy and avformat_configuration, dead-stripped, against the frameworks, prebuilts and app-link.txt. It also checks that Libmpv keeps the AVFoundation notification name log line.
…spec [skip release]

Corrects the adapter's audio-option rows, the zoom row's reason, the list of moments the engine waits on the main thread and the cover-art case for audio-only loads, recorded as amendments 17.7 to 17.10.
…p release] [skip ci]

Engine implementers work on their own experiment/lucid-engine-* branches, so run the Lucid Engine workflow on pushes to those as well as to experiment/lucid-engine-build. The path filters are unchanged, and the concurrency group stays per branch, so a newer push cancels only that branch's running build.
The behaviour contract Vivid's own mpv and FFmpeg patches are written from: the interface Vivid relies on, the AVFoundation audio and video outputs, Dolby Vision in FFmpeg's VideoToolbox path, libdovi without aborts, the other kept behaviour, the dropped patches, build provenance and the tests. Linked from the build guide, with the patch number ranges.
… [skip release]

libdovi was the last engine library linked as a third-party prebuilt that
FFmpeg and libplacebo feed media data to, and upstream builds its C library
to abort the process on any panic. Build it here instead, as the eleventh
framework, Libdovi:

- Pin the dovi_tool libdovi-3.3.2 source, the SHA-256 of its dolby_vision
  Cargo.lock, Rust 1.98.0 stable (rustc, cargo and the standard library for
  the runner and each slice, which now ships for tvOS too, so no nightly or
  -Zbuild-std) and cargo-c 0.10.25. fetch downloads every crate the lock
  file lists from static.crates.io by its checksum, and the build runs
  offline with --frozen from those vendored crates.
- Build the static library with cargo-c first, so FFmpeg and mpv find its
  dovi.pc. Remove the LLVM bitcode Rust's prebuilt standard library embeds,
  which Xcode's nm and linker cannot read, with the toolchain's own
  rust-objcopy. Replace [prebuilt:libdovi] with a reference entry that check
  uses to require the same header and exported C API as today's prebuilt.
- Add Vivid's patch 0001 (MIT, like libdovi): unwinding plus catch_unwind
  in every exported function, counts checked against the remaining input
  before memory is reserved, no write of a field holding u64::MAX (the bit
  writer would first write 512 MiB of zeros), no header when the display
  management query that libplacebo does not null-check would fail, and a
  null buffer treated as a parse error.
- Add lucid.py test-libdovi and a CI job for it: libdovi built for the
  runner unpatched and patched, and about 19,400 malformed and valid RPUs
  through every entry point and through FFmpeg's and libplacebo's call
  sequences, one process per case. The patched build must never abort and
  must match the unpatched build wherever that does not abort; the
  unpatched build must abort on each abort class of the patch
  specification. Packaging waits for it.
- Check per slice: libdovi's form and minimum OS, panic runtime, missing
  bitcode, header and exports against today's prebuilt, and the libdovi
  functions libplacebo and FFmpeg import. The test link now calls libdovi.

Reproducible archives: set ZERO_AR_DATE=1 and SOURCE_DATE_EPOCH (mpv
v0.41.0's commit time, which fixes mpv's build date) for every build, check
that every archive member has a zero timestamp and the expected build date,
and package twice in the packaging job, failing unless the zips match.

Build only the tvOS device slice for this first run; the next commit
restores all four slices.
…oducible builds [skip release]

Add libdovi to what the pipeline builds, with its pins (Rust 1.98.0, cargo-c 0.10.25 and the locked crates), the patch and why it is sound, the C API test and its corpus, the reproducibility measures, the branch pattern the workflow now runs on, the new checks and the differences from today's prebuilt.
…source [skip release]

The tvOS device slice and the libdovi C API test passed in run 38366707132 (229 of 229 slice checks, no failures in the corpus), so restore the iOS device, iOS simulator and tvOS simulator slices.
… release]

Add FFmpeg patches 0010 to 0012 from the Lucid Engine patch specification (sections 5 and 6.6): an explicit sample size for every VideoToolbox sample, native Dolby Vision HEVC decoding for profiles 5, 7 and 8 with the profile 7 to 8.1 conversion through libdovi 3.3.2 in its own videotoolbox_dovi.c, and verbose levels for two hevcdec messages. Each is LGPL-2.1-or-later and applies with zero fuzz on top of the existing series.
…ip release]

Add mpv patch 0040 from the Lucid Engine patch specification (section 6.1): once hardware decoding has output a frame, a run of decoding errors ends it only after two keyframes fail to recover it or after 240 errors. Probing and copy-back failures still fall back at once. LGPL-2.1-or-later.
…lice [skip release]

lucid.py gives FFmpeg libdovi's include path and -ldovi from the staged dovi.pc through CFLAGS and LDFLAGS only, so the configure line is unchanged, and records the flags. lucid.py check now requires the libdovi and per-frame HDR metadata references in Libavcodec, the verbose hevcdec levels, mpv 0040's recovery line and no fault substring in the decoder patches' messages. The new lucid.py test step builds the Dolby Vision host tests from the patched FFmpeg tree, against a scripted libdovi and against libdovi 3.3.2, and fails on any failed check or an empty suite.
…ks [skip release]

Vivid's own mpv patches for the AVFoundation audio output, written from
the patch specification and applied on top of patches 0001 and 0002:

- 0010 carries E-AC-3 at four times the codec rate;
- 0011 wakes the output chain after a hard reset;
- 0012 rebuilds the output around a shared centre (options, queue,
  audio session, passthrough block, trace edges, prefetch guard);
- 0013 adds the decoded PCM sink with the bounded tvOS mode;
- 0014 adds passthrough start-up supervision and clock anchoring;
- 0015 passes AC-3 and E-AC-3 through AVPlayer and a resource loader.

The output's decisions are plain C behind operation tables, so
engine/tests/ao_avfoundation_vectors.c drives the shipped code through
fakes. `lucid.py test-audio` builds it on the runner from each slice's
patched mpv tree and runs every vector of section 9.3, and `lucid.py
check` now requires that result, the 25 frozen log formats (with the
standalone fallback line checked against a doctored copy), the option and
Vivid markers, max-lookahead on tvOS only, and the renderer notification
and selectors the output needs. www.gnu.org joins the reference hosts for
the LGPL file headers.
xcodebuild -create-xcframework lists the slices in a different order from run to run, so the four-slice packaging in run 38367673194 gave different zips when packaged twice and the new reproducibility check failed it. Rewrite the Info.plist with the slices sorted by library identifier and its keys sorted, so identical frameworks give identical zips.
…ord libdovi flags [skip release]

Patch 0011 now keeps the previous session's frame flags until the new VideoToolbox session has been created, so frames output during a restart are not briefly treated as plain HEVC, and releases any session object before the plain HEVC retry. The provenance summary lists the libdovi flags FFmpeg was built with.
…ease]

Brings in libdovi 3.3.2 built from source with Vivid's crash-proof patch. FFmpeg now takes libdovi's flags from the dovi.pc that build installs, and lucid.py test builds the same patched libdovi for the build host instead of looking for a host library in the old prebuilt, reads the RPU samples from the pinned libdovi source's own test assets, and passes every RPU of the libdovi corpus through FFmpeg's profile 7 conversion. The copied RPU vectors are no longer needed.
…t frame is rendered [skip release]

A static event with glyphs no font provides that draws nothing visible
(fully transparent, off screen or clipped to nothing) has no image on
screen to keep its event render cache entry. When the images on screen
exceed the 32 MiB budget, the cut at the start of every frame dropped
that entry, so the event was rendered and its fonts searched again on
every frame.

Patch 0010 now gives every entry a frame uses a reference of its own,
held by the renderer until the next frame has been rendered, as the
frame's images hold theirs, and released then or when the renderer is
freed. Such an event is searched for once per appearance, plus once per
added fallback face, however full the cache is, and a transparent line
whose glyphs all resolve is not rendered again either. Nothing is held
by events, so freeing an event or a track leaves nothing behind.

The libass host test gains a visible baseline of four drawings and
three boxed signs that keeps the cache over its budget on its own, and
four lines on top of it: the unassigned code point transparent, off
screen and clipped to nothing, and a transparent CJK line. Their 12 new
checks fail with the previous 0010 and pass with this one (82
scenarios, 10,862 scenario checks).
… invisible-line pressure tests [skip release]
…ranch [skip release]

Brings engine/, the Lucid Engine build workflow and the engine guides and patch specification onto this branch. The previous engine's patches, scripts, workflows and licence texts stay deleted.
… source [skip release]

Both platform specs and Package.resolved move from the 0.1.0-interim.1 prerelease (11d60dc) to release 0.1.0 (53ebeac), which Vivid's pipeline built from upstream source in full, including libass with its parity patches and the eleven libraries that were interim prebuilt binaries.
…n main and pull requests [skip release]

A new always-run workflow checks on every pull request and push that no previous third-party player code or package returns and that both apps pin the same Lucid Engine package, because the player regression workflow only runs for app changes. The Lucid Engine build now also runs on pushes to main and on pull requests that change engine/ or its workflow, so engine changes stay tested once this lands.
…source [skip release]

The in-app licence headers, the acknowledgements overview and the third-party notices now describe release 0.1.0: every library built from upstream source by Vivid's pipeline, each library's patches and their licences (mpv, FFmpeg and libbluray LGPL-2.1-or-later, libass ISC including its two upstream patches, libdovi MIT, uavs3d BSD-3-Clause), and where the corresponding source lives. The upstream licence texts are unchanged and match the package's LICENSES folder; the licence test records the new header hashes.
…on this branch [skip release]

The engine guides, the patch and bridge specifications, the documentation index, the contribution and agent guides and the release guides now describe the final state: the app pins release 0.1.0, built entirely from upstream source by the pipeline in engine/, which is tested on main and on pull requests and published by hand with engine/publish_package.py. Links that pointed at commits on the two experiment branches are now relative.
@blurbery blurbery changed the title refactor: add Vivid's own player bridge behind a build flag [skip release] refactor: play everything through Vivid's own player bridge and Lucid Engine Oct 13, 2026
@blurbery
blurbery marked this pull request as ready for review October 13, 2026 23:06
@cubic-dev-ai

cubic-dev-ai Bot commented Oct 13, 2026

Copy link
Copy Markdown

This PR is large and would use a significant portion of your monthly review quota. Comment @cubic-dev-ai review this to confirm that you want cubic to review it.

@blurbery

Copy link
Copy Markdown
Owner Author

@cubic-dev-ai review

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 13, 2026

Copy link
Copy Markdown

@cubic-dev-ai review

@blurbery I have started the AI code review. It will take a few minutes to complete.

@github-actions

github-actions Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

Claude review of the new commits 5cb2aad..f970015

I reviewed only the new commit, which changes one line in docs/playback/lucid-engine-patch-spec.md (line 1739). That line now says no library comes as a prebuilt binary apart from the Rust standard library inside libdovi, from the pinned rust-std archives. This fixes the earlier P3 comment and matches the other docs and section 8.4 of the same spec. Nothing needs fixing. I did not re-review the earlier commits.

I reviewed the one change since 5cb2aad, the Rust standard library exception on line 1739 of docs/playback/lucid-engine-patch-spec.md. It matches engine/pins.ini, which pins the rust-std archives. It also fits the surrounding 8.3 text on libdovi's Rust standard library and agrees with the other docs. I have no findings.

claude-sonnet-5-5, high effort, 8 turns, about US$0.17 of API credit

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 197 files

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

Comment thread engine/tests/vo/test_layers.m Outdated
Comment thread engine/tests/vo/test_centre_tv.m Outdated
Comment thread engine/config/expected-libs/libunibreak.pc
Comment thread THIRD_PARTY_NOTICES.md Outdated
Comment thread engine/tests/vo/test_clock.c
Comment thread engine/publish_package.py
Comment thread docs/cores/lucid-engine-build.md Outdated
…rrect engine docs [skip release]

Review follow-ups for the engine's host tests, its publishing tool and
the docs. No engine patch, build option or app code changes.

- test_layers: the off-main helper's completion flag is now an atomic
  stored with release and loaded with acquire, so the values the worker
  block writes are safely visible on the main thread. A volatile flag
  gave no such ordering.
- test_centre_tv: the tvOS default-mode case only examines and
  uninitialises the VO when preinit succeeded.
- test_pixels: the 10-bit and 12-bit upload checks now cover every luma
  sample and chroma pair of each plane, not half of them.
- test_frame: the frame-size case now also requires the composite kind,
  a blend into the decoder's buffer whenever the cue reaches the frame
  and none when it is wholly off it, so a dropped cue can no longer pass.
- publish_package.py refuses a package checkout with uncommitted or
  untracked files before writing anything, since it replaces LICENSES/
  and the package's own files there.
- Docs: the notices and distribution guide now say the Rust standard
  library inside libdovi comes from Rust's pinned prebuilt rust-std
  archives; the shipped slices are arm64 only, with MoltenVK's simulator
  x86_64 build thinned away; the adapter track test runs in the iOS jobs
  only; and the library build facts record that uavs3d's VERSION_SHA1 is
  its own tag commit, 0e20d2c2, as patch 0001 sets it.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude review of the new commits ccc9c42..ead3ead. The summary comment lists everything found.

Comment thread iosApp/Resources/OpenSourceLicenses/README.txt
Comment thread docs/cores/lucid-engine-build.md Outdated

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude review of the new commits ead3ead..1792e76. The summary comment lists everything found.

Comment thread docs/cores/lucid-engine-build.md

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude review of the new commits 1792e76..5cb2aad. The summary comment lists everything found.

Comment thread docs/playback/lucid-engine-patch-spec.md Outdated
@blurbery
blurbery merged commit c2dad70 into main Oct 14, 2026
17 checks passed
@blurbery
blurbery deleted the experiment/vivid-player-bridge branch October 14, 2026 00:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant