TASK 4 ship step 5.5: social bar bug fixes + bar on the live output — direction-snap drag (SocialBarSnap.Decide + ClearValue, local Canvas.Top was overriding the binding), fediverse nodeinfo subdomain probing + load-time heal (settable FediverseSoftware), SocialBarRenderer strip blitted above the flash via a re-read FramePump socialBar seam — 155 tests passing, 0 warnings
This commit is contained in:
@@ -28,6 +28,7 @@ public sealed class FramePump : IDisposable
|
||||
private readonly Func<IFfmpegEncoder> _encoderFactory;
|
||||
private readonly Action<string>? _log;
|
||||
private readonly Func<TimeSpan, CancellationToken, Task> _pacingDelay;
|
||||
private readonly Func<(VideoFrame? Frame, SocialBarPosition Position)>? _socialBar;
|
||||
private readonly SceneCompositor _compositor = new();
|
||||
|
||||
private readonly object _gate = new();
|
||||
@@ -49,7 +50,8 @@ public sealed class FramePump : IDisposable
|
||||
Func<EncoderOptions?> encoderOptions,
|
||||
Func<IFfmpegEncoder> encoderFactory,
|
||||
Action<string>? log = null,
|
||||
Func<TimeSpan, CancellationToken, Task>? pacingDelay = null)
|
||||
Func<TimeSpan, CancellationToken, Task>? pacingDelay = null,
|
||||
Func<(VideoFrame? Frame, SocialBarPosition Position)>? socialBar = null)
|
||||
{
|
||||
_sceneProvider = sceneProvider ?? throw new ArgumentNullException(nameof(sceneProvider));
|
||||
_frameResolver = frameResolver ?? throw new ArgumentNullException(nameof(frameResolver));
|
||||
@@ -58,6 +60,7 @@ public sealed class FramePump : IDisposable
|
||||
_encoderFactory = encoderFactory ?? throw new ArgumentNullException(nameof(encoderFactory));
|
||||
_log = log;
|
||||
_pacingDelay = pacingDelay ?? ((delay, ct) => Task.Delay(delay, ct));
|
||||
_socialBar = socialBar;
|
||||
}
|
||||
|
||||
public bool IsRunning { get; private set; }
|
||||
@@ -212,7 +215,20 @@ public sealed class FramePump : IDisposable
|
||||
var scene = _sceneProvider();
|
||||
if (scene != null)
|
||||
{
|
||||
var frame = _compositor.Render(scene, _frameResolver, null, _compositorOptions());
|
||||
var compositorOptions = _compositorOptions();
|
||||
VideoFrame? socialBarFrame = null;
|
||||
var socialBarTop = 0;
|
||||
if (_socialBar != null)
|
||||
{
|
||||
var (barFrame, position) = _socialBar();
|
||||
socialBarFrame = barFrame;
|
||||
if (barFrame != null)
|
||||
socialBarTop = position == SocialBarPosition.Top
|
||||
? 0
|
||||
: compositorOptions.SourceRectHeight - barFrame.Height;
|
||||
}
|
||||
var frame = _compositor.Render(
|
||||
scene, _frameResolver, null, compositorOptions, socialBarFrame, socialBarTop);
|
||||
IFfmpegEncoder? encoder;
|
||||
lock (_gate) encoder = _encoder;
|
||||
if (encoder == null) break; // _encoder is only cleared after the loop ends; defensive
|
||||
|
||||
Reference in New Issue
Block a user