diff --git a/src/Dragon-ISO.Engine/Domain/FrameProcessingSettings.cs b/src/Dragon-ISO.Engine/Domain/FrameProcessingSettings.cs
index d675978..c00cef8 100644
--- a/src/Dragon-ISO.Engine/Domain/FrameProcessingSettings.cs
+++ b/src/Dragon-ISO.Engine/Domain/FrameProcessingSettings.cs
@@ -23,6 +23,27 @@ public sealed record FrameProcessingSettings(
_ => throw new InvalidOperationException($"Unknown framerate: {Framerate}")
};
+ ///
+ /// Returns the framerate as an exact rational (numerator / denominator), as
+ /// required by the NDI sender's frame_rate_N / frame_rate_D and
+ /// by container muxers. The broadcast fractional rates are 1000/1001 pulldowns
+ /// of their integer parents (e.g. 59.94 = 60000/1001), so we must carry the
+ /// rational rather than a rounded double — advertising
+ /// 60/1 for a 59.94 stream causes drift and A/V desync downstream.
+ ///
+ public (int Numerator, int Denominator) FrameRate => Framerate switch
+ {
+ TargetFramerate.Fps23_976 => (24000, 1001),
+ TargetFramerate.Fps24 => (24, 1),
+ TargetFramerate.Fps25 => (25, 1),
+ TargetFramerate.Fps29_97 => (30000, 1001),
+ TargetFramerate.Fps30 => (30, 1),
+ TargetFramerate.Fps50 => (50, 1),
+ TargetFramerate.Fps59_94 => (60000, 1001),
+ TargetFramerate.Fps60 => (60, 1),
+ _ => throw new InvalidOperationException($"Unknown framerate: {Framerate}")
+ };
+
/// Returns the resolution as (width, height).
public (int Width, int Height) ResolutionSize => Resolution switch
{