feat(pipeline): add SolidFrameRenderer slate and IFrameScaler/PassthroughFrameScaler
Some checks failed
CI / build-and-test (push) Failing after 25s

This commit is contained in:
Zac Gaetano 2026-05-07 15:14:37 +00:00
parent 1b280e3e77
commit 970f04861d
4 changed files with 72 additions and 0 deletions

View file

@ -0,0 +1,8 @@
using TeamsISO.Engine.Domain;
namespace TeamsISO.Engine.Pipeline;
public interface IFrameScaler
{
ProcessedFrame Scale(RawFrame source, int targetWidth, int targetHeight, AspectMode aspect, long timestampTicks);
}

View file

@ -0,0 +1,20 @@
using TeamsISO.Engine.Domain;
namespace TeamsISO.Engine.Pipeline;
/// <summary>
/// Phase A scaler. Copies the source frame's pixel buffer through unchanged and tags the
/// output with the requested target dimensions. Real scaling is added in Phase B against libyuv.
/// </summary>
public sealed class PassthroughFrameScaler : IFrameScaler
{
public ProcessedFrame Scale(RawFrame source, int targetWidth, int targetHeight, AspectMode aspect, long timestampTicks)
{
return new ProcessedFrame(
Width: targetWidth,
Height: targetHeight,
TimestampTicks: timestampTicks,
Pixels: source.Pixels,
Format: source.Format == PixelFormat.Bgra ? PixelFormat.Bgra : PixelFormat.Bgra);
}
}

View file

@ -0,0 +1,20 @@
namespace TeamsISO.Engine.Pipeline;
/// <summary>
/// Generates a solid-color BGRA frame for use as a "no signal" slate.
/// </summary>
public sealed class SolidFrameRenderer
{
public ProcessedFrame Render(int width, int height, byte b, byte g, byte r, byte a, long timestampTicks)
{
var pixels = new byte[width * height * 4];
for (var i = 0; i < pixels.Length; i += 4)
{
pixels[i + 0] = b;
pixels[i + 1] = g;
pixels[i + 2] = r;
pixels[i + 3] = a;
}
return new ProcessedFrame(width, height, timestampTicks, pixels, PixelFormat.Bgra);
}
}

View file

@ -0,0 +1,24 @@
using TeamsISO.Engine.Pipeline;
namespace TeamsISO.Engine.Tests.Pipeline;
public class SolidFrameRendererTests
{
[Fact]
public void Render_ProducesBgraFrameOfTargetSize_FilledWithColor()
{
var renderer = new SolidFrameRenderer();
var frame = renderer.Render(width: 1920, height: 1080, b: 0x80, g: 0x80, r: 0x80, a: 0xFF, timestampTicks: 12345);
frame.Width.Should().Be(1920);
frame.Height.Should().Be(1080);
frame.Format.Should().Be(PixelFormat.Bgra);
frame.Pixels.Length.Should().Be(1920 * 1080 * 4);
frame.TimestampTicks.Should().Be(12345);
var span = frame.Pixels.Span;
span[0].Should().Be(0x80); span[1].Should().Be(0x80); span[2].Should().Be(0x80); span[3].Should().Be(0xFF);
var last = span.Length - 4;
span[last].Should().Be(0x80); span[last + 3].Should().Be(0xFF);
}
}