Architecture#
Overview#
MOSAIC is built on Qt 6 / C++23 and organised into five layers:
Startup sequence#
Logger::open_log_file() →
AppSettings::load() (reads
~/.config/CSRU/mosaic/profiles/<user>/settings.json) →
TriggerManager() (installs keyboard event filters immediately) →
AudioManager() →
VideoManager::open() (opens cameras, or stubs) →
RecordManager()
Video pipeline#
Each configured camera runs its own pair of threads:
VideoManager owns all (Grabber, Buffer, Encoder) triples and starts / stops
them together via RecordManager.
Thread safety#
RingBuffer<T>is a lock-free SPSC structure (one producer, one consumer). Each camera has its own ring so there is no cross-camera contention.FrameTimestampWriter::write()is mutex-protected (called from grabber thread,stop()from main thread).Logger::log()is mutex-protected; theentry_addedsignal is emitted from the calling thread — connect withQt::QueuedConnectionwhen the receiver lives on the main thread.
Session output#
A recording session creates the following files:
Settings persistence#
Settings are stored as JSON (schema v1) in a per-profile directory:
Switching profiles (File → Switch profile) exits with code 42; main()
detects this and re-shows the login dialog, rebuilding the entire
Application + MainWindow with the new user’s settings.
Feature-flag guards#
Hardware subsystems are compiled under preprocessor guards so the software runs on any developer machine without lab hardware:
Guard |
What it enables |
|---|---|
|
Basler Pylon camera access in |
|
FFmpeg encode path in |
|
NVIDIA NVENC codec selection |
|
Apple VideoToolbox codec selection |
|
Calibration in |
|
InpOut32 polling in |