Skip to main content

ff_encode/video/builder/
video.rs

1//! Video stream settings for [`VideoEncoderBuilder`].
2
3use super::VideoEncoderBuilder;
4use crate::{BitrateMode, HardwareEncoder, Preset, VideoCodec};
5
6impl VideoEncoderBuilder {
7    /// Configure video stream settings.
8    #[must_use]
9    pub fn video(mut self, width: u32, height: u32, fps: f64) -> Self {
10        self.video_width = Some(width);
11        self.video_height = Some(height);
12        self.video_fps = Some(fps);
13        self
14    }
15
16    /// Set video codec.
17    #[must_use]
18    pub fn video_codec(mut self, codec: VideoCodec) -> Self {
19        self.video_codec = codec;
20        self.video_codec_explicit = true;
21        self
22    }
23
24    /// Set the bitrate control mode for video encoding.
25    #[must_use]
26    pub fn bitrate_mode(mut self, mode: BitrateMode) -> Self {
27        self.video_bitrate_mode = Some(mode);
28        self
29    }
30
31    /// Set encoding preset (speed vs quality tradeoff).
32    #[must_use]
33    pub fn preset(mut self, preset: Preset) -> Self {
34        self.preset = preset;
35        self
36    }
37
38    /// Set hardware encoder.
39    #[must_use]
40    pub fn hardware_encoder(mut self, hw: HardwareEncoder) -> Self {
41        self.hardware_encoder = hw;
42        self
43    }
44
45    /// Accept an encoder from a different codec family when the requested codec
46    /// has no encoder available.
47    ///
48    /// By default, asking for H.264 and getting anything that is not H.264 is an
49    /// error. Some codecs have an LGPL-compatible stand-in (VP9 for H.264, AV1
50    /// for H.265) that can encode the frames, but the output is that other
51    /// codec, so it is only used when this is set. When it is used, a warning
52    /// names the encoder that was chosen, and
53    /// [`actual_video_codec`](super::VideoEncoder::actual_video_codec) reports
54    /// it.
55    #[must_use]
56    pub fn allow_codec_substitution(mut self) -> Self {
57        self.allow_codec_substitution = true;
58        self
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65    use std::path::PathBuf;
66
67    #[test]
68    fn builder_video_settings_should_be_stored() {
69        let builder = VideoEncoderBuilder::new(PathBuf::from("output.mp4"))
70            .video(1920, 1080, 30.0)
71            .video_codec(VideoCodec::H264)
72            .bitrate_mode(BitrateMode::Cbr(8_000_000));
73        assert_eq!(builder.video_width, Some(1920));
74        assert_eq!(builder.video_height, Some(1080));
75        assert_eq!(builder.video_fps, Some(30.0));
76        assert_eq!(builder.video_codec, VideoCodec::H264);
77        assert_eq!(
78            builder.video_bitrate_mode,
79            Some(BitrateMode::Cbr(8_000_000))
80        );
81    }
82
83    #[test]
84    fn builder_preset_should_be_stored() {
85        let builder = VideoEncoderBuilder::new(PathBuf::from("output.mp4"))
86            .video(1920, 1080, 30.0)
87            .preset(Preset::Fast);
88        assert_eq!(builder.preset, Preset::Fast);
89    }
90
91    #[test]
92    fn builder_hardware_encoder_should_be_stored() {
93        let builder = VideoEncoderBuilder::new(PathBuf::from("output.mp4"))
94            .video(1920, 1080, 30.0)
95            .hardware_encoder(HardwareEncoder::Nvenc);
96        assert_eq!(builder.hardware_encoder, HardwareEncoder::Nvenc);
97    }
98}