Skip to main content

x264_next/setup/
mod.rs

1use core::ffi::c_char;
2use core::mem::MaybeUninit;
3use x264::*;
4use {Encoder, Encoding, Error, Result};
5
6mod preset;
7mod tune;
8
9pub use self::preset::*;
10pub use self::tune::*;
11
12/// Builds a new encoder.
13pub struct Setup {
14    raw: x264_param_t,
15}
16
17impl Setup {
18    /// Creates a new builder with the specified preset and tune.
19    pub fn preset(preset: Preset, tune: Tune, fast_decode: bool, zero_latency: bool) -> Self {
20        let mut raw = MaybeUninit::uninit();
21
22        // Name validity verified at compile-time.
23        assert_eq!(0, unsafe {
24            x264_param_default_preset(
25                raw.as_mut_ptr(),
26                preset.to_cstr() as *const c_char,
27                tune.to_cstr(fast_decode, zero_latency) as *const c_char,
28            )
29        });
30
31        Self {
32            raw: unsafe { raw.assume_init() },
33        }
34    }
35
36    /// Makes the first pass faster.
37    pub fn fastfirstpass(mut self) -> Self {
38        unsafe {
39            x264_param_apply_fastfirstpass(&mut self.raw);
40        }
41        self
42    }
43
44    /// The video's framerate, represented as a rational number.
45    ///
46    /// The value is in frames per second.
47    pub fn fps(mut self, num: u32, den: u32) -> Self {
48        self.raw.i_fps_num = num;
49        self.raw.i_fps_den = den;
50        self
51    }
52
53    /// The encoder's timebase, used in rate control with timestamps.
54    ///
55    /// The value is in seconds per tick.
56    pub fn timebase(mut self, num: u32, den: u32) -> Self {
57        self.raw.i_timebase_num = num;
58        self.raw.i_timebase_den = den;
59        self
60    }
61
62    /// Enabel/disable Annex B start codes.
63    /// 
64    /// More information at [https://github.com/quadrupleslap/x264/issues/4](https://github.com/quadrupleslap/x264/issues/4).
65    /// 
66    /// This defaults to `true`, but should be disabled for MP4 files.
67    pub fn annexb(mut self, annexb: bool) -> Self {
68        self.raw.b_annexb = annexb as i32;
69        self
70    }
71
72    /// Approximately restricts the bitrate.
73    ///
74    /// The value is in metric kilobits per second.
75    pub fn bitrate(mut self, bitrate: i32) -> Self {
76        self.raw.rc.i_bitrate = bitrate;
77        self
78    }
79
80    /// The lowest profile, with guaranteed compatibility with all decoders.
81    pub fn baseline(mut self) -> Self {
82        unsafe {
83            x264_param_apply_profile(&mut self.raw, b"baseline\0" as *const u8 as *const c_char);
84        }
85        self
86    }
87
88    /// A useless middleground between the baseline and high profiles.
89    pub fn main(mut self) -> Self {
90        unsafe {
91            x264_param_apply_profile(&mut self.raw, b"main\0" as *const u8 as *const c_char);
92        }
93        self
94    }
95
96    /// The highest profile, which almost all encoders support.
97    pub fn high(mut self) -> Self {
98        unsafe {
99            x264_param_apply_profile(&mut self.raw, b"high\0" as *const u8 as *const c_char);
100        }
101        self
102    }
103
104    /// Set the maximum number of frames between keyframes.
105    pub fn max_keyframe_interval(mut self, interval: i32) -> Self {
106        self.raw.i_keyint_max = interval;
107        self
108    }
109
110    /// Set the minimum number of frames between keyframes.
111    pub fn min_keyframe_interval(mut self, interval: i32) -> Self {
112        self.raw.i_keyint_min = interval;
113        self
114    }
115
116    /// Set the scenecut threshold. Set this to zero to guarantee a keyframe
117    /// every `max_keyframe_interval`.
118    pub fn scenecut_threshold(mut self, threshold: i32) -> Self {
119        self.raw.i_scenecut_threshold = threshold;
120        self
121    }
122
123    /// Build the encoder.
124    pub fn build<C>(mut self, csp: C, width: i32, height: i32) -> Result<Encoder>
125    where
126        C: Into<Encoding>,
127    {
128        self.raw.i_csp = csp.into().into_raw();
129        self.raw.i_width = width;
130        self.raw.i_height = height;
131
132        let raw = unsafe { x264_encoder_open(&mut self.raw) };
133
134        if raw.is_null() {
135            Err(Error)
136        } else {
137            Ok(unsafe { Encoder::from_raw(raw) })
138        }
139    }
140}
141
142impl Default for Setup {
143    fn default() -> Self {
144        let raw = unsafe {
145            let mut raw = MaybeUninit::uninit();
146            x264_param_default(raw.as_mut_ptr());
147            raw
148        };
149
150        Self {
151            raw: unsafe { raw.assume_init() },
152        }
153    }
154}