codec/encode/tuning/params.rs
1//! Per-encoder parameter structs, rate-control enums, quality presets,
2//! and associated constants.
3//!
4//! These are the concrete knob-sets that the adapter functions in
5//! `adapters.rs` produce. Each encoder backend (rav1e, NVENC, AMF, QSV)
6//! consumes the matching struct directly.
7
8// ─── rav1e ───────────────────────────────────────────────────────
9
10/// Concrete parameters for rav1e's `EncoderConfig`.
11///
12/// Consumed in `crates/codec/src/encode/rav1e_enc.rs::build_rav1e_config`.
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub struct Rav1eParams {
15 /// rav1e quantizer: 0–255, lower = higher quality. Default 100.
16 pub quantizer: usize,
17 /// rav1e speed preset 0 (slowest/best) – 10 (fastest). Archive=4,
18 /// Standard=6, Draft=8.
19 pub speed_preset: u8,
20 /// Number of tile rows (literal, not log2). Resolution-dependent.
21 pub tile_rows: usize,
22 /// Number of tile columns (literal). Resolution-dependent.
23 pub tile_cols: usize,
24}
25
26// ─── NVENC ───────────────────────────────────────────────────────
27
28/// Concrete parameters for NVENC AV1 (NV_ENC_CONFIG + NV_ENC_RC_PARAMS).
29///
30/// Consumed in `crates/codec/src/encode/nvenc.rs` when populating
31/// `NV_ENC_INITIALIZE_PARAMS.encode_config` (currently null — see
32/// `reviews/codec-review-3.md` issues 1-3).
33///
34/// GUID is returned as its raw 16-byte form so the caller can splat
35/// it into the SDK's `#[repr(C)] Guid { data1: u32, data2: u16,
36/// data3: u16, data4: [u8;8] }` without this module depending on the
37/// FFI struct definitions.
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub struct NvencAv1Params {
40 /// Rate control mode. Values are the SDK constants
41 /// `NV_ENC_PARAMS_RC_CONSTQP = 0`, `NV_ENC_PARAMS_RC_VBR = 1`,
42 /// `NV_ENC_PARAMS_RC_CBR = 2`. We only emit CONSTQP (archive) or
43 /// VBR+targetQuality (all other tiers) — CBR is never used by
44 /// this service.
45 pub rc_mode: NvencRateControl,
46 /// AV1 CQ target (for VBR mode) or constant QP (for CONSTQP mode).
47 /// Range 0–63 for AV1 (NOT 0-51 — that range is H.264/HEVC).
48 pub cq: u8,
49 /// Preset GUID raw bytes, ready to splat into a `#[repr(C)] Guid`.
50 /// Order: data1 (4 bytes, u32 LE), data2 (2 bytes u16 LE),
51 /// data3 (2 bytes u16 LE), data4 (8 raw bytes).
52 pub preset_guid: [u8; 16],
53 /// `NV_ENC_TUNING_INFO` — always `HIGH_QUALITY (1)` for this
54 /// service; never low-latency.
55 pub tuning_info: u32,
56 /// Adaptive quantization strength 0–15. 0 disables AQ. ~8 is
57 /// a reasonable default under HIGH_QUALITY tuning.
58 pub aq_strength: u8,
59 /// Lookahead depth (frames). 0 disables. Higher = better quality
60 /// bias at cost of latency.
61 pub lookahead_depth: u32,
62 /// `NV_ENC_CONFIG_AV1.numTileColumns`.
63 pub num_tile_columns: u32,
64 /// `NV_ENC_CONFIG_AV1.numTileRows`.
65 pub num_tile_rows: u32,
66 /// `NV_ENC_CONFIG_AV1.outputAnnexBFormat`. Always 0 (LOB) for
67 /// MP4 muxing — AV1-ISOBMFF requires `obu_has_size_field = 1`.
68 pub output_annex_b_format: u32,
69 /// `NV_ENC_CONFIG_AV1.repeatSeqHdr`. Always 1 so every IDR
70 /// carries a sequence header for seeking.
71 pub repeat_seq_hdr: u32,
72}
73
74/// NVENC rate control modes actually used by this service. The numeric
75/// value matches the SDK's `NV_ENC_PARAMS_RC_MODE`.
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
77#[repr(u32)]
78pub enum NvencRateControl {
79 /// `NV_ENC_PARAMS_RC_CONSTQP = 0`. Every frame gets the same QP.
80 /// Strict archival mode — bitrate floats.
81 ConstQp = 0,
82 /// `NV_ENC_PARAMS_RC_VBR = 1` with `targetQuality` set. NVENC's
83 /// CQ mode — quality-stable across content.
84 VbrTargetQuality = 1,
85}
86
87// ─── AMF ─────────────────────────────────────────────────────────
88
89/// Concrete parameters for AMD AMF AV1 (VCN on RDNA3+).
90///
91/// AMF is property-driven: every knob is set via
92/// `AMFComponent::SetProperty(name, value)` using wide-string names
93/// defined in `vendor/amd/VideoEncoderAV1.h`. The adapter emits integer
94/// ranges that exactly match the property-value ranges the AMF runtime
95/// accepts — out-of-range values return `AMF_INVALID_ARG`.
96///
97/// Consumed in `crates/codec/src/encode/amf.rs::AmfEncoder::new`.
98#[derive(Debug, Clone, Copy, PartialEq, Eq)]
99pub struct AmfAv1Params {
100 /// `AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD`. CQP for archive,
101 /// QVBR (quality-VBR) for the common quality-target tiers.
102 pub rc_mode: AmfRateControl,
103 /// `AMF_VIDEO_ENCODER_AV1_Q_INDEX_INTRA`. AV1 QP index 0..255 (the
104 /// full AV1 quantizer range — NOT 0..63; that's NVENC's scale).
105 pub q_index_intra: u8,
106 /// `AMF_VIDEO_ENCODER_AV1_Q_INDEX_INTER`. Usually +8 on intra so
107 /// P-frames spend fewer bits.
108 pub q_index_inter: u8,
109 /// `AMF_VIDEO_ENCODER_AV1_QVBR_QUALITY_LEVEL`. 1..100 when
110 /// rc_mode == `QualityVbr`; ignored for CQP. Higher = better.
111 pub qvbr_quality: u8,
112 /// `AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET`. Lower = better quality.
113 pub quality_preset: AmfQualityPreset,
114 /// `AMF_VIDEO_ENCODER_AV1_GOP_SIZE`. Frames between keyframes.
115 pub gop_size: u32,
116 /// `AMF_VIDEO_ENCODER_AV1_AQ_MODE`. 0=off, 1=CAQ (content-adaptive).
117 pub aq_mode: u32,
118 /// `AMF_VIDEO_ENCODER_AV1_TILES_PER_FRAME`. AMF picks the grid;
119 /// we specify the total. 1 tile at ≤1080p, 4 at 1080p+, 4 at 4K
120 /// (VCN is less tile-parallel than rav1e — more tiles hurts HQ).
121 pub tiles_per_frame: u32,
122}
123
124/// AMF AV1 quality presets. Values match `AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET_*`
125/// constants from the GPUOpen AMF wiki. Lower = better quality / more wall-clock.
126/// The transcode service never picks `Speed` (same rationale as NVENC: no
127/// low-latency presets in this service — see research §2.4).
128#[derive(Debug, Clone, Copy, PartialEq, Eq)]
129#[repr(i64)]
130pub enum AmfQualityPreset {
131 HighQuality = 10,
132 Quality = 30,
133 Balanced = 50,
134 /// Not used by this service; kept in the enum so the mapping table
135 /// stays complete for any future ultra-low-latency path.
136 #[allow(dead_code)]
137 Speed = 70,
138}
139
140/// AMF AV1 rate control modes actually used by this service.
141/// Values match `AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_*`.
142#[derive(Debug, Clone, Copy, PartialEq, Eq)]
143#[repr(i64)]
144pub enum AmfRateControl {
145 /// `AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_CQP = 1`. Every
146 /// frame gets the same q-index. Archival.
147 Cqp = 1,
148 /// `AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD_QUALITY_VBR = 5`.
149 /// Quality-target VBR — bitrate floats to hit a perceptual level.
150 QualityVbr = 5,
151}
152
153// ─── QSV ─────────────────────────────────────────────────────────
154
155/// Concrete parameters for Intel QSV AV1 (oneVPL on Arc / Meteor Lake+).
156///
157/// oneVPL is struct-driven: `mfxVideoParam` carries every knob in fixed
158/// fields (no property bag). The adapter produces the exact values we
159/// splat into the struct in `crates/codec/src/encode/qsv.rs`.
160#[derive(Debug, Clone, Copy, PartialEq, Eq)]
161pub struct QsvAv1Params {
162 /// `mfxVideoParam.mfx.RateControlMethod`. ICQ for the common
163 /// quality targets; CQP for archive.
164 pub rc_mode: QsvRateControl,
165 /// `mfxVideoParam.mfx.ICQQuality` (ICQ mode) — 1..51 for AV1 per
166 /// oneVPL 2.8+ dispatcher. 1=best, 51=worst. Mapped from libaom CQ.
167 pub icq_quality: u16,
168 /// `mfxVideoParam.mfx.QPI` (CQP mode) — AV1 q-index 0..255.
169 pub qp_i: u16,
170 /// `mfxVideoParam.mfx.QPP` (CQP mode) — inter-frame QP.
171 pub qp_p: u16,
172 /// `mfxVideoParam.mfx.TargetUsage`. 1=best quality, 7=best speed.
173 pub target_usage: u16,
174 /// `mfxVideoParam.mfx.GopPicSize`. Frames between keyframes.
175 pub gop_pic_size: u16,
176 /// Tile grid — `mfxExtAV1TileParam.NumTileColumns` / `NumTileRows`.
177 pub num_tile_columns: u8,
178 pub num_tile_rows: u8,
179 /// `mfxVideoParam.mfx.LowPower`. Always
180 /// `MFX_CODINGOPTION_OFF = 32` for this service — the low-power
181 /// path on older Arc silicon has documented quality regressions;
182 /// leaving it explicitly OFF sidesteps that.
183 pub low_power: u16,
184}
185
186/// oneVPL tri-state option values (from `MFX_CODINGOPTION_*`).
187/// Used for `LowPower` and a handful of other `mfxU16` toggles.
188pub const MFX_CODINGOPTION_OFF: u16 = 32;
189/// Not currently used but named so the value shows up next to `OFF`
190/// whenever a future code path wants explicit on-switching.
191#[allow(dead_code)]
192pub const MFX_CODINGOPTION_ON: u16 = 16;
193
194/// QSV AV1 rate control mode values match `MFX_RATECONTROL_*`
195/// in `oneVPL/include/vpl/mfxstructs.h`.
196#[derive(Debug, Clone, Copy, PartialEq, Eq)]
197#[repr(u16)]
198pub enum QsvRateControl {
199 /// `MFX_RATECONTROL_CQP = 3`.
200 Cqp = 3,
201 /// `MFX_RATECONTROL_ICQ = 8`. Intelligent constant quality — the
202 /// QSV equivalent of CRF. Best match for a perceptual target.
203 Icq = 8,
204}