-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparams.rs
More file actions
255 lines (239 loc) · 11.5 KB
/
Copy pathparams.rs
File metadata and controls
255 lines (239 loc) · 11.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
//! Per-encoder parameter structs, rate-control enums, quality presets,
//! and associated constants.
//!
//! These are the concrete knob-sets that the adapter functions in
//! `adapters.rs` produce. Each encoder backend (rav1e, NVENC, AMF, QSV)
//! consumes the matching struct directly.
// ─── rav1e ───────────────────────────────────────────────────────
/// Concrete parameters for rav1e's `EncoderConfig`.
///
/// Consumed in `crates/codec/src/encode/rav1e_enc.rs::build_rav1e_config`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Rav1eParams {
/// rav1e quantizer: 0–255, lower = higher quality. Default 100.
pub quantizer: usize,
/// rav1e speed preset 0 (slowest/best) – 10 (fastest). Archive=4,
/// Standard=6, Draft=8.
pub speed_preset: u8,
/// Number of tile rows (literal, not log2). Resolution-dependent.
pub tile_rows: usize,
/// Number of tile columns (literal). Resolution-dependent.
pub tile_cols: usize,
}
// ─── h26x (software H.264 / H.265) ───────────────────────────────
/// Concrete parameters for the native software H.264 / H.265 encoders
/// (`h26x::encode::Config`).
///
/// Consumed in `crates/codec/src/encode/h26x_sw.rs`. The quantiser is the
/// ordinary H.26x 0..51 QP — the same currency as an x264 / x265 CRF and as
/// the QSV H.26x table, so the anchors are shared with it rather than
/// re-derived.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct H26xSwParams {
/// Constant quantiser, 0..=51, lower = higher quality.
pub qp: u8,
/// H.264 only: offer the 8x8 transform (High profile). Ignored by H.265.
pub transform_8x8: bool,
/// H.264 only: offer inter partitions below 16x16. Costs search time and
/// buys little outside content where macroblock halves move differently,
/// so it is the slowest tier's tool. Ignored by H.265.
pub subparts: bool,
/// H.265 only: sample adaptive offset. Refused by H.264.
pub sao: bool,
}
// ─── NVENC ───────────────────────────────────────────────────────
/// Concrete parameters for NVENC AV1 (NV_ENC_CONFIG + NV_ENC_RC_PARAMS).
///
/// Consumed in `crates/codec/src/encode/nvenc.rs` when populating
/// `NV_ENC_INITIALIZE_PARAMS.encode_config` (currently null — see
/// `reviews/codec-review-3.md` issues 1-3).
///
/// GUID is returned as its raw 16-byte form so the caller can splat
/// it into the SDK's `#[repr(C)] Guid { data1: u32, data2: u16,
/// data3: u16, data4: [u8;8] }` without this module depending on the
/// FFI struct definitions.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NvencAv1Params {
/// Rate control mode. Values are the SDK constants
/// `NV_ENC_PARAMS_RC_CONSTQP = 0`, `NV_ENC_PARAMS_RC_VBR = 1`,
/// `NV_ENC_PARAMS_RC_CBR = 2`. We only emit CONSTQP (archive) or
/// VBR+targetQuality (all other tiers) — CBR is never used by
/// this service.
pub rc_mode: NvencRateControl,
/// AV1 CQ target (for VBR mode) or constant QP (for CONSTQP mode).
/// Range 0–63 for AV1 (NOT 0-51 — that range is H.264/HEVC).
pub cq: u8,
/// Preset GUID raw bytes, ready to splat into a `#[repr(C)] Guid`.
/// Order: data1 (4 bytes, u32 LE), data2 (2 bytes u16 LE),
/// data3 (2 bytes u16 LE), data4 (8 raw bytes).
pub preset_guid: [u8; 16],
/// `NV_ENC_TUNING_INFO` — always `HIGH_QUALITY (1)` for this
/// service; never low-latency.
pub tuning_info: u32,
/// Adaptive quantization strength 0–15. 0 disables AQ. ~8 is
/// a reasonable default under HIGH_QUALITY tuning.
pub aq_strength: u8,
/// Lookahead depth (frames). 0 disables. Higher = better quality
/// bias at cost of latency.
pub lookahead_depth: u32,
/// `NV_ENC_CONFIG_AV1.numTileColumns`.
pub num_tile_columns: u32,
/// `NV_ENC_CONFIG_AV1.numTileRows`.
pub num_tile_rows: u32,
/// `NV_ENC_CONFIG_AV1.outputAnnexBFormat`. Always 0 (LOB) for
/// MP4 muxing — AV1-ISOBMFF requires `obu_has_size_field = 1`.
pub output_annex_b_format: u32,
/// `NV_ENC_CONFIG_AV1.repeatSeqHdr`. Always 1 so every IDR
/// carries a sequence header for seeking.
pub repeat_seq_hdr: u32,
}
/// NVENC rate control modes actually used by this service. The numeric
/// value matches the SDK's `NV_ENC_PARAMS_RC_MODE`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum NvencRateControl {
/// `NV_ENC_PARAMS_RC_CONSTQP = 0`. Every frame gets the same QP.
/// Strict archival mode — bitrate floats.
ConstQp = 0,
/// `NV_ENC_PARAMS_RC_VBR = 1` with `targetQuality` set. NVENC's
/// CQ mode — quality-stable across content.
VbrTargetQuality = 1,
}
// ─── AMF ─────────────────────────────────────────────────────────
/// Concrete parameters for AMD AMF AV1 (VCN on RDNA3+).
///
/// AMF is property-driven: every knob is set via
/// `AMFComponent::SetProperty(name, value)` using wide-string names
/// defined in `vendor/amd/VideoEncoderAV1.h`. The adapter emits integer
/// ranges that exactly match the property-value ranges the AMF runtime
/// accepts — out-of-range values return `AMF_INVALID_ARG`.
///
/// Consumed in `crates/codec/src/encode/amf.rs::AmfEncoder::new`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AmfAv1Params {
/// `AMF_VIDEO_ENCODER_AV1_RATE_CONTROL_METHOD`. CQP for archive,
/// QVBR (quality-VBR) for the common quality-target tiers.
pub rc_mode: AmfRateControl,
/// `AMF_VIDEO_ENCODER_AV1_Q_INDEX_INTRA`. AV1 QP index 0..255 (the
/// full AV1 quantizer range — NOT 0..63; that's NVENC's scale).
pub q_index_intra: u8,
/// `AMF_VIDEO_ENCODER_AV1_Q_INDEX_INTER`. Usually +8 on intra so
/// P-frames spend fewer bits.
pub q_index_inter: u8,
/// `AMF_VIDEO_ENCODER_AV1_QVBR_QUALITY_LEVEL`. 1..100 when
/// rc_mode == `QualityVbr`; ignored for CQP. Higher = better.
pub qvbr_quality: u8,
/// `AMF_VIDEO_ENCODER_AV1_QUALITY_PRESET`. Lower = better quality.
pub quality_preset: AmfQualityPreset,
/// `AMF_VIDEO_ENCODER_AV1_GOP_SIZE`. Frames between keyframes.
pub gop_size: u32,
/// `AMF_VIDEO_ENCODER_AV1_AQ_MODE`. 0=off, 1=CAQ (content-adaptive).
pub aq_mode: u32,
/// `AMF_VIDEO_ENCODER_AV1_TILES_PER_FRAME`. AMF picks the grid;
/// we specify the total. 1 tile at ≤1080p, 4 at 1080p+, 4 at 4K
/// (VCN is less tile-parallel than rav1e — more tiles hurts HQ).
pub tiles_per_frame: u32,
}
/// AMF quality presets, backend-agnostic. Each AMF codec numbers its
/// `QUALITY_PRESET` enum differently (v1.4.36 headers: AV1 `0/30/70/100`
/// in `VideoEncoderAV1.h:128-131`, AVC `3/2/0/1` in
/// `VideoEncoderVCE.h:112-115`, HEVC `15/0/5/10` in
/// `VideoEncoderHEVC.h:107-110`), so the numeric value is assigned per codec
/// in `encode/amf/{av1,h26x}.rs`, not here. Lower is better quality / more
/// wall-clock. The transcode service never picks `Speed` (same rationale as
/// NVENC: no low-latency presets in this service — see research §2.4).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AmfQualityPreset {
HighQuality,
Quality,
Balanced,
/// Not used by this service; kept in the enum so the mapping table
/// stays complete for any future ultra-low-latency path.
#[allow(dead_code)]
Speed,
}
/// AMF rate control modes actually used by this service. The header value
/// is the same for all three codecs (`RATE_CONTROL_METHOD_CONSTANT_QP = 0`,
/// `QUALITY_VBR = 4`: `VideoEncoderAV1.h:91,95`, `VideoEncoderVCE.h:101,105`,
/// `VideoEncoderHEVC.h:80,84`) and is assigned in `encode/amf/`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AmfRateControl {
/// Every frame gets the same quantiser. Archival, and the chunked
/// path's `ParallelConstQp`.
Cqp,
/// Quality-target VBR — bitrate floats to hit a quality level, within
/// explicit target / peak / VBV constraints.
QualityVbr,
}
/// Concrete parameters for AMD AMF H.264 (`AMFVideoEncoderVCE_AVC`) and
/// H.265 (`AMFVideoEncoderHW_HEVC`).
///
/// The quantiser is the ordinary H.26x 0..51 QP, the same currency as the
/// QSV H.26x table and the native `h26x` software encoders, so the anchors
/// are shared with them rather than re-derived. Consumed in
/// `crates/codec/src/encode/amf/h26x.rs`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AmfH26xParams {
/// `RateControlMethod` / `HevcRateControlMethod`. CQP for archive, QVBR
/// for the common quality-target tiers.
pub rc_mode: AmfRateControl,
/// `QPI` / `HevcQP_I`, 0..=51.
pub qp_i: u8,
/// `QPP` / `HevcQP_P`, 0..=51; a small step coarser than intra.
pub qp_p: u8,
/// `QvbrQualityLevel` / `HevcQvbrQualityLevel`, 1..=51, **higher** =
/// better (measured; the header only says "default = 23; range =
/// 1-51"). `52 - qp_i`, see `adapters::qvbr_level_for_qp`.
pub qvbr_quality: u8,
/// `QualityPreset` / `HevcQualityPreset`, mapped per codec.
pub quality_preset: AmfQualityPreset,
}
// ─── QSV ─────────────────────────────────────────────────────────
/// Concrete parameters for Intel QSV AV1 (oneVPL on Arc / Meteor Lake+).
///
/// oneVPL is struct-driven: `mfxVideoParam` carries every knob in fixed
/// fields (no property bag). The adapter produces the exact values we
/// splat into the struct in `crates/codec/src/encode/qsv.rs`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct QsvAv1Params {
/// `mfxVideoParam.mfx.RateControlMethod`. ICQ for the common
/// quality targets; CQP for archive.
pub rc_mode: QsvRateControl,
/// `mfxVideoParam.mfx.ICQQuality` (ICQ mode) — 1..51 for AV1 per
/// oneVPL 2.8+ dispatcher. 1=best, 51=worst. Mapped from libaom CQ.
pub icq_quality: u16,
/// `mfxVideoParam.mfx.QPI` (CQP mode) — AV1 q-index 0..255.
pub qp_i: u16,
/// `mfxVideoParam.mfx.QPP` (CQP mode) — inter-frame QP.
pub qp_p: u16,
/// `mfxVideoParam.mfx.TargetUsage`. 1=best quality, 7=best speed.
pub target_usage: u16,
/// `mfxVideoParam.mfx.GopPicSize`. Frames between keyframes.
pub gop_pic_size: u16,
/// Tile grid — `mfxExtAV1TileParam.NumTileColumns` / `NumTileRows`.
pub num_tile_columns: u8,
pub num_tile_rows: u8,
/// `mfxVideoParam.mfx.LowPower`. Always
/// `MFX_CODINGOPTION_OFF = 32` for this service — the low-power
/// path on older Arc silicon has documented quality regressions;
/// leaving it explicitly OFF sidesteps that.
pub low_power: u16,
}
/// oneVPL tri-state option values (from `MFX_CODINGOPTION_*`).
/// Used for `LowPower` and a handful of other `mfxU16` toggles.
pub const MFX_CODINGOPTION_OFF: u16 = 32;
/// Not currently used but named so the value shows up next to `OFF`
/// whenever a future code path wants explicit on-switching.
#[allow(dead_code)]
pub const MFX_CODINGOPTION_ON: u16 = 16;
/// QSV AV1 rate control mode values match `MFX_RATECONTROL_*`
/// in `oneVPL/include/vpl/mfxstructs.h`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u16)]
pub enum QsvRateControl {
/// `MFX_RATECONTROL_CQP = 3`.
Cqp = 3,
/// `MFX_RATECONTROL_ICQ = 8`. Intelligent constant quality — the
/// QSV equivalent of CRF. Best match for a perceptual target.
Icq = 8,
}