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 {