Skip to content

Commit 9f064d7

Browse files
Melissa Bellclaude
authored andcommitted
Derive NDI FourCC from snapshot pixel format instead of OS check
Rather than inferring the pixel channel order from the OS platform, read it directly from the Bitmap.Format of the compositor snapshot. The backend decides the layout (BGRA on D3D, RGBA on Metal) and Format reflects this, so the FourCC now tracks any future backend changes automatically without manual platform guards. Adds FourCC to PendingFrame so the send thread uses the value recorded at capture time. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 9f2494e commit 9f064d7

1 file changed

Lines changed: 15 additions & 6 deletions

File tree

‎EmoTracker/Extensions/NDI/NdiSendContainer.cs‎

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Avalonia;
22
using Avalonia.Controls;
33
using Avalonia.Media.Imaging;
4+
using Avalonia.Platform;
45
using Avalonia.Rendering.Composition;
56
using Avalonia.Threading;
67
using NewTek; // NDIlib + nested types
@@ -202,6 +203,7 @@ private struct PendingFrame
202203
public int FrameRateNum, FrameRateDen;
203204
public int Scale;
204205
public bool DropShadow;
206+
public NDIlib.FourCC_type_e FourCC;
205207
}
206208

207209
// -------------------------------------------------------------------------
@@ -434,6 +436,14 @@ public async Task TriggerCaptureAsync()
434436
if (snapshot == null || _disposed)
435437
return;
436438

439+
// Derive the NDI pixel format from the snapshot's reported format rather
440+
// than inferring it from the OS. The compositor backend decides channel
441+
// order (BGRA on Windows/D3D, RGBA on macOS/Metal), and reading it here
442+
// handles any future backend changes automatically.
443+
NDIlib.FourCC_type_e ndiFormat = snapshot.Format == PixelFormat.Rgba8888
444+
? NDIlib.FourCC_type_e.FourCC_type_RGBA
445+
: NDIlib.FourCC_type_e.FourCC_type_BGRA;
446+
437447
int width = snapshot.PixelSize.Width;
438448
int height = snapshot.PixelSize.Height;
439449
int stride = width * 4;
@@ -488,6 +498,7 @@ public async Task TriggerCaptureAsync()
488498
FrameRateDen = NdiFrameRateDenominator,
489499
Scale = Math.Max(NdiIntegerScale, 1),
490500
DropShadow = NdiDropShadow,
501+
FourCC = ndiFormat,
491502
});
492503

493504
LogCaptureHeartbeat(width, height);
@@ -575,12 +586,10 @@ private void ProcessOneFrame()
575586
{
576587
xres = scaledWidth,
577588
yres = scaledHeight,
578-
// Avalonia's Metal backend (macOS/Linux) produces RGBA pixels;
579-
// the Windows D3D/Skia backend produces BGRA. Tell NDI which
580-
// layout the bytes are actually in so colours render correctly.
581-
FourCC = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
582-
? NDIlib.FourCC_type_e.FourCC_type_BGRA
583-
: NDIlib.FourCC_type_e.FourCC_type_RGBA,
589+
// FourCC is derived from the snapshot's reported pixel format at
590+
// capture time — see TriggerCaptureAsync — so it matches whatever
591+
// the compositor backend actually produced.
592+
FourCC = frame.FourCC,
584593
frame_rate_N = frame.FrameRateNum,
585594
frame_rate_D = frame.FrameRateDen,
586595
picture_aspect_ratio = (float)frame.Width / frame.Height,

0 commit comments

Comments
 (0)