Mimir/docs/obs-stem-plugin.md

162 lines
5.1 KiB
Markdown
Raw Normal View History

2026-05-27 21:28:15 +01:00
# OBS Native Plugin
2026-05-27 20:55:48 +01:00
2026-05-27 21:28:15 +01:00
The production OBS path is a Mimir/Fensalir-owned program texture plus a
Mimir/Fensalir-owned stem bus, exposed through a narrow native OBS plugin.
2026-05-27 20:55:48 +01:00
## Authority
2026-05-27 21:28:15 +01:00
- Fensalir owns the completed program pixels.
2026-05-27 20:55:48 +01:00
- Mimir/Fensalir own timing, alignment, DSP, and stem identity.
- OBS owns broadcast mixing and scene composition.
2026-05-27 21:28:15 +01:00
- The plugin imports already-produced program pixels and reads already-processed
stem samples. It does not synchronize raw sources, estimate clocks, render the
field, or decide which payload is true.
2026-05-27 20:55:48 +01:00
## Current Contract
2026-05-27 21:28:15 +01:00
### Video
Fensalir publishes the completed backbuffer into a named shared D3D12
`B8G8R8A8_UNorm` texture when these environment variables are set:
```text
FENSALIR_PROGRAM_OUTPUT_D3D12=1
FENSALIR_PROGRAM_OUTPUT_NAME=Global\MimirFensalirProgramTexture
```
The native OBS plugin in `native/obs_stem_source` exposes a `Mimir Program
Texture` video source. Set:
```text
Shared D3D12 texture name: Global\MimirFensalirProgramTexture
2026-05-27 23:56:42 +01:00
Shared D3D12 fence name: Global\MimirFensalirProgramFence
Consumer D3D12 fence name: Global\MimirObsProgramConsumerFence
2026-05-28 00:04:52 +01:00
Texture ring slots: 1
2026-05-27 21:28:15 +01:00
```
OBS/libobs is D3D11 internally on Windows, so this source opens the named D3D12
2026-05-27 23:34:44 +01:00
texture, creates an OBS-readable legacy shared D3D11 texture, opens that same
bridge texture from D3D12, and performs a GPU-to-GPU copy during OBS render
before drawing the source. This avoids CPU readback and does not require
Spout2. It is not pure zero-copy yet; the remaining copy is the
2026-05-28 00:09:39 +01:00
D3D12-to-libobs-D3D11 boundary. Fensalir also publishes a named D3D12
program-output fence; the OBS source opens it and observes publication
completion before copying. This prevents blind read-before-producer-completion
behavior without coupling OBS to Fensalir's private frame fence.
2026-05-27 21:28:15 +01:00
2026-05-28 00:04:52 +01:00
For OBS-only stress testing, Fensalir and the OBS source can agree on a bounded
texture ring:
```text
FENSALIR_PROGRAM_OUTPUT_RING_COUNT=3
FENSALIR_PROGRAM_OUTPUT_CONSUMER_FENCE_NAME=Global\MimirObsProgramConsumerFence
2026-05-28 00:04:52 +01:00
Texture ring slots: 3
Consumer D3D12 fence name: Global\MimirObsProgramConsumerFence
2026-05-28 00:04:52 +01:00
```
With a ring count above one, Fensalir publishes textures named
`Global\MimirFensalirProgramTexture.0`, `.1`, and so on. The OBS source uses the
program-output fence value to copy the latest completed slot and signals the
consumer fence after its GPU copy. When Fensalir is launched with the matching
consumer-fence environment variable, it will not reuse a ring slot until OBS has
acknowledged a copy at or beyond that slot's published fence value. Leave the
ring count at `1` for EVE until the EVE relay speaks the same ring contract.
2026-05-28 00:04:52 +01:00
2026-05-27 23:34:44 +01:00
For a visible interop witness while the real Mimir scene is sparse, launch
Mimir with:
```text
MIMIR_OBS_PROOF_VISUAL=1
```
That enables a small bright SDF/starfield proof visual. It is a debug witness,
not production scene policy.
2026-05-27 21:28:15 +01:00
### Audio
2026-05-27 20:55:48 +01:00
`MimirObsStemSharedMemoryPublisher` writes the latest validated
`MimirObsStemPublicationSnapshot` into a Windows shared-memory map named
`Local\MimirObsStemBus` by default. The native OBS plugin in
2026-05-27 21:28:15 +01:00
`native/obs_stem_source` exposes a `Mimir Audio Stem` input source. Add one
source per stem and set:
2026-05-27 20:55:48 +01:00
```text
Shared memory map: Local\MimirObsStemBus
Stem id: aligned_source_0
```
Use `aligned_source_0` through `aligned_source_5` for the first actuator-stage
source lanes.
## Build
```powershell
2026-05-27 21:04:43 +01:00
.\scripts\build-obs-stem-plugin.ps1
2026-05-27 20:55:48 +01:00
```
2026-05-27 21:04:43 +01:00
The script stages `obsproject/obs-plugintemplate` under `artifacts/obs-sdk/`,
lets the upstream template fetch/build the matching OBS/libobs development
surface, then builds `native/obs_stem_source` against that SDK. The staged SDK
and native build products are local artifacts, not repository state.
The managed shared-memory publisher is verified by:
2026-05-27 20:55:48 +01:00
```powershell
dotnet run --no-build --project .\src\Mimir.BufferSmoke\Mimir.BufferSmoke.csproj -- --obs-stem-shared-memory-smoke
```
2026-05-27 21:04:43 +01:00
The local native plugin build currently succeeds and emits:
```text
native\obs_stem_source\build\Release\mimir_obs_stem_source.dll
```
2026-05-27 21:28:15 +01:00
That DLL currently registers both source types:
```text
Mimir Program Texture
Mimir Audio Stem
2026-06-08 21:01:48 +01:00
Muninn Stream
2026-05-27 21:28:15 +01:00
```
2026-05-27 21:29:23 +01:00
2026-06-08 21:01:48 +01:00
### Muninn Streams
2026-06-08 21:31:25 +01:00
The `Muninn Stream` source is a thin OBS wrapper over Muninn's typed
CultCache/CultMesh stream catalog. It reads Muninn's local `.cc` store:
2026-06-08 21:01:48 +01:00
```text
2026-06-08 21:31:25 +01:00
C:\Meta\Odin\state\muninn.telemetry.cc
2026-06-08 21:01:48 +01:00
```
2026-06-08 21:31:25 +01:00
The source looks for record key `obs` with type:
2026-06-08 21:01:48 +01:00
```text
2026-06-08 21:31:25 +01:00
muninn.obs_stream_catalog
2026-06-08 21:01:48 +01:00
```
2026-06-08 21:31:25 +01:00
Muninn owns that catalog as typed CultCache state. OBS owns only the selected
scene source and media rendering. The source does not probe devices and does
not activate streams by itself; use Muninn's explicit activation command before
selecting a stream that requires capture resources.
2026-06-08 21:01:48 +01:00
2026-05-27 21:29:23 +01:00
## Install
2026-05-27 21:30:31 +01:00
For the standard OBS plugin search path:
2026-05-27 21:29:23 +01:00
```powershell
.\scripts\install-obs-mimir-plugin.ps1
```
2026-05-27 21:30:31 +01:00
By default this writes:
```text
C:\ProgramData\obs-studio\plugins\mimir_obs_stem_source\bin\64bit\mimir_obs_stem_source.dll
```
For a portable OBS tree or direct OBS installation root:
2026-05-27 21:29:23 +01:00
```powershell
.\scripts\install-obs-mimir-plugin.ps1 -ObsRoot D:\Tools\obs-studio
```
2026-05-27 21:30:31 +01:00
The script does not create scene items or alter OBS profiles.