#[non_exhaustive]pub struct EncodeOptions {
pub base_q_idx: u8,
pub alpha_q_idx: u8,
pub premultiplied_alpha: bool,
pub chroma: StillChroma,
pub embed_exif: bool,
pub embed_xmp: bool,
pub embed_icc: bool,
pub speed: EncodeSpeed,
pub threads: usize,
}Expand description
Tuning for the encoders (crate::encode, crate::encode_rgb8,
crate::encode_rgba8, crate::still::encode_still …). The
default is a lossless colour encode (base_q_idx = 0), lossless
alpha, straight (non-premultiplied) alpha signalling, 4:2:0 for the
RGB one-call paths, every metadata block embedded.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.base_q_idx: u8AV1 base_q_idx for the colour planes. 0 = lossless
(default); higher = lossier / smaller (255 = coarsest). See
Self::with_quality for the 0–100 scale.
alpha_q_idx: u8AV1 base_q_idx for the alpha auxiliary. Defaults to 0
(lossless) — alpha artefacts are far more visible than colour
ones, and flat alpha planes are cheap.
premultiplied_alpha: boolEmit the prem iref declaring the colour planes premultiplied
by alpha (HEIF §6.10.1.1). Signalling only — the samples are
stored as given.
chroma: StillChromaChroma layout of crate::encode_rgb8 / crate::encode_rgba8
(default 4:2:0; odd extents fall back to 4:4:4, see those
functions). crate::encode keeps the image’s own layout.
embed_exif: boolEmbed metadata.exif as an Exif item (default true).
embed_xmp: boolEmbed metadata.xmp as a mime item (default true).
embed_icc: boolEmbed metadata.icc as an ICC colr next to the nclx one
(default true).
speed: EncodeSpeedSearch effort of the AV1 encode (default EncodeSpeed::Fast).
threads: usizeWorker threads for the AV1 tile search of every coded item
(default 1). The tile layout is derived from the picture size
alone, so the coded bytes never depend on this value.
Implementations§
Source§impl EncodeOptions
impl EncodeOptions
Sourcepub fn new(base_q_idx: u8, alpha_q_idx: u8, premultiplied_alpha: bool) -> Self
pub fn new(base_q_idx: u8, alpha_q_idx: u8, premultiplied_alpha: bool) -> Self
The historical three-field constructor (base_q_idx,
alpha_q_idx, premultiplied_alpha); the other fields take
their defaults.
Examples found in repository?
58fn main() {
59 let mut args = std::env::args().skip(1);
60 let threads: usize = args.next().and_then(|s| s.parse().ok()).unwrap_or(8);
61 let width: u32 = args.next().and_then(|s| s.parse().ok()).unwrap_or(4000);
62 let height: u32 = args.next().and_then(|s| s.parse().ok()).unwrap_or(3000);
63
64 let input = YuvFrame {
65 width,
66 height,
67 bit_depth: 8,
68 format: ChromaFormat::Yuv420,
69 y: plane(width, height, 1),
70 u: plane(width / 2, height / 2, 2),
71 v: plane(width / 2, height / 2, 3),
72 };
73 let t = Instant::now();
74 let coded = encode_still_yuv(&input, &StillOptions::new(120).threads(threads)).expect("encode");
75 let av1c = Av1CodecConfig::from_sequence_header(&coded.seq).to_bytes();
76 let file = oxideav_avif::encode_still_av1(
77 width,
78 height,
79 coded.temporal_unit_bytes,
80 av1c,
81 vec![8, 8, 8],
82 )
83 .expect("mux");
84 eprintln!(
85 "{width}x{height} 4:2:0 still: {} bytes, encoded in {:.2} s on {threads} threads",
86 file.len(),
87 t.elapsed().as_secs_f64()
88 );
89
90 let (serial, t1) = decode(&file, 1);
91 let (parallel, tn) = decode(&file, threads);
92 assert_eq!(serial, parallel, "byte-identical at any budget");
93 eprintln!(
94 "decode: serial {t1:.3} s, {threads} workers {tn:.3} s ({:.2}x), identical bytes",
95 t1 / tn
96 );
97
98 // The registry encoder on the same picture (quality 50): serial vs
99 // the budget — identical bytes, the wall clock is the point.
100 let registry_frame = Frame::Video(oxideav_core::frame::VideoFrame {
101 pts: Some(0),
102 planes: [
103 (&input.y, width),
104 (&input.u, width / 2),
105 (&input.v, width / 2),
106 ]
107 .iter()
108 .map(|(p, w)| oxideav_core::frame::VideoPlane {
109 stride: *w as usize,
110 data: p.iter().map(|&v| v as u8).collect(),
111 })
112 .collect(),
113 });
114 let mut p = CodecParameters::video(CodecId::new(oxideav_avif::CODEC_ID_STR));
115 p.width = Some(width);
116 p.height = Some(height);
117 p.pixel_format = Some(oxideav_core::PixelFormat::Yuv420P);
118 p.options = oxideav_core::CodecOptions::new().set("quality", "50");
119 let encode_registry = |budget: usize| -> (Vec<u8>, f64) {
120 let mut enc = oxideav_avif::make_encoder(&p).expect("encoder");
121 if budget > 1 {
122 enc.set_execution_context(&ExecutionContext::with_threads(budget));
123 }
124 let t = Instant::now();
125 enc.send_frame(®istry_frame).expect("send");
126 let pkt = enc.receive_packet().expect("packet");
127 (pkt.data, t.elapsed().as_secs_f64())
128 };
129 let (e1, te1) = encode_registry(1);
130 let (en, ten) = encode_registry(threads);
131 assert_eq!(e1, en, "registry encoder: byte-identical at any budget");
132 eprintln!(
133 "registry encode (quality 50): {} bytes, serial {te1:.2} s, {threads} workers {ten:.2} s ({:.2}x), identical bytes",
134 e1.len(),
135 te1 / ten
136 );
137
138 // The same picture as a 4 × 3 grid of single-tile items.
139 let t = Instant::now();
140 let still = StillImage::yuv(
141 width,
142 height,
143 8,
144 StillChroma::Yuv420,
145 input.y.clone(),
146 input.u.clone(),
147 input.v.clone(),
148 )
149 .expect("still");
150 let grid = encode_still_grid(&still, &EncodeOptions::new(120, 0, false), 4, 3).expect("grid");
151 eprintln!(
152 "{width}x{height} as a 4x3 grid: {} bytes, encoded in {:.2} s (serial encoder)",
153 grid.len(),
154 t.elapsed().as_secs_f64()
155 );
156 let (serial, t1) = decode(&grid, 1);
157 let (parallel, tn) = decode(&grid, threads);
158 assert_eq!(serial, parallel, "grid: byte-identical at any budget");
159 eprintln!(
160 "grid decode: serial {t1:.3} s, {threads} workers {tn:.3} s ({:.2}x), identical bytes",
161 t1 / tn
162 );
163}Sourcepub fn with_base_q_idx(self, base_q_idx: u8) -> Self
pub fn with_base_q_idx(self, base_q_idx: u8) -> Self
Setter: replace base_q_idx.
Sourcepub fn with_alpha_q_idx(self, alpha_q_idx: u8) -> Self
pub fn with_alpha_q_idx(self, alpha_q_idx: u8) -> Self
Setter: replace alpha_q_idx.
Sourcepub fn with_premultiplied_alpha(self, premultiplied_alpha: bool) -> Self
pub fn with_premultiplied_alpha(self, premultiplied_alpha: bool) -> Self
Setter: replace premultiplied_alpha.
Sourcepub fn with_chroma(self, chroma: StillChroma) -> Self
pub fn with_chroma(self, chroma: StillChroma) -> Self
Setter: replace chroma.
Sourcepub fn with_embed_exif(self, embed_exif: bool) -> Self
pub fn with_embed_exif(self, embed_exif: bool) -> Self
Setter: replace embed_exif.
Sourcepub fn with_embed_xmp(self, embed_xmp: bool) -> Self
pub fn with_embed_xmp(self, embed_xmp: bool) -> Self
Setter: replace embed_xmp.
Sourcepub fn with_embed_icc(self, embed_icc: bool) -> Self
pub fn with_embed_icc(self, embed_icc: bool) -> Self
Setter: replace embed_icc.
Sourcepub fn with_speed(self, speed: EncodeSpeed) -> Self
pub fn with_speed(self, speed: EncodeSpeed) -> Self
Setter: replace speed.
Sourcepub fn with_threads(self, threads: usize) -> Self
pub fn with_threads(self, threads: usize) -> Self
Setter: replace threads (clamped to at least 1).
Sourcepub fn with_quality(self, quality: u8) -> Self
pub fn with_quality(self, quality: u8) -> Self
Colour quality on a 0–100 scale (100 = lossless): sets
base_q_idx = ((100 − quality) × 255 + 50) / 100, so 100 → 0,
90 → 26, 75 → 64, 50 → 128, 0 → 255. Values above 100 clamp to
100. Alpha stays at its own alpha_q_idx.