1use std::collections::BTreeMap;
2
3use renderbox_dsl::ParamValue;
4
5#[derive(Debug, Clone, Copy)]
10pub enum Preset {
11 Ultrafast,
12 Superfast,
13 Veryfast,
14 Faster,
15 Fast,
16 Medium,
17 Slow,
18 Slower,
19 Veryslow,
20}
21
22impl Preset {
23 pub(crate) fn as_str(&self) -> &'static str {
24 match self {
25 Preset::Ultrafast => "ultrafast",
26 Preset::Superfast => "superfast",
27 Preset::Veryfast => "veryfast",
28 Preset::Faster => "faster",
29 Preset::Fast => "fast",
30 Preset::Medium => "medium",
31 Preset::Slow => "slow",
32 Preset::Slower => "slower",
33 Preset::Veryslow => "veryslow",
34 }
35 }
36}
37
38#[derive(Debug, Clone, Copy)]
39pub enum H264Profile {
40 Baseline,
41 Main,
42 High,
43 High10,
44}
45
46impl H264Profile {
47 pub(crate) fn as_str(&self) -> &'static str {
48 match self {
49 H264Profile::Baseline => "baseline",
50 H264Profile::Main => "main",
51 H264Profile::High => "high",
52 H264Profile::High10 => "high10",
53 }
54 }
55}
56
57#[derive(Debug, Clone, Copy)]
58pub enum H264Tune {
59 Film,
60 Animation,
61 Grain,
62 Stillimage,
63 Fastdecode,
64 Zerolatency,
65}
66
67impl H264Tune {
68 pub(crate) fn as_str(&self) -> &'static str {
69 match self {
70 H264Tune::Film => "film",
71 H264Tune::Animation => "animation",
72 H264Tune::Grain => "grain",
73 H264Tune::Stillimage => "stillimage",
74 H264Tune::Fastdecode => "fastdecode",
75 H264Tune::Zerolatency => "zerolatency",
76 }
77 }
78}
79
80#[derive(Debug, Clone, Copy)]
81pub enum H265Profile {
82 Main,
83 Main10,
84 Main12,
85}
86
87impl H265Profile {
88 pub(crate) fn as_str(&self) -> &'static str {
89 match self {
90 H265Profile::Main => "main",
91 H265Profile::Main10 => "main10",
92 H265Profile::Main12 => "main12",
93 }
94 }
95}
96
97#[derive(Debug, Clone, Copy)]
98pub enum ProResProfile {
99 Proxy,
100 Lt,
101 Standard,
102 Hq,
103 Fourfourfour,
104 Xq,
105}
106
107impl ProResProfile {
108 pub(crate) fn as_str(&self) -> &'static str {
109 match self {
110 ProResProfile::Proxy => "proxy",
111 ProResProfile::Lt => "lt",
112 ProResProfile::Standard => "standard",
113 ProResProfile::Hq => "hq",
114 ProResProfile::Fourfourfour => "4444",
115 ProResProfile::Xq => "xq",
116 }
117 }
118}
119
120#[derive(Debug, Clone)]
125pub struct H264 {
126 pub crf: u8,
127 pub preset: Preset,
128 pub profile: Option<H264Profile>,
129 pub tune: Option<H264Tune>,
130}
131
132impl Default for H264 {
133 fn default() -> Self {
134 Self {
135 crf: 23,
136 preset: Preset::Medium,
137 profile: None,
138 tune: None,
139 }
140 }
141}
142
143#[derive(Debug, Clone)]
144pub struct H265 {
145 pub crf: u8,
146 pub preset: Preset,
147 pub profile: Option<H265Profile>,
148}
149
150impl Default for H265 {
151 fn default() -> Self {
152 Self {
153 crf: 28,
154 preset: Preset::Medium,
155 profile: None,
156 }
157 }
158}
159
160#[derive(Debug, Clone)]
161pub struct VP9 {
162 pub crf: u8,
163 pub speed: u8,
164}
165
166impl Default for VP9 {
167 fn default() -> Self {
168 Self { crf: 30, speed: 1 }
169 }
170}
171
172#[derive(Debug, Clone)]
173pub struct AV1 {
174 pub crf: u8,
175 pub preset: u8,
176}
177
178impl Default for AV1 {
179 fn default() -> Self {
180 Self { crf: 30, preset: 6 }
181 }
182}
183
184#[derive(Debug, Clone)]
185pub struct ProRes {
186 pub profile: ProResProfile,
187}
188
189impl Default for ProRes {
190 fn default() -> Self {
191 Self {
192 profile: ProResProfile::Hq,
193 }
194 }
195}
196
197pub trait ContainerOpts {
202 fn to_params(&self) -> BTreeMap<String, ParamValue>;
203}
204
205#[derive(Debug, Clone)]
206pub enum Mp4Opts {
207 H264(H264),
208 H265(H265),
209 AV1(AV1),
210}
211
212impl Mp4Opts {
213 pub fn h264(opts: H264) -> Self {
214 Self::H264(opts)
215 }
216 pub fn h265(opts: H265) -> Self {
217 Self::H265(opts)
218 }
219 pub fn av1(opts: AV1) -> Self {
220 Self::AV1(opts)
221 }
222}
223
224impl ContainerOpts for Mp4Opts {
225 fn to_params(&self) -> BTreeMap<String, ParamValue> {
226 match self {
227 Mp4Opts::H264(o) => h264_params(o),
228 Mp4Opts::H265(o) => h265_params(o),
229 Mp4Opts::AV1(o) => av1_params(o),
230 }
231 }
232}
233
234#[derive(Debug, Clone)]
235pub enum WebmOpts {
236 VP9(VP9),
237 AV1(AV1),
238}
239
240impl ContainerOpts for WebmOpts {
241 fn to_params(&self) -> BTreeMap<String, ParamValue> {
242 match self {
243 WebmOpts::VP9(o) => vp9_params(o),
244 WebmOpts::AV1(o) => av1_params(o),
245 }
246 }
247}
248
249#[derive(Debug, Clone)]
250pub enum MovOpts {
251 ProRes(ProRes),
252 H264(H264),
253 H265(H265),
254}
255
256impl ContainerOpts for MovOpts {
257 fn to_params(&self) -> BTreeMap<String, ParamValue> {
258 match self {
259 MovOpts::ProRes(o) => prores_params(o),
260 MovOpts::H264(o) => h264_params(o),
261 MovOpts::H265(o) => h265_params(o),
262 }
263 }
264}
265
266#[derive(Debug, Clone)]
267pub enum MkvOpts {
268 H264(H264),
269 H265(H265),
270 VP9(VP9),
271 AV1(AV1),
272}
273
274impl ContainerOpts for MkvOpts {
275 fn to_params(&self) -> BTreeMap<String, ParamValue> {
276 match self {
277 MkvOpts::H264(o) => h264_params(o),
278 MkvOpts::H265(o) => h265_params(o),
279 MkvOpts::VP9(o) => vp9_params(o),
280 MkvOpts::AV1(o) => av1_params(o),
281 }
282 }
283}
284
285fn h264_params(o: &H264) -> BTreeMap<String, ParamValue> {
290 let mut m = BTreeMap::new();
291 m.insert("codec".into(), ParamValue::String("h264".into()));
292 m.insert("crf".into(), ParamValue::Number(o.crf as f64));
293 m.insert(
294 "preset".into(),
295 ParamValue::String(o.preset.as_str().into()),
296 );
297 if let Some(p) = &o.profile {
298 m.insert("profile".into(), ParamValue::String(p.as_str().into()));
299 }
300 if let Some(t) = &o.tune {
301 m.insert("tune".into(), ParamValue::String(t.as_str().into()));
302 }
303 m
304}
305
306fn h265_params(o: &H265) -> BTreeMap<String, ParamValue> {
307 let mut m = BTreeMap::new();
308 m.insert("codec".into(), ParamValue::String("h265".into()));
309 m.insert("crf".into(), ParamValue::Number(o.crf as f64));
310 m.insert(
311 "preset".into(),
312 ParamValue::String(o.preset.as_str().into()),
313 );
314 if let Some(p) = &o.profile {
315 m.insert("profile".into(), ParamValue::String(p.as_str().into()));
316 }
317 m
318}
319
320fn vp9_params(o: &VP9) -> BTreeMap<String, ParamValue> {
321 let mut m = BTreeMap::new();
322 m.insert("codec".into(), ParamValue::String("vp9".into()));
323 m.insert("crf".into(), ParamValue::Number(o.crf as f64));
324 m.insert("speed".into(), ParamValue::Number(o.speed as f64));
325 m
326}
327
328fn av1_params(o: &AV1) -> BTreeMap<String, ParamValue> {
329 let mut m = BTreeMap::new();
330 m.insert("codec".into(), ParamValue::String("av1".into()));
331 m.insert("crf".into(), ParamValue::Number(o.crf as f64));
332 m.insert("preset".into(), ParamValue::Number(o.preset as f64));
333 m
334}
335
336fn prores_params(o: &ProRes) -> BTreeMap<String, ParamValue> {
337 let mut m = BTreeMap::new();
338 m.insert("codec".into(), ParamValue::String("prores".into()));
339 m.insert(
340 "profile".into(),
341 ParamValue::String(o.profile.as_str().into()),
342 );
343 m
344}