Skip to main content

renderbox_sdk/
codec.rs

1use std::collections::BTreeMap;
2
3use renderbox_dsl::ParamValue;
4
5// ---------------------------------------------------------------------------
6// Codec presets / profiles
7// ---------------------------------------------------------------------------
8
9#[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// ---------------------------------------------------------------------------
121// Per-codec option structs
122// ---------------------------------------------------------------------------
123
124#[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
197// ---------------------------------------------------------------------------
198// Container-constrained enums
199// ---------------------------------------------------------------------------
200
201pub 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
285// ---------------------------------------------------------------------------
286// Param builders
287// ---------------------------------------------------------------------------
288
289fn 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}