printnanny_gst/
options.rs

1use clap::{ArgEnum, PossibleValue};
2
3#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ArgEnum)]
4pub enum AppModeOption {
5    // broadcast source video stream over 1 rtp port (light compute)
6    RtpVideo,
7    // broadcast source video, model inference video, and model inference tensor over 3 rtp ports (medium compute)
8    RtpTfliteOverlay,
9    // broadcast video composited from source / inference (heavy compute)
10    RtpTfliteComposite,
11}
12
13impl AppModeOption {
14    pub fn possible_values() -> impl Iterator<Item = PossibleValue<'static>> {
15        AppModeOption::value_variants()
16            .iter()
17            .filter_map(ArgEnum::to_possible_value)
18    }
19}
20
21impl std::fmt::Display for AppModeOption {
22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23        self.to_possible_value()
24            .expect("no values are skipped")
25            .get_name()
26            .fmt(f)
27    }
28}
29
30impl std::str::FromStr for AppModeOption {
31    type Err = String;
32
33    fn from_str(s: &str) -> Result<Self, Self::Err> {
34        for variant in Self::value_variants() {
35            if variant.to_possible_value().unwrap().matches(s, false) {
36                return Ok(*variant);
37            }
38        }
39        Err(format!("Invalid variant: {}", s))
40    }
41}
42
43#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ArgEnum)]
44pub enum SinkOption {
45    Fakesink,
46    Udpsink,
47}
48
49impl SinkOption {
50    pub fn possible_values() -> impl Iterator<Item = PossibleValue<'static>> {
51        SinkOption::value_variants()
52            .iter()
53            .filter_map(ArgEnum::to_possible_value)
54    }
55}
56
57impl std::fmt::Display for SinkOption {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        self.to_possible_value()
60            .expect("no values are skipped")
61            .get_name()
62            .fmt(f)
63    }
64}
65
66impl std::str::FromStr for SinkOption {
67    type Err = String;
68
69    fn from_str(s: &str) -> Result<Self, Self::Err> {
70        for variant in Self::value_variants() {
71            if variant.to_possible_value().unwrap().matches(s, false) {
72                return Ok(*variant);
73            }
74        }
75        Err(format!("Invalid variant: {}", s))
76    }
77}
78
79#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ArgEnum)]
80pub enum SrcOption {
81    Libcamerasrc,
82    Videotestsrc,
83}
84
85impl SrcOption {
86    pub fn possible_values() -> impl Iterator<Item = PossibleValue<'static>> {
87        SrcOption::value_variants()
88            .iter()
89            .filter_map(ArgEnum::to_possible_value)
90    }
91}
92
93impl std::fmt::Display for SrcOption {
94    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95        self.to_possible_value()
96            .expect("no values are skipped")
97            .get_name()
98            .fmt(f)
99    }
100}
101
102impl std::str::FromStr for SrcOption {
103    type Err = String;
104
105    fn from_str(s: &str) -> Result<Self, Self::Err> {
106        for variant in Self::value_variants() {
107            if variant.to_possible_value().unwrap().matches(s, false) {
108                return Ok(*variant);
109            }
110        }
111        Err(format!("Invalid variant: {}", s))
112    }
113}
114
115#[derive(Debug)]
116pub struct VideoParameter {
117    pub encoder: &'static str,
118    pub encoding_name: &'static str,
119    pub payloader: &'static str,
120    pub parser: &'static str,
121    pub requirements: &'static str,
122}
123
124pub const H264_SOFTWARE: VideoParameter = VideoParameter {
125    requirements: "x264",
126    encoder: "x264enc tune=zerolatency",
127    encoding_name: "h264",
128    parser: "h264parse",
129    payloader: "rtph264pay aggregate-mode=zero-latency",
130};
131
132pub const H264_HARDWARE: VideoParameter = VideoParameter {
133    requirements: "video4linux2",
134    encoder: "v4l2h264enc extra-controls=controls,repeat_sequence_header=1",
135    encoding_name: "h264",
136    parser: "h264parse",
137    payloader: "rtph264pay aggregate-mode=zero-latency",
138};
139
140#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ArgEnum)]
141pub enum VideoEncodingOption {
142    H264Software,
143    H264Hardware,
144}
145
146impl From<VideoEncodingOption> for VideoParameter {
147    fn from(opt: VideoEncodingOption) -> Self {
148        match opt {
149            VideoEncodingOption::H264Hardware => H264_HARDWARE,
150            VideoEncodingOption::H264Software => H264_SOFTWARE,
151        }
152    }
153}
154
155impl VideoEncodingOption {
156    pub fn possible_values() -> impl Iterator<Item = PossibleValue<'static>> {
157        VideoEncodingOption::value_variants()
158            .iter()
159            .filter_map(ArgEnum::to_possible_value)
160    }
161}
162
163impl std::fmt::Display for VideoEncodingOption {
164    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165        self.to_possible_value()
166            .expect("no values are skipped")
167            .get_name()
168            .fmt(f)
169    }
170}
171
172impl std::str::FromStr for VideoEncodingOption {
173    type Err = String;
174
175    fn from_str(s: &str) -> Result<Self, Self::Err> {
176        for variant in Self::value_variants() {
177            if variant.to_possible_value().unwrap().matches(s, false) {
178                return Ok(*variant);
179            }
180        }
181        Err(format!("Invalid variant: {}", s))
182    }
183}