using Xunit; using ytLive.Models; using ytLive.Services; using ytLive.Services.Compositor; namespace ytLive.Tests; /// /// The universal privacy blur at the compositor level (creator ruling 2026-11-01): it blankets /// every layer beneath it, and the brand logo — blitted after the blur — is never swallowed. /// public class BlurCompositorTests { private static VideoFrame Solid(int w, int h, byte r, byte g, byte b) { var pixels = new byte[w * h * 4]; for (var i = 0; i < pixels.Length; i += 4) { pixels[i] = b; pixels[i + 1] = g; pixels[i + 2] = r; pixels[i + 3] = 255; } return new VideoFrame(w, h, pixels); } /// Hard left/right colour split — blurring is unmistakable on it. private static VideoFrame Split(int w, int h, byte lr, byte lg, byte lb, byte rr, byte rg, byte rb) { var pixels = new byte[w * h * 4]; var half = w / 2; for (var y = 0; y < h; y++) for (var x = 0; x < w; x++) { var i = (y * w + x) * 4; pixels[i] = x < half ? lb : rb; pixels[i + 1] = x < half ? lg : rg; pixels[i + 2] = x < half ? lr : rr; pixels[i + 3] = 255; } return new VideoFrame(w, h, pixels); } private static void AssertPixel(VideoFrame frame, int x, int y, byte r, byte g, byte b) { var i = (y * frame.Width + x) * 4; Assert.True( frame.BgraPixels[i + 2] == r && frame.BgraPixels[i + 1] == g && frame.BgraPixels[i] == b, $"pixel ({x},{y}): expected rgb({r},{g},{b}), got rgb({frame.BgraPixels[i + 2]},{frame.BgraPixels[i + 1]},{frame.BgraPixels[i]})"); } [Fact] public void The_blur_covers_what_is_beneath_it_and_never_the_brand_logo() { var stripes = Split(1920, 1080, 0, 0, 255, 0, 255, 0); // blue | green, hard edge at x=960 var brand = Solid(120, 60, 255, 255, 255); // white logo var background = new Source { Type = SourceType.DisplayCapture, IsBackground = true, CaptureKey = "monitor:0" }; var logo = new Source { Type = SourceType.Image, IsBrandLogo = true, X = 900, Y = 500, Width = 120, Height = 60 }; var blur = new Source { Type = SourceType.Blur, X = 700, Y = 400, Width = 600, Height = 300, BlurAmount = 1.0 }; var scene = new Scene { Name = "Live" }; scene.Elements.Add(background); scene.Elements.Add(logo); scene.Elements.Add(blur); VideoFrame? FrameFor(SceneElement e) => e switch { Source { IsBackground: true } => stripes, Source { IsBrandLogo: true } => brand, _ => null, }; var options = new CompositorOptions { SourceRectX = 0, SourceRectY = 0, SourceRectWidth = 1920, SourceRectHeight = 1080, OutputWidth = 1920, OutputHeight = 1080, }; var output = new SceneCompositor().Render(scene, FrameFor, null, options); // 1. Inside the blur, over the colour edge: blended, not the hard split. var i = (450 * output.Width + 950) * 4; Assert.True(output.BgraPixels[i] > 0 && output.BgraPixels[i + 1] > 0, "a blurred pixel on the colour edge must be a blend of both sides"); // 2. The logo, sitting inside the blur's area, is untouched. AssertPixel(output, 950, 530, 255, 255, 255); } }