libdisplay_info/
gtf.rs

1//! Low-level API for Generalized Timing Formula Standard version 1.1.
2use std::mem::MaybeUninit;
3
4use libdisplay_info_derive::FFIFrom;
5
6use crate::ffi;
7
8pub const DEFAULT_M: f64 = 600.0;
9pub const DEFAULT_C: f64 = 40.0;
10pub const DEFAULT_K: f64 = 128.0;
11pub const DEFAULT_J: f64 = 20.0;
12
13/// Type of frequency parameter used in di_gtf_options.ip_freq_rqd.
14#[derive(Debug, Clone, Copy, PartialEq, Eq, FFIFrom)]
15#[ffi(ffi::gtf::di_gtf_ip_param)]
16#[repr(u32)]
17pub enum IpParam {
18    /// Vertical frame frequency (Hz)
19    VFrameRate = ffi::gtf::di_gtf_ip_param_DI_GTF_IP_PARAM_V_FRAME_RATE,
20    /// Horizontal frequency (kHz)
21    HFreq = ffi::gtf::di_gtf_ip_param_DI_GTF_IP_PARAM_H_FREQ,
22    /// Pixel clock rate (MHz)
23    HPixels = ffi::gtf::di_gtf_ip_param_DI_GTF_IP_PARAM_H_PIXELS,
24}
25
26/// Input options for GTF.
27#[derive(Debug, Copy, Clone, FFIFrom)]
28#[ffi(ffi::gtf::di_gtf_options)]
29pub struct Options {
30    /// Number of active image pixels displayed on a line, not including any margin
31    pub h_pixels: i32,
32    /// Number of vertical lines in the displayed image
33    pub v_lines: i32,
34    /// Whether margins are required
35    pub margins_rqd: bool,
36    /// Indicates which frequency parameter is specified in ip_freq_rqd
37    pub ip_param: IpParam,
38    /// Vertical frame frequency (in Hz), horizontal frequency (in kHz) or pixel clock rate (in MHz)
39    pub ip_freq_rqd: f64,
40    /// Whether interlaced is required
41    pub int_rqd: bool,
42    /// Blanking formula gradient
43    pub m: f64,
44    /// Blanking formula offset
45    pub c: f64,
46    /// Blanking formula scaling factor
47    pub k: f64,
48    /// Blanking formula scaling factor weighting
49    pub j: f64,
50}
51
52/// Output timing data for GTF.
53#[derive(Debug, Copy, Clone, FFIFrom)]
54#[ffi(ffi::gtf::di_gtf_timing)]
55pub struct Timing {
56    pub h_pixels: i32,
57    pub v_lines: i32,
58    pub h_sync: i32,
59    pub v_sync: i32,
60    pub h_front_porch: i32,
61    pub h_back_porch: i32,
62    pub v_front_porch: i32,
63    pub v_back_porch: i32,
64    pub h_border: i32,
65    pub v_border: i32,
66    pub pixel_freq_mhz: f64,
67}
68
69impl Timing {
70    /// Compute a timing via the GTF formula.
71    pub fn compute(options: Options) -> Self {
72        let mut timing = MaybeUninit::<ffi::gtf::di_gtf_timing>::uninit();
73        let options = ffi::gtf::di_gtf_options {
74            h_pixels: options.h_pixels,
75            v_lines: options.v_lines,
76            margins_rqd: options.margins_rqd,
77            ip_param: options.ip_param as u32,
78            ip_freq_rqd: options.ip_freq_rqd,
79            int_rqd: options.int_rqd,
80            m: options.m,
81            c: options.c,
82            k: options.k,
83            j: options.j,
84        };
85        unsafe {
86            ffi::gtf::di_gtf_compute(timing.as_mut_ptr(), &options);
87        }
88        Timing::from(unsafe { timing.assume_init() })
89    }
90}