feat: add alpha probe diagnostics to webcam frame capture
Co-authored-by: aider (openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
This commit is contained in:
@@ -267,6 +267,9 @@ public sealed class MediaCaptureFrameSource : ICameraFrameSource
|
|||||||
private int _ringNext;
|
private int _ringNext;
|
||||||
private long _epoch;
|
private long _epoch;
|
||||||
|
|
||||||
|
// Alpha probe diagnostics (one-shot, throttled)
|
||||||
|
private DateTime _lastAlphaProbe = DateTime.MinValue;
|
||||||
|
|
||||||
private byte[] RentRingBuffer(int size)
|
private byte[] RentRingBuffer(int size)
|
||||||
{
|
{
|
||||||
for (var tries = 0; tries < _frameRing.Length; tries++)
|
for (var tries = 0; tries < _frameRing.Length; tries++)
|
||||||
@@ -304,6 +307,15 @@ public sealed class MediaCaptureFrameSource : ICameraFrameSource
|
|||||||
{
|
{
|
||||||
var pixels = RentRingBuffer((int)capacity);
|
var pixels = RentRingBuffer((int)capacity);
|
||||||
Marshal.Copy(pixelsPtr, pixels, 0, (int)capacity);
|
Marshal.Copy(pixelsPtr, pixels, 0, (int)capacity);
|
||||||
|
|
||||||
|
// Alpha probe diagnostics (throttled to once per 5s)
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
if ((now - _lastAlphaProbe).TotalSeconds >= 5.0)
|
||||||
|
{
|
||||||
|
_lastAlphaProbe = now;
|
||||||
|
ProbeAlphaStats(pixels, bitmap.PixelWidth, bitmap.PixelHeight);
|
||||||
|
}
|
||||||
|
|
||||||
// MediaCapture video carries no alpha plane — the OS fills 255.
|
// MediaCapture video carries no alpha plane — the OS fills 255.
|
||||||
FrameAvailable?.Invoke(new VideoFrame(bitmap.PixelWidth, bitmap.PixelHeight, pixels)
|
FrameAvailable?.Invoke(new VideoFrame(bitmap.PixelWidth, bitmap.PixelHeight, pixels)
|
||||||
{ IsOpaque = true, Epoch = ++_epoch });
|
{ IsOpaque = true, Epoch = ++_epoch });
|
||||||
@@ -319,4 +331,37 @@ public sealed class MediaCaptureFrameSource : ICameraFrameSource
|
|||||||
bitmap.Dispose();
|
bitmap.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ProbeAlphaStats(byte[] pixels, int width, int height)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Sample 1000 alpha bytes (every 4th byte in BGRA format)
|
||||||
|
var sampleCount = Math.Min(1000, pixels.Length / 4);
|
||||||
|
var alphaMin = 255;
|
||||||
|
var alphaMax = 0;
|
||||||
|
var alphaSum = 0;
|
||||||
|
|
||||||
|
for (var i = 0; i < sampleCount; i++)
|
||||||
|
{
|
||||||
|
var alphaIndex = (i * 4) + 3; // Alpha is 4th byte in BGRA
|
||||||
|
if (alphaIndex < pixels.Length)
|
||||||
|
{
|
||||||
|
var alpha = pixels[alphaIndex];
|
||||||
|
alphaMin = Math.Min(alphaMin, alpha);
|
||||||
|
alphaMax = Math.Max(alphaMax, alpha);
|
||||||
|
alphaSum += alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var alphaMean = sampleCount > 0 ? alphaSum / (double)sampleCount : 0;
|
||||||
|
AppLog.Write($"Webcam alpha probe: {width}x{height}, epoch {_epoch}, " +
|
||||||
|
$"alpha[min={alphaMin}, max={alphaMax}, mean={alphaMean:F1}], " +
|
||||||
|
$"sampled {sampleCount} pixels");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
AppLog.Write($"Webcam alpha probe failed: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user