Repository navigation
Releases: speculor-app/speculor
Release list
Speculor v0.29.0
Install
Quick start (one download per platform)
Windows (x64) — speculor-0.29.0-windows-x64-full.zip. Extract and run speculor\speculor_app.exe.
Linux (x64) — speculor-0.29.0-linux-x64-full.tar.xz. Extract and run ./speculor/speculor_app.
Linux (ARM64) — speculor-0.29.0-linux-arm64-full.tar.xz. For ARM64 single-board computers (Raspberry Pi 5, Orange Pi 5 / RK3588). Extract and run ./speculor/speculor_app.
Custom install (pick the plugin domains you need)
Download the smaller speculor-0.29.0-<platform> archive plus any speculor-bundle-<domain>-0.29.0-<platform> archives, and extract them all at the same install root. Bundle domains: adsb, astro, audio, sdr, passive-radar, video-sources, motion-analysis, detection, image-filters, renderers, automation, mounts, scripting, output, database, data-filters, misc-sources, oss (open-source plugins: ViBe/SuBSENSE motion + RTL-SDR).
What's changed
Application
Features
- seal: verify a desktop session's seal and name what kind of key signed it
- seal: seal every session recorded here, at the stop
- seal: hash each part as it closes, and seal what retention dropped
- seal: a late seal is unchanged since SEALED, and says when the take stopped
- sapient: acknowledge registrations
- sapient: listen on a configurable address, every interface by default
- sapient: keep one node identity across restarts with a Node ID setting
- engine: give every datum a timestamp and sequence number
- refuse to start on a CPU without AVX2, with a message instead of a crash
Bug fixes
- build: read the OpenAIP key from the environment
- build: stop the build when the OpenAIP key is missing
- engine: contain plugin crashes on Linux and macOS
- engine: keep frame pools apart when their sizes hash alike
- engine: keep signals flowing to a restarted node
- cli: run projects that contain virtual plugins
- engine: retry a failed node restart as the same plugin
- engine: keep a GPU bridge alive while a call is using it
- recording: remove a data race in the recorder's writer statistics
- engine: keep frame pools alive until their last frame comes back
- engine: destroy plugin instances before their host contexts
- sapient: give each camera's tracks their own object ids
- engine: don't block painting and stats behind a restart
- sapient: bound TLS handshakes and fail closed when TLS can't load
- engine: keep workers off engine state that stop can change
- engine: restart a node that sends control commands without crashing
- logger: keep the log size cap after a failed roll
- logger: stop file logging without hanging on the writer
- licensing: name encrypted licence files instead of calling them tampered
- engine: keep feeding every data consumer when a node with a control edge restarts
- engine: restart a node blocked in on_signal, and give its producer a new worker
- engine: free a producer blocked in a disabled consumer's on_signal
- engine: return a failed iteration's frames to the pool at once
- gui,cli: stop claiming a frame pool preallocates every slot
- engine: stop overrunning the frame pool when a plugin pads its rows
- engine: never stop a plugin that is still inside process()
- engine: keep Stop bounded when a parameter set from a control edge hangs
- engine: keep Stop bounded when a watchdog restart wedges in the plugin
- engine: keep Stop bounded when a plugin's request_stop blocks
- engine: feed real pixels to a GPU node that falls back to its CPU path
- recording: keep a session openable after a crash or power loss
- engine: clamp a port's queue depth so an absurd one can't corrupt memory
- engine: contain crashes in destroy_instance and stack overflows on Linux
- ingest: bound open connections and keep a challenge flood off others' nonces
- engine: return the frames a plugin acquired when it reports no data
- engine: publish every health change, including to callbacks added early
- dds: refuse remote writes to a parameter its node reports as read-only
- clock: stop a DDS time-sync follower and the local discipline taking turns
- gui: stop the GUI freezing while the engine restarts a node
- gui: keep the window responsive while the pipeline starts or stops
- engine: GPU nodes deliver their tables, packets and records with the right frame
- recording: recordings keep each datum's time and sequence, and exports cover the range asked for
Performance
- engine: download previewed GPU frames only when the preview shows them
- engine: keep frame acquisition off the engine-wide pool lock
- engine: stop paying a system call on every plugin call on Linux and macOS
- engine: stop holding back a node's next input after it reports no data
- dds: an exposed port nobody subscribes to costs nothing
- engine: hand out pooled frames and tables without allocating
- engine: opening or closing a preview no longer stalls every node
- engine: frame pools grow with the number of nodes producing each frame size
Engine SDK
Performance
- gpu: GPU streams no longer wait on each other's transfers or buffer frees
Features
- sdk: add a timestamp and sequence number to scalars, records and control messages
- sdk: refuse to start on a CPU below the build's x86-64 level, with a message
Plugins
Features
- audio_input: Native sample rate, and the real capture rate reported downstream
Bug fixes
- sdr_spectrum: waterfall scrolls down from the spectrum, newest line on top
- audio_spectrum: frequency axis follows the input's real sample rate, top limit configurable
- wmv_bgs,mog2_bgs: stop the mask overwriting a frame already sent on when the pool is full
- sources: let Weather and Home Assistant sources stop mid-request
Open-source plugins
Bug fixes
- vibe_bgs,subsense_bgs: stop the mask overwriting a frame already sent on when the pool is full
Generated from commit history across the Speculor repos (v0.28.0 → v0.29.0).
Speculor v0.28.0
Install
Quick start (one download per platform)
Windows (x64) — speculor-0.28.0-windows-x64-full.zip. Extract and run speculor\speculor_app.exe.
Linux (x64) — speculor-0.28.0-linux-x64-full.tar.xz. Extract and run ./speculor/speculor_app.
Linux (ARM64) — speculor-0.28.0-linux-arm64-full.tar.xz. For ARM64 single-board computers (Raspberry Pi 5, Orange Pi 5 / RK3588). Extract and run ./speculor/speculor_app.
Custom install (pick the plugin domains you need)
Download the smaller speculor-0.28.0-<platform> archive plus any speculor-bundle-<domain>-0.28.0-<platform> archives, and extract them all at the same install root. Bundle domains: adsb, astro, audio, sdr, passive-radar, video-sources, motion-analysis, detection, image-filters, renderers, automation, mounts, scripting, output, database, data-filters, misc-sources, oss (open-source plugins: ViBe/SuBSENSE motion + RTL-SDR).
What's changed
Application
Features
- dds: signals cross DDS — exposed, published and received as signals
Bug fixes
- engine: a table keeps its signal header through delivery
Plugins
Features
- dds: dds_subscribe_signal, and the Sensor Panel takes the microphone as a signal
Generated from commit history across the Speculor repos (v0.27.0 → v0.28.0).
Speculor v0.27.0
Install
Quick start (one download per platform)
Windows (x64) — speculor-0.27.0-windows-x64-full.zip. Extract and run speculor\speculor_app.exe.
Linux (x64) — speculor-0.27.0-linux-x64-full.tar.xz. Extract and run ./speculor/speculor_app.
Linux (ARM64) — speculor-0.27.0-linux-arm64-full.tar.xz. For ARM64 single-board computers (Raspberry Pi 5, Orange Pi 5 / RK3588). Extract and run ./speculor/speculor_app.
Custom install (pick the plugin domains you need)
Download the smaller speculor-0.27.0-<platform> archive plus any speculor-bundle-<domain>-0.27.0-<platform> archives, and extract them all at the same install root. Bundle domains: adsb, astro, audio, sdr, passive-radar, video-sources, motion-analysis, detection, image-filters, renderers, automation, mounts, scripting, output, database, data-filters, misc-sources, oss (open-source plugins: ViBe/SuBSENSE motion + RTL-SDR).
What's changed
Application
Features
- devices: the phone node offers the sound of its video
Engine SDK
Features
- map: draw the Light style from OpenStreetMap too, and drop Voyager
Bug fixes
- map: draw the Dark style from OpenStreetMap, and cache tiles in true colour
Plugins
Features
- maps: Light drawn from OpenStreetMap, Voyager dropped from every style list
- sensor_panel: sound from the video, horizon only, no picture
- sensor_panel: related lanes together, the tilt said once, sound across its own column
Bug fixes
- maps: draw the Dark style from OpenStreetMap in sensor_panel and pr_map
- sensor_panel: wait when there is nothing to take or draw
Open-source plugins
Features
- adsb_display: Light drawn from OpenStreetMap, Voyager dropped
Bug fixes
- adsb_display: draw the Dark map from OpenStreetMap, and cache tiles in true colour
Generated from commit history across the Speculor repos (v0.26.0 → v0.27.0).
Speculor v0.26.0
Install
Quick start (one download per platform)
Windows (x64) — speculor-0.26.0-windows-x64-full.zip. Extract and run speculor\speculor_app.exe.
Linux (x64) — speculor-0.26.0-linux-x64-full.tar.xz. Extract and run ./speculor/speculor_app.
Linux (ARM64) — speculor-0.26.0-linux-arm64-full.tar.xz. For ARM64 single-board computers (Raspberry Pi 5, Orange Pi 5 / RK3588). Extract and run ./speculor/speculor_app.
Custom install (pick the plugin domains you need)
Download the smaller speculor-0.26.0-<platform> archive plus any speculor-bundle-<domain>-0.26.0-<platform> archives, and extract them all at the same install root. Bundle domains: adsb, astro, audio, sdr, passive-radar, video-sources, motion-analysis, detection, image-filters, renderers, automation, mounts, scripting, output, database, data-filters, misc-sources, oss (open-source plugins: ViBe/SuBSENSE motion + RTL-SDR).
What's changed
Application
Features
- devices: a phone added as one node comes with its sensor panel
Engine SDK
Bug fixes
- spclib: say a low magnetometer calibration once
Bug fixes
- spclib: read gravity the way Android reports it
Features
- spclib: instruments, what a phone's readings mean
Plugins
Features
- renderers: sensor_panel, a phone's sensors as one image
Bug fixes
- sensor_panel: take the inputs in the Mobile Sensor node's order
Generated from commit history across the Speculor repos (v0.25.0 → v0.26.0).
Speculor v0.25.0
Install
Quick start (one download per platform)
Windows (x64) — speculor-0.25.0-windows-x64-full.zip. Extract and run speculor\speculor_app.exe.
Linux (x64) — speculor-0.25.0-linux-x64-full.tar.xz. Extract and run ./speculor/speculor_app.
Linux (ARM64) — speculor-0.25.0-linux-arm64-full.tar.xz. For ARM64 single-board computers (Raspberry Pi 5, Orange Pi 5 / RK3588). Extract and run ./speculor/speculor_app.
Custom install (pick the plugin domains you need)
Download the smaller speculor-0.25.0-<platform> archive plus any speculor-bundle-<domain>-0.25.0-<platform> archives, and extract them all at the same install root. Bundle domains: adsb, astro, audio, sdr, passive-radar, video-sources, motion-analysis, detection, image-filters, renderers, automation, mounts, scripting, output, database, data-filters, misc-sources, oss (open-source plugins: ViBe/SuBSENSE motion + RTL-SDR).
What's changed
Application
Features
- devices: a mobile sensor is one node
Bug fixes
- recording: a phone's video plays back the way it was seen
Engine SDK
Features
- video: a stream's rotation travels in the video, and the crop/rotate stage is the SDK's
Plugins
Bug fixes
- video_source: bind the crop as a compute pipeline, not a shader object
- video_source: stand a stream upright by the rotation inside its video
Generated from commit history across the Speculor repos (v0.24.0 → v0.25.0).
Speculor v0.24.0
Install
Quick start (one download per platform)
Windows (x64) — speculor-0.24.0-windows-x64-full.zip. Extract and run speculor\speculor_app.exe.
Linux (x64) — speculor-0.24.0-linux-x64-full.tar.xz. Extract and run ./speculor/speculor_app.
Linux (ARM64) — speculor-0.24.0-linux-arm64-full.tar.xz. For ARM64 single-board computers (Raspberry Pi 5, Orange Pi 5 / RK3588). Extract and run ./speculor/speculor_app.
Custom install (pick the plugin domains you need)
Download the smaller speculor-0.24.0-<platform> archive plus any speculor-bundle-<domain>-0.24.0-<platform> archives, and extract them all at the same install root. Bundle domains: adsb, astro, audio, sdr, passive-radar, video-sources, motion-analysis, detection, image-filters, renderers, automation, mounts, scripting, output, database, data-filters, misc-sources, oss (open-source plugins: ViBe/SuBSENSE motion + RTL-SDR).
What's changed
Application
Features
- licensing: recognise Recorder as a tier above Community
- pairing: pair a phone by a typed one-time code, over SPAKE2
- ingest: a take lands once; a repeat is replaced only on the operator's word
- recordings: a sealed phone session is verified on every import and names what changed
- recordings: a sealed session says which account signed it, and whether its key still stands
- recordings: the seal check reads as a verdict and one marked row per finding
- licensing: the key leaves plain text on Linux, into the keyring or an owner-only file
- licensing: an account client, so the desktop can sign in for its licence
- licensing: the desktop signs in for its licence; the key field and the key QR go
- cli: speculor_cli --sign-in, the device grant; --activate goes
- licensing: a machine with no internet gets its licence by hand
- analyzer: read a phone take as the phone's review does, and play its sound
- analyzer: read every lane at the pointer, scales on the left
- analyzer: a take with no microphone record plays its video's sound
- dds: a Phones tab that connects a phone in one step
- devices: mobile sensors on the network are live recipes
Bug fixes
- licensing: a subscription is not a perpetual licence
- pairing: Unpair all devices revokes at once, not at the next restart
- licensing: after signing out, the next sign-in asks who instead of reusing the browser
- analyzer: quieter overlays, and a lane's words say one thing
- analyzer: a lane's words fit beside its dial
- analyzer: drop the gravity trace's unused y, which GCC refuses
- analyzer: roll is the picture's, so a phone held sideways reads level
- analyzer: true north, whole-take sound, and a sealed take left sealed
- analyzer: the video's copy says what was done to it only where the take does
Engine SDK
Features
- BREAKING: api: add SPC_LICENSE_RECORDER between Community and Personal
Plugins
Bug fixes
- winradio: tell two receivers of the same model apart
- video_source: tell two cameras of the same model apart
Open-source plugins
Bug fixes
- rtl_sdr: tell two dongles with the same serial apart
- nesdr: tell two dongles with the same serial apart
Generated from commit history across the Speculor repos (v0.23.0 → v0.24.0).
Speculor v0.23.0
Install
Quick start (one download per platform)
Windows (x64) — speculor-0.23.0-windows-x64-full.zip. Extract and run speculor\speculor_app.exe.
Linux (x64) — speculor-0.23.0-linux-x64-full.tar.xz. Extract and run ./speculor/speculor_app.
Linux (ARM64) — speculor-0.23.0-linux-arm64-full.tar.xz. For ARM64 single-board computers (Raspberry Pi 5, Orange Pi 5 / RK3588). Extract and run ./speculor/speculor_app.
Custom install (pick the plugin domains you need)
Download the smaller speculor-0.23.0-<platform> archive plus any speculor-bundle-<domain>-0.23.0-<platform> archives, and extract them all at the same install root. Bundle domains: adsb, astro, audio, sdr, passive-radar, video-sources, motion-analysis, detection, image-filters, renderers, automation, mounts, scripting, output, database, data-filters, misc-sources, oss (open-source plugins: ViBe/SuBSENSE motion + RTL-SDR).
What's changed
Application
Features
- app: show device-scan warnings in a dialog at the scan button
- app: full-frame boresight crosshair in the Azimuth Finder preview
- app: mount-truth reference points in the Camera Azimuth Finder
- app: QR pairing for the mobile sensor — license and DDS dialogs
- recordings: Import Bundle — unzip a .spcsession into the recordings root
- ingest: LAN session-ingest receiver advertised via the DDS directory card
- replay: Session Data dock — every recorded channel at the playhead
- ingest: show an incoming session in the status bar while it lands
- dds: a stream's node segment is a name, not a number
- dds: publish exposed ports under a name, not a node id
- dds: say so when a subscribed stream has been renamed
- dds: show the key's node segment in the Console, not the ordinal
- analyzer: read a recording as an instrument, every stream on one playhead
- recordings: open a device recording straight in the Sensor Analyzer
- analyzer: show where the device was pointing and where it went
- analyzer: use the field of view the device measured, when it recorded one
- analyzer: a header that says what the recording is, and controls worth using
- logging: rotate the log daily and collapse repeated messages
- logging: expose retention, rotation size and repeat suppression
- analyzer: read a recording at its own pace, on one time axis
- profiler: show what the GUI thread is spending itself on
- preferences: bring the GPU decode and coalescing switches into the UI
- engine: report how far behind the clock each node's data is
- profiler: show how far behind live each node is, and its queue
- preferences: move the exit grace period into Reliability
Bug fixes
- app: allow camera H-FOV below 5 degrees in the Azimuth Finder
- app: account for atmospheric refraction in celestial alignment
- recording: report one MCAP loss window per loss, with its own count
- recording: choose a data codec that keeps up, and report loss honestly
- recording: open the mcap part file, and drop the SPC_RECORD_* env knobs
- recording: record what a session lost, so a lossy one cannot read as clean
- test: drop the line continuation that made the bench header one comment
- recording: warn before replaying an incomplete session, and stop a bulk stream starving the cheap ones
- recording: shrink the spool reserve so it does not cost the dominant stream
- cmake: stop every reconfigure rebuilding QtNodes and relinking the app
- licensing: migrate license slots into the portable settings store
- licensing: distinguish perpetual licenses from the cert TTL
- build: fetch the QR generator via FetchContent, not vcpkg
- build: link miniz statically
- recordings: name the recording product on the card, honestly
- ingest: require pairing, bound every input, stop opening a port by default
- pairing: decouple session push from DDS and from the license tier
- pairing: point the dialog at the phone screens that actually exist
- replay: play a phone recording's sensor streams, not just its video
- tests: bind the size pairs by reference in the layout loop
- analyzer: stop open_session reporting its own failure, and keep the layout test offline
- tests: give each analyzer layout test its own fixture directory
- engine: report pool exhaustion once per period, not once per flap
- tests: take the clock out of the envelope fixture
- replay: reach the frame before the one already on screen
- analyzer: put the recorded track and the aim where they can be read
- replay: keep the frame's predecessor across a forward walk
- ui: bound the log panel's per-tick drain
- engine: drop two env vars that overruled their own preferences
Performance
- analyzer: stop redrawing every sensor strip on every frame
- replay: decode recorded video on the GPU, upright, at the size shown
- ui: stop the node graph repainting itself
- visualization: stop antialiasing the video blit
- visualization: stop redrawing the whole canvas on every repaint
Engine SDK
Features
- expose the sender capture clock from VideoReader
- video: read the sender's in-band capture time from decoded frames
- plugins: add a windowed FpsMeter for source plugins to publish
- video: report the stream's declared display rotation
- video: decode only what the caller will look at
- video: stand emitted frames upright, on request
- gpu: let the host turn Vulkan Video decode off
Bug fixes
- video: record on a microsecond time base so files keep wall-clock timing
- video: keep the untimestamped write at the configured fps
- video: say when the frame rate is inferred rather than declared
- video: let a live source finish opening instead of giving up at 2 s
- video: stop printing camera credentials in error logs
- video: say what a silent drop to software decode costs
- video: scale the hardware-decode fallback window with the stream's rate
- gpu: stop reader reopens from sampling destroyed decode images
- video: say why a GPU-decoded read failed
- video: say how long opening a source took, step by step
- gpu: say when Vulkan validation is actually running
- video: stop asking for STORAGE on Vulkan decode images
- gpu: keep decode images alive while views on them exist
- gpu: stop SPC_GPU_DEVICE_INDEX overruling the chosen GPU
- astro: compare the two ephemeris paths by agreement, not bit-identity
- video: drop the RKMPP DRM_PRIME override
- gpu: remove the env vars that duplicate a host setting
Plugins
Features
- mount_hud: show two decimals in the AZ/EL readouts
- track_crop: crop the frame around a tracked object
- video_source: optionally timestamp frames on the sender capture clock
- track_crop: follow a designated target and pass the designation on
- temporal_sr: recover real detail from a moving subject
- track_designator: pick one track as the target, and hold it
- adsb_merge: join 1090 ES and 978 UAT feeds into one aircraft picture
- sources: report the delivered frame rate on fps_out
- adsb_events: make per-event debug logging opt-in
- video_source: stand sensor-oriented streams upright (rotation as metadata)
- video_source: say what ended a connection when reconnecting
- sort_tracker: warn when the boxes and the passthrough image disagree
Bug fixes
- sources: explain empty device scans across hardware sources
- qhy_source: bin in software on color cameras instead of cropping
- video_source: timestamp frames from the sender's capture time
- video_source: treat a zero sender clock as unknown, not 1970
- astro: timestamp frames at mid-exposure, not after readout
- live_stack: stop stack alignment decaying frame by frame
- temporal_sr: stop colour frames losing green and red
- video_source: publish nothing rather than a guessed frame rate
- video_source: count reconnect attempts instead of repeating "1 failures"
- video_source: retire the NV12 direct-sampling cache at every reader swap
- video_source: install the log bridge on the GPU decode path
- video_source: stop asking every camera about rotation on every reconnect
- video_source: stop a live source starting seconds behind
- bbox_merger: carry the image through with the boxes
- sort_tracker: bound how far the image can lag the boxes
- video_source: keep the reconnect backoff on a flapping stream
- video_source: tell the NV12 pipeline which decode pool it is on
Performance
- temporal_sr: cut the per-pixel work and size the cost guard honestly
Open-source plugins
Bug fixes
- sdr: explain every empty device scan
Generated from commit history across the Speculor repos (v0.22.0 → v0.23.0).
Speculor v0.22.0
Install
Quick start (one download per platform)
Windows (x64) — speculor-0.22.0-windows-x64-full.zip. Extract and run speculor\speculor_app.exe.
Linux (x64) — speculor-0.22.0-linux-x64-full.tar.xz. Extract and run ./speculor/speculor_app.
Linux (ARM64) — speculor-0.22.0-linux-arm64-full.tar.xz. For ARM64 single-board computers (Raspberry Pi 5, Orange Pi 5 / RK3588). Extract and run ./speculor/speculor_app.
Custom install (pick the plugin domains you need)
Download the smaller speculor-0.22.0-<platform> archive plus any speculor-bundle-<domain>-0.22.0-<platform> archives, and extract them all at the same install root. Bundle domains: adsb, astro, audio, sdr, passive-radar, video-sources, motion-analysis, detection, image-filters, renderers, automation, mounts, scripting, output, database, data-filters, misc-sources, oss (open-source plugins: ViBe/SuBSENSE motion + RTL-SDR).
What's changed
Application
Features
- recording: record which build produced a session
- recordings: show on the card which build produced a recording
- replay: keep replayed video on the GPU instead of round-tripping it
- recording: record each channel's pixel format and bit depth
- recording: record each channel's coded dimensions
Bug fixes
- app: derive display time from the engine clock, not wall clock
- recording: write the session poster from the recorder, not the GUI
- recording: re-root the container when the clock steps
- recording: key ring eviction on the file, and report what it deleted
- replay: make the frame at time t independent of how the playhead got there
- replay: deliver each frame's capture time, not the playhead
- replay: address code-review findings on the recording/replay work
- tests: drop the line-continuation backslash in the benchmark headers
- tests: give each replay fixture its own temp directory
- app: keep sub-degree precision in the Camera Azimuth Finder
- ci: keep the archives a workflow_dispatch build produces
- engine: don't warn when a node simply has no GPU path
- build: stop a failed build wiping every source dep on the next run
- recording: stop() could hang forever waiting on its own writer thread
- build: pin FetchContent nlohmann_json over the SDK's find_dependency
- engine: recover default-profile nodes from GPU device loss
- engine: demote GPU record paths that fail silently
- app: destroy the extension coordinator before the engine on exit
Performance
- replay: cut the MCAP segment default that sets seek latency
- replay: read the time window a query asks for, not the whole segment
Engine SDK
Bug fixes
- BREAKING: build: stop exporting an nlohmann link requirement consumers cannot satisfy
Features
- BREAKING: sdk: replace serialize_table with a table-walking sink
Bug fixes
- video: stop the D3D11 interop probe from killing the shared VkDevice
Features
- gpu: standalone NV12->RGB conversion for non-plugin callers
- video: hand decoded frames out as dma-buf where the decoder exports them
- gpu: import decoder dma-bufs as Vulkan images
- gpu: drive decoder dma-bufs to RGB without leaving the GPU
- gpu: bridge VideoReader dma-buf frames to the importer
- video: serve dma-buf frames through read_gpu
- dmabuf: report dma-buf import as GPU decode so video_source uses it
- sdk: add speculor_plugin_common so plugins/common has a home for code
Bug fixes
- sdk: let camera pose params hold sub-degree precision
- video: keep the dma-buf path from breaking non-Linux builds
- video: make prefer_dmabuf safe to set unconditionally
- dmabuf: allow plane views on imported NV12 so it can be sampled in place
- dmabuf: keep the AVFrame alive as long as the image that aliases it
- dmabuf: size the import ring for the engine's maximum pipeline depth
- dmabuf: stop GPU-resident decode losing the Vulkan device on RK3588
- build: pin arm64 FFmpeg to our own mirror so clean builds stop breaking
- build: add a fallback mirror for the FFmpeg source tarball
- build: clear the install prefix before packaging a bundle
Plugins
Features
- mounts: optional zoom axis in the mount core
- mount_director: zoom in on the tracked target
- mounts: steer a Wisenet network PTZ as a mount (sunapi_ptz)
- stats_monitor: lead with Speculor's own CPU and memory
- adsb_overlay: log the clicked pixel alongside the steer angle
- seestar_mount: control a ZWO Seestar S50/S30 over its network API
- video_source: expose the network stream timeout and probe limits
- super_resolve: AI super-resolution for low-resolution crops
- super_resolve: name the GPU the node actually runs on
- super_resolve: ship the realesr-general-x4v3 model with the plugin
Bug fixes
- mounts: PTZ review round — the goto/rate race and the zoom edge cases
- tests: stop the SUNAPI simulator hanging its own shutdown on Linux
- adsb_decoder: age tracks on the host clock, not a wall clock
- plugins: derive time from the pipeline, not a wall clock
- system_stats: report process CPU against the whole machine
- skywatcher_mount: report altitude as a signed angle
- plugins: let camera pose and FOV params hold sub-degree precision
- video_source: report GPU device loss and keep the camera reopenable
- build: resolve nlohmann_json before the SDK's find_dependency
- optical_flow_nv: GPU-resident output never reached the edge ring
- super_resolve: keep producing frames when the GPU path is down
- super_resolve: honour the node's GPU toggle, drop the duplicate one
- super_resolve: keep the vendored ncnn model byte-exact across checkouts
- frame_writer: keep the frame's own bit depth when writing
Open-source plugins
Features
- nesdr: add NooElec NESDR I/Q source with per-model capability gating
Generated from commit history across the Speculor repos (v0.21.0 → v0.22.0).
Speculor v0.21.0
Install
Quick start (one download per platform)
Windows (x64) — speculor-0.21.0-windows-x64-full.zip. Extract and run speculor\speculor_app.exe.
Linux (x64) — speculor-0.21.0-linux-x64-full.tar.xz. Extract and run ./speculor/speculor_app.
Linux (ARM64) — speculor-0.21.0-linux-arm64-full.tar.xz. For ARM64 single-board computers (Raspberry Pi 5, Orange Pi 5 / RK3588). Extract and run ./speculor/speculor_app.
Custom install (pick the plugin domains you need)
Download the smaller speculor-0.21.0-<platform> archive plus any speculor-bundle-<domain>-0.21.0-<platform> archives, and extract them all at the same install root. Bundle domains: adsb, astro, audio, sdr, passive-radar, video-sources, motion-analysis, detection, image-filters, renderers, automation, mounts, scripting, output, database, data-filters, misc-sources, oss (open-source plugins: ViBe/SuBSENSE motion + RTL-SDR).
What's changed
Application
Features
- azimuth-finder: calibrate all-sky cameras from their image circle
- azimuth-finder: give the frame preview room and make the map aim readable
- tools: Live streaming in the Zone Editor, and window buttons on both editors
- engine: notify consumers when the pipeline starts and stops
Bug fixes
- azimuth-finder: solve camera pose on SO(3) so the zenith is not singular
- tools: close the defects the Live refactor introduced
- tools: convert 16-bit camera frames instead of scrambling them
- tools: review round 3 — button state, stale lists, and the BGR hot path
- azimuth-finder: qualify ptrdiff_t so the disc detector builds under gcc
- presets: reset params a preset predates to their descriptor defaults
Engine SDK
Features
- geo: describe all-sky cameras by their image circle
Plugins
Features
- camera: carry the all-sky image circle in frame metadata
- adsb: drop the FOV cone from the compass on an all-sky camera
- mounts: add Celestron NexStar mount control
- roi_filter: blur the masked region instead of blacking it out
Bug fixes
- mounts: stop a wrong serial port from freezing pipeline start
- mounts: match the shared target defaults to the descriptor
- mounts: correct the ZWO equatorial rate frame and stop the axis pulsing
- mount_director: carry the all-sky image circle into the view gate
Generated from commit history across the Speculor repos (v0.20.3 → v0.21.0).
Speculor v0.20.3
Install
Quick start (one download per platform)
Windows (x64) — speculor-0.20.3-windows-x64-full.zip. Extract and run speculor\speculor_app.exe.
Linux (x64) — speculor-0.20.3-linux-x64-full.tar.xz. Extract and run ./speculor/speculor_app.
Linux (ARM64) — speculor-0.20.3-linux-arm64-full.tar.xz. For ARM64 single-board computers (Raspberry Pi 5, Orange Pi 5 / RK3588). Extract and run ./speculor/speculor_app.
Custom install (pick the plugin domains you need)
Download the smaller speculor-0.20.3-<platform> archive plus any speculor-bundle-<domain>-0.20.3-<platform> archives, and extract them all at the same install root. Bundle domains: adsb, astro, audio, sdr, passive-radar, video-sources, motion-analysis, detection, image-filters, renderers, automation, mounts, scripting, output, database, data-filters, misc-sources, oss (open-source plugins: ViBe/SuBSENSE motion + RTL-SDR).
What's changed
Application
Features
- engine: report per-port output consumers to plugins
- sapient: give net::Conn a bounded readiness wait
Bug fixes
- sapient: ignore SIGPIPE so a peer disconnect cannot kill the engine
- sapient: poll before accept so the HLDMM stop path cannot hang
- ci: skip the deploy phase so the gate ignores sibling repos
- sapient: bound the ASM reader so stop() cannot deadlock
- sapient: bound the HLDMM client loop without losing heartbeat eviction
Engine SDK
Bug fixes
- testing: stop the conformance suite asserting unreachable states
- build: stop flagging partially initialized structs under GNU
Bug fixes
- deps: declare OpenCV's real ISA baseline
Bug fixes
- packaging: build published bundles for a portable ISA baseline
Features
- testing: add a header-only plugin test harness
- cmake: add spc_add_plugin_test for harness consumers
Performance
- spclib: sweep the blob seam merge instead of scanning it
- spclib: flood fill blobs a run at a time, not a pixel at a time
Features
- sdk: tell plugins which output ports anything is reading
Performance
- spclib: halve Horn-Schunck's memory traffic per SOR iteration
Bug fixes
- package: make the SDK bundle relocatable and link OpenCV's jpeg
Features
- spclib: let Pcg32 callers choose where they enter the table
Bug fixes
- package: define the CURL target the SDK bundle's export requires
Performance
- spclib: align Pcg32 to a cache line to stop false sharing
Plugins
Features
- qhy_source: add opt-in per-phase frame timing
- sky_object_detect: add opt-in per-phase frame timing
Bug fixes
- object_classifier: stop demanding a class prior that is meant to be optional
- bbox_merger: keep frame number and timestamp on detection-free frames
- sources: make the ROI parameters readable
- database: report SPC_ERR_NOT_FOUND for unknown parameter names
- build: clear the build warnings, keep ncnn out of LTO
Performance
- optical_flow: skip the flow visualisation when nothing reads it
- optical_flow: skip the flow angle and the NVOFA visualisation when unread
- mog2_bgs,wmv_bgs: give the GPU shaders one row per workgroup
- image_stabilizer: skip the valid-region mask when nothing reads it
- sky_object_detect: extract blobs with contours by default
- sky_object_detect: extract blobs with spclib's detector by default
- sdr_spectrum: blend signal markers only over the columns they touch
- sdr_spectrum: stop reallocating the spectrum fill buffer every frame
Open-source plugins
Bug fixes
- vibe_bgs: stop every worker drawing the same random sequence
Performance
- vibe_bgs: give the GPU process shader one row per workgroup
- vibe_bgs: clear the GPU mask up front instead of per pixel
- vibe_bgs: write the GPU model a word at a time, not a byte at a time
Generated from commit history across the Speculor repos (v0.20.2 → v0.20.3).