Skip to main content

forge_browser/
frame.rs

1//! A painted frame as it leaves the host: a small header and encoded pixels.
2//!
3//! The wire form is `[profile u16][tab u16][seq u32][width u16][height u16]
4//! [format u8][key u8][page_width u16][page_height u16][bytes]` in
5//! little-endian, and [`crate::channel`] carries it with a length prefix. The
6//! bytes stay encoded end to end: the host is the only encoder, and the
7//! server relays them untouched.
8
9/// How a frame's pixels are encoded.
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11pub enum Format {
12    /// Lossy or lossless, decided by the frame's `key` flag.
13    Webp,
14}
15
16impl Format {
17    fn code(self) -> u8 {
18        match self {
19            Format::Webp => 1,
20        }
21    }
22
23    fn from_code(code: u8) -> Option<Self> {
24        match code {
25            1 => Some(Format::Webp),
26            _ => None,
27        }
28    }
29}
30
31/// The header's own length; the payload follows it.
32pub const HEADER_LEN: usize = 18;
33
34/// One encoded frame for one tab of one profile.
35#[derive(Clone, Debug, PartialEq, Eq)]
36pub struct Frame {
37    /// The served profile's id, as the server assigned it.
38    pub profile: u16,
39    /// The profile's tab this frame belongs to.
40    pub tab: u16,
41    /// Monotonic per tab; a newer frame supersedes an older one.
42    pub seq: u32,
43    pub width: u16,
44    pub height: u16,
45    pub format: Format,
46    /// A full-quality frame: the first of a surface, and every resize.
47    pub key: bool,
48    /// The page's own viewport, the space a gesture's point is sent in. **Not
49    /// the frame's pixels divided by anything**: the raster between them is
50    /// the host's, and the encoded scale may change it too.
51    pub page_width: u16,
52    pub page_height: u16,
53    pub bytes: Vec<u8>,
54}
55
56impl Frame {
57    /// The header and the payload, with no length prefix.
58    pub fn encode(&self) -> Vec<u8> {
59        let mut out = Vec::with_capacity(HEADER_LEN + self.bytes.len());
60        out.extend_from_slice(&self.profile.to_le_bytes());
61        out.extend_from_slice(&self.tab.to_le_bytes());
62        out.extend_from_slice(&self.seq.to_le_bytes());
63        out.extend_from_slice(&self.width.to_le_bytes());
64        out.extend_from_slice(&self.height.to_le_bytes());
65        out.push(self.format.code());
66        out.push(u8::from(self.key));
67        out.extend_from_slice(&self.page_width.to_le_bytes());
68        out.extend_from_slice(&self.page_height.to_le_bytes());
69        out.extend_from_slice(&self.bytes);
70        out
71    }
72
73    /// One encoded frame, header checked before any payload is trusted.
74    pub fn decode(bytes: &[u8]) -> Result<Self, String> {
75        if bytes.len() < HEADER_LEN {
76            return Err(format!("a frame is at least {HEADER_LEN} bytes, got {}", bytes.len()));
77        }
78        let profile = u16::from_le_bytes([bytes[0], bytes[1]]);
79        let tab = u16::from_le_bytes([bytes[2], bytes[3]]);
80        let seq = u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
81        let width = u16::from_le_bytes([bytes[8], bytes[9]]);
82        let height = u16::from_le_bytes([bytes[10], bytes[11]]);
83        let format = Format::from_code(bytes[12])
84            .ok_or_else(|| format!("unknown frame format {}", bytes[12]))?;
85        let key = match bytes[13] {
86            0 => false,
87            1 => true,
88            other => return Err(format!("the key flag is 0 or 1, got {other}")),
89        };
90        let page_width = u16::from_le_bytes([bytes[14], bytes[15]]);
91        let page_height = u16::from_le_bytes([bytes[16], bytes[17]]);
92        let payload = bytes[HEADER_LEN..].to_vec();
93        if payload.is_empty() {
94            return Err("a frame carries no encoded pixels".to_owned());
95        }
96        if width == 0 || height == 0 {
97            return Err(format!("a frame has a size, got {width}x{height}"));
98        }
99        if page_width == 0 || page_height == 0 {
100            return Err(format!(
101                "a frame names the page it was laid out at, got {page_width}x{page_height}"
102            ));
103        }
104        Ok(Frame {
105            profile,
106            tab,
107            seq,
108            width,
109            height,
110            format,
111            key,
112            page_width,
113            page_height,
114            bytes: payload,
115        })
116    }
117}
118
119/// One frame's encoder settings.
120///
121/// **A lossy frame takes the fastest effort; a key frame keeps libwebp's.**
122/// `method` drives a different search on each path. On the lossy one, 0 sets
123/// `RD_OPT_NONE`, drops the token buffer and zeroes the SNS weighting in the
124/// quantiser matrices (`webp_enc.c`, `quant_enc.c`): a third of the CPU per
125/// frame of a 2048x1112 window at 2x, at the same quality setting and about
126/// 18% larger on the wire. On the lossless one, `vp8l_enc.c` reads 0 as
127/// `low_effort`, which skips `AnalyzeEntropy` and coarsens `histo_bits` from
128/// 3 to 7, and a flat page's key frame came out 69x the bytes and 2.4x the
129/// time. A key frame fires on attach, pause-resume and every resize, and
130/// `Sink::offer` keys on a size change, so a window drag emits one per
131/// painted size.
132#[cfg(target_os = "macos")]
133fn config(quality: u8, key: bool) -> Option<webp::WebPConfig> {
134    /// **The fastest effort libwebp offers, where the search is the cost and
135    /// not the answer**: it is the lossy path only, for the reason above.
136    const LOSSY_EFFORT: i32 = 0;
137    let mut config = webp::WebPConfig::new().ok()?;
138    config.lossless = i32::from(key);
139    config.alpha_compression = i32::from(!key);
140    config.quality = f32::from(quality);
141    if !key {
142        config.method = LOSSY_EFFORT;
143    }
144    Some(config)
145}
146
147/// Encode one BGRA view buffer.
148///
149/// **BGRA is what CEF paints and what the ring holds**; libwebp's own
150/// layouts do not include it, so the pixels are swapped into RGBA once.
151/// `key` frames are lossless (a surface's first frame and every resize);
152/// the rest use the configured quality. `None` is an encoder refusal, which
153/// is a frame not produced rather than a panicked paint callback.
154#[cfg(target_os = "macos")]
155pub fn encode_webp(
156    bgra: &[u8],
157    width: u32,
158    height: u32,
159    quality: u8,
160    key: bool,
161) -> Option<Vec<u8>> {
162    if width == 0 || height == 0 {
163        return None;
164    }
165    let mut rgba = bgra.to_vec();
166    for pixel in rgba.chunks_mut(4) {
167        pixel.swap(0, 2);
168    }
169    let Some(config) = config(quality, key) else {
170        eprintln!(
171            "cef host: a frame was not encoded (event_name cef_frame_encode_failed, \
172             {width}x{height}): libwebp refused the encoder config"
173        );
174        return None;
175    };
176    let encoder = webp::Encoder::from_rgba(&rgba, width, height);
177    match encoder.encode_advanced(&config) {
178        Ok(memory) => Some(memory.to_vec()),
179        Err(why) => {
180            eprintln!(
181                "cef host: a frame was not encoded (event_name cef_frame_encode_failed, \
182                 {width}x{height}): {why:?}"
183            );
184            None
185        }
186    }
187}
188
189/// The host's paint-to-wire path: encode one paint and write it to the
190/// profile's socket.
191///
192/// **The configured rate is the worker's wait, not this sink's drop.** The
193/// worker waits out [`Sink::interval_remaining`], then hands the newest paint
194/// over, so a 60 Hz paint cadence costs one encoder run per interval and the
195/// last state of a burst is never lost. A frame a slow reader cannot take is
196/// dropped whole and the surface is served by the next one.
197#[cfg(target_os = "macos")]
198pub struct Sink {
199    profile: u16,
200    tab: u16,
201    path: std::path::PathBuf,
202    fps: u16,
203    quality: u8,
204    stream: Option<std::os::unix::net::UnixStream>,
205    last_attempt: Option<std::time::Instant>,
206    last_sent: Option<std::time::Instant>,
207    size: Option<(u32, u32)>,
208    seq: u32,
209    logged_failure: bool,
210    /// Set by [`Sink::force_key`]: the next sent frame is full quality.
211    forced_key: bool,
212    /// While set, paints are counted but nothing is encoded or written.
213    paused: bool,
214}
215
216#[cfg(target_os = "macos")]
217impl Sink {
218    pub fn new(profile: u16, tab: u16, path: std::path::PathBuf, fps: u16, quality: u8) -> Self {
219        Self {
220            profile,
221            tab,
222            path,
223            fps: fps.clamp(1, 120),
224            quality: quality.min(100),
225            stream: None,
226            last_attempt: None,
227            last_sent: None,
228            size: None,
229            seq: 0,
230            logged_failure: false,
231            forced_key: false,
232            paused: false,
233        }
234    }
235
236    /// Ask for a full-quality frame on the next paint: a viewer has attached,
237    /// and its first draw is the crisp one.
238    pub fn force_key(&mut self) {
239        self.forced_key = true;
240    }
241
242    /// Offer one packet of the page's audio.
243    ///
244    /// **No rate limit and no encode**: the samples are already the wire's
245    /// own, and audio is a clock of its own rather than a repaint. A paused
246    /// viewer is silent, the same rule frames follow.
247    pub fn offer_audio(&mut self, audio: &crate::channel::Audio) {
248        if self.paused {
249            return;
250        }
251        if self.stream.is_none() && !self.reconnect() {
252            return;
253        }
254        if let Some(stream) = self.stream.as_mut()
255            && let Err(why) = crate::channel::write_audio(stream, audio)
256        {
257            eprintln!(
258                "cef host: an audio packet was not written (event_name \
259                 cef_audio_write_failed, profile {}): {why}",
260                self.profile
261            );
262            // The connection is dropped; the next packet reconnects.
263            self.stream = None;
264        }
265    }
266
267    /// Pause or resume encoding. **Resuming asks for a key frame**: frames
268    /// that changed while nobody watched are not a delta's to describe.
269    pub fn set_paused(&mut self, paused: bool) {
270        if paused == self.paused {
271            return;
272        }
273        self.paused = paused;
274        if !paused {
275            self.forced_key = true;
276        }
277    }
278
279    /// How long the configured frame interval still owes, since the last
280    /// frame was written. **The worker waits this out before encoding the
281    /// newest paint**, which is where the configured rate is spent; the sink
282    /// itself never drops a frame for arriving early.
283    pub fn interval_remaining(&self) -> std::time::Duration {
284        let interval = std::time::Duration::from_millis(1000 / u64::from(self.fps));
285        self.last_sent
286            .map_or(std::time::Duration::ZERO, |last| interval.saturating_sub(last.elapsed()))
287    }
288
289    /// Offer one painted view: encode it and write it. Called by the host's
290    /// frame worker, which has already picked the newest paint; `page` is the
291    /// viewport that paint was laid out at.
292    pub fn offer(&mut self, bgra: &[u8], width: u32, height: u32, page: (u32, u32)) {
293        // **Nobody is watching: paint, but do not encode.** The paint itself
294        // is CEF's and still happens; this is the WebP cost a viewer pays
295        // for and an unwatched host does not.
296        if self.paused {
297            return;
298        }
299        // **A key frame is never coalesced away**: a resize or an attach is
300        // the one paint the viewer cannot get from a later delta.
301        let key = self.forced_key || self.size != Some((width, height));
302        if self.stream.is_none() && !self.reconnect() {
303            return;
304        }
305        let Some(bytes) = encode_webp(bgra, width, height, self.quality, key) else {
306            return;
307        };
308        let (Ok(width16), Ok(height16)) = (u16::try_from(width), u16::try_from(height)) else {
309            return;
310        };
311        let (Ok(page_width), Ok(page_height)) =
312            (u16::try_from(page.0.max(1)), u16::try_from(page.1.max(1)))
313        else {
314            return;
315        };
316        let frame = Frame {
317            profile: self.profile,
318            tab: self.tab,
319            seq: self.seq,
320            width: width16,
321            height: height16,
322            format: Format::Webp,
323            key,
324            page_width,
325            page_height,
326            bytes,
327        };
328        if let Some(stream) = self.stream.as_mut() {
329            match crate::channel::write(stream, &frame) {
330                Ok(()) => {
331                    self.seq = self.seq.wrapping_add(1);
332                    self.last_sent = Some(std::time::Instant::now());
333                    self.size = Some((width, height));
334                    self.logged_failure = false;
335                    self.forced_key = false;
336                }
337                Err(why) => {
338                    // **A reader that cannot take a frame is not the paint
339                    // path's problem.** The connection is dropped and the
340                    // next interval tries again; the frame is superseded by
341                    // the one after it, which carries the whole page.
342                    if !self.logged_failure {
343                        eprintln!(
344                            "cef host: a frame was dropped (event_name cef_frame_dropped, \
345                             profile {}): {why}",
346                            self.profile
347                        );
348                        self.logged_failure = true;
349                    }
350                    self.stream = None;
351                }
352            }
353        }
354    }
355
356    /// A connection at most once a second, so a service that has not taken
357    /// the socket yet costs the paint path nothing but a failed syscall.
358    fn reconnect(&mut self) -> bool {
359        let now = std::time::Instant::now();
360        if self.last_attempt.is_some_and(|last| now.duration_since(last) < ONE_SECOND) {
361            return false;
362        }
363        self.last_attempt = Some(now);
364        match crate::channel::connect(&self.path) {
365            Ok(stream) => {
366                self.stream = Some(stream);
367                self.logged_failure = false;
368                true
369            }
370            Err(why) => {
371                if !self.logged_failure {
372                    eprintln!(
373                        "cef host: the frame socket is not taken yet (event_name \
374                         cef_frames_unconnected, profile {}): {why}",
375                        self.profile
376                    );
377                    self.logged_failure = true;
378                }
379                false
380            }
381        }
382    }
383}
384
385#[cfg(target_os = "macos")]
386const ONE_SECOND: std::time::Duration = std::time::Duration::from_secs(1);
387
388#[cfg(test)]
389mod tests {
390    use super::{Format, Frame, HEADER_LEN};
391
392    fn frame(seq: u32, profile: u16) -> Frame {
393        Frame {
394            profile,
395            tab: 1,
396            seq,
397            width: 800,
398            height: 600,
399            format: Format::Webp,
400            key: seq == 0,
401            page_width: 400,
402            page_height: 300,
403            bytes: vec![1, 2, 3, 4],
404        }
405    }
406
407    /// **The wire form round-trips, field for field.** A header placed at
408    /// the wrong offset draws shifted rows or another profile's page.
409    #[test]
410    fn a_frame_round_trips_with_its_header() {
411        let original = frame(7, 3);
412        let bytes = original.encode();
413        assert_eq!(bytes.len(), HEADER_LEN + original.bytes.len());
414        assert_eq!(Frame::decode(&bytes), Ok(original));
415    }
416
417    /// **The profile and the tab are both on the wire.** A host serves one
418    /// profile's tabs, and a frame that lost its tab drew on the wrong one.
419    #[test]
420    fn a_frame_names_its_profile_and_its_tab() {
421        let frame = Frame {
422            profile: 3,
423            tab: 7,
424            seq: 9,
425            width: 800,
426            height: 600,
427            format: Format::Webp,
428            key: true,
429            page_width: 400,
430            page_height: 300,
431            bytes: vec![1, 2, 3],
432        };
433        let encoded = frame.encode();
434        assert_eq!(u16::from_le_bytes([encoded[0], encoded[1]]), 3);
435        assert_eq!(u16::from_le_bytes([encoded[2], encoded[3]]), 7);
436        assert_eq!(Frame::decode(&encoded).expect("a frame decodes"), frame);
437
438        let mut old = encoded.clone();
439        old[2..4].copy_from_slice(&0_u16.to_le_bytes());
440        old.truncate(12);
441        assert_eq!(
442            Frame::decode(&old).expect_err("a short header is refused"),
443            "a frame is at least 18 bytes, got 12",
444        );
445    }
446
447    /// **The page's own viewport crosses beside the frame's pixels**, and
448    /// the two are not the same number: a viewer maps a gesture through the
449    /// page, so a header that carried only the pixels left every click on a
450    /// rescaled or letterboxed picture at the wrong point.
451    #[test]
452    fn a_frame_names_the_page_its_pixels_were_painted_from() {
453        let mut frame = frame(1, 0);
454        frame.width = 2560;
455        frame.height = 1440;
456        frame.page_width = 1280;
457        frame.page_height = 720;
458        let encoded = frame.encode();
459        assert_eq!(u16::from_le_bytes([encoded[14], encoded[15]]), 1280, "the header's page width");
460        assert_eq!(u16::from_le_bytes([encoded[16], encoded[17]]), 720, "and its height");
461        let read = Frame::decode(&encoded).expect("a frame decodes");
462        assert_eq!((read.page_width, read.page_height), (1280, 720));
463        assert_eq!((read.width, read.height), (2560, 1440), "and its pixels are their own");
464
465        let mut unnamed = encoded.clone();
466        unnamed[14..16].copy_from_slice(&0_u16.to_le_bytes());
467        assert_eq!(
468            Frame::decode(&unnamed).expect_err("a frame with no page is refused"),
469            "a frame names the page it was laid out at, got 0x720",
470        );
471    }
472
473    /// **A frame the header cannot describe is refused, not read.** The
474    /// negative control is the control: a truncated buffer and an unknown
475    /// format byte must not decode into something plausible.
476    #[test]
477    fn a_frame_that_does_not_fit_its_header_is_refused() {
478        let whole = frame(1, 0).encode();
479        assert!(Frame::decode(&whole[..HEADER_LEN - 1]).is_err(), "a short header");
480        assert!(Frame::decode(&whole[..HEADER_LEN]).is_err(), "no pixels");
481        let mut unknown = whole.clone();
482        unknown[12] = 9;
483        assert!(Frame::decode(&unknown).is_err(), "an unknown format");
484        let mut flag = whole;
485        flag[13] = 2;
486        assert!(Frame::decode(&flag).is_err(), "a key flag that is not a flag");
487    }
488
489    /// **An unwatched host paints but does not encode.** The paused sink
490    /// writes nothing; unpausing sends one key frame, because frames that
491    /// changed while nobody watched are not a delta's to describe.
492    #[cfg(target_os = "macos")]
493    #[test]
494    fn a_paused_sink_writes_nothing_and_resumes_with_a_key_frame() {
495        let dir = std::env::temp_dir().join(format!("forge-sink-pause-{}", std::process::id()));
496        std::fs::create_dir_all(&dir).expect("a temp dir");
497        let path = dir.join("frames.sock");
498        let listener = std::os::unix::net::UnixListener::bind(&path).expect("a listener");
499        let bgra = [255_u8, 0, 0, 255, 0, 0, 255, 255];
500
501        let mut sink = super::Sink::new(1, 1, path.clone(), 120, 80);
502        sink.set_paused(true);
503        sink.offer(&bgra, 2, 1, (1, 1));
504        listener.set_nonblocking(true).expect("a non-blocking listener");
505        assert!(listener.accept().is_err(), "a paused sink writes no frame");
506
507        sink.set_paused(false);
508        sink.offer(&bgra, 2, 1, (1, 1));
509        let (mut stream, _) = listener.accept().expect("a frame connection");
510        stream.set_read_timeout(Some(super::ONE_SECOND)).expect("a read bound");
511        let crate::channel::Reception::Frame(frame) =
512            crate::channel::read(&mut stream).expect("a frame")
513        else {
514            panic!("a resumed sink sends a frame");
515        };
516        assert!(frame.key, "the first frame after a pause is a key frame");
517        std::fs::remove_dir_all(&dir).expect("the temp dir goes");
518    }
519
520    /// **The sink never drops a frame, and a resize is a key frame.** The
521    /// configured rate is the worker's wait; a sink that ate the newest paint
522    /// left the viewer on a state no later paint repaired.
523    #[cfg(target_os = "macos")]
524    #[test]
525    fn a_sink_writes_every_frame_and_a_resize_is_a_key() {
526        let dir = std::env::temp_dir().join(format!("forge-sink-resize-{}", std::process::id()));
527        std::fs::create_dir_all(&dir).expect("a temp dir");
528        let path = dir.join("frames.sock");
529        let listener = std::os::unix::net::UnixListener::bind(&path).expect("a listener");
530        let two = [255_u8, 0, 0, 255, 0, 0, 255, 255];
531        let four = [1_u8; 16];
532
533        // One frame a second, so every frame after the first is well inside
534        // the interval and would have been dropped by the old rate limit.
535        let mut sink = super::Sink::new(1, 1, path.clone(), 1, 80);
536        sink.offer(&two, 2, 1, (1, 1));
537        let (mut stream, _) = listener.accept().expect("the first connection");
538        stream.set_read_timeout(Some(super::ONE_SECOND)).expect("a read bound");
539        let crate::channel::Reception::Frame(first) =
540            crate::channel::read(&mut stream).expect("the first frame")
541        else {
542            panic!("a painted frame arrives");
543        };
544        assert_eq!((first.width, first.height), (2, 1));
545
546        sink.offer(&four, 4, 1, (2, 1));
547        let crate::channel::Reception::Frame(resized) =
548            crate::channel::read(&mut stream).expect("the resized frame")
549        else {
550            panic!("a resize sends inside the interval");
551        };
552        assert_eq!((resized.width, resized.height), (4, 1));
553        assert!(resized.key, "and the resize is a key frame");
554
555        sink.offer(&four, 4, 1, (2, 1));
556        assert!(
557            matches!(
558                crate::channel::read(&mut stream).expect("a same-size frame"),
559                crate::channel::Reception::Frame(_)
560            ),
561            "a same-size frame inside the interval is written, not dropped"
562        );
563        std::fs::remove_dir_all(&dir).expect("the temp dir goes");
564    }
565
566    /// **A lossy frame takes the fastest effort; a key frame keeps
567    /// libwebp's.** `method` 0 on the LOSSLESS path is `low_effort`
568    /// (`vp8l_enc.c`): it skips `AnalyzeEntropy` and coarsens `histo_bits`,
569    /// which made a flat page's key frame 69x the bytes at 2.4x the time.
570    /// **`quality` is not a lossy-only setting**: on VP8L it drives the
571    /// hash-chain search, so a key frame keeps it too.
572    #[cfg(target_os = "macos")]
573    #[test]
574    fn a_lossy_frame_takes_the_fastest_effort_and_a_key_frame_does_not() {
575        // A quality libwebp does not default to, so an assignment deleted by
576        // accident cannot pass on the sampled default.
577        let lossy = super::config(83, false).expect("a config");
578        assert_eq!(lossy.method, 0, "a lossy frame takes the fastest effort");
579        assert_eq!(lossy.quality, 83.0, "the configured quality is the one encoded");
580        assert_eq!(lossy.lossless, 0, "a frame between key frames is lossy");
581        assert_eq!(lossy.alpha_compression, 1, "a lossy frame compresses alpha, as it always did");
582        let key = super::config(83, true).expect("a config");
583        let libwebp = webp::WebPConfig::new().expect("a config");
584        assert_eq!(key.lossless, 1, "a surface's first frame is lossless");
585        assert_eq!(key.method, libwebp.method, "a key frame keeps libwebp's default effort");
586        assert_eq!(
587            key.quality, 83.0,
588            "a key frame keeps the configured quality: VP8L searches on it"
589        );
590        // VP8L codes the whole ARGB, so this is the crate's own legacy
591        // setting rather than a decision: it is what `encode_simple` gave a
592        // lossless frame, and the key-frame bytes stay identical to it.
593        assert_eq!(
594            key.alpha_compression, 0,
595            "a lossless frame keeps encode_simple's alpha setting"
596        );
597    }
598
599    /// **A painted BGRA buffer becomes a WebP a decoder would recognise, and
600    /// a lossy frame is the fast-effort encode.** The channel between two
601    /// profiles is only bytes, so this pins the encoder's own output shape:
602    /// RIFF/WebP, and libwebp's `VP8`/`VP8L` chunk for the lossy and
603    /// lossless cases.
604    ///
605    /// **The oracle is the whole point.** `encode_webp`'s lossy branch is
606    /// one call, and reverting it to `encode_simple` - what a conflict
607    /// resolution or a "lossy needs no custom config" tidy writes - would
608    /// restore the 200 ms lag with every other test green. The control below
609    /// first proves the two efforts disagree on this buffer, so the equality
610    /// after it can fail.
611    #[cfg(target_os = "macos")]
612    #[test]
613    fn a_bgra_view_encodes_to_webp() {
614        // A structured view: flat blocks, a colour shift per channel and
615        // bright rows. **Not the two-pixel pair**: the two efforts can emit
616        // identical bytes on a buffer that small, which would make the
617        // oracle blind.
618        const WIDTH: u32 = 128;
619        const HEIGHT: u32 = 80;
620        let mut bgra = vec![0_u8; (WIDTH * HEIGHT * 4) as usize];
621        for (at, pixel) in bgra.chunks_mut(4).enumerate() {
622            let x = u32::try_from(at).expect("an index") % WIDTH;
623            let y = u32::try_from(at).expect("an index") / WIDTH;
624            let base = if (x / 8 + y / 8).is_multiple_of(2) { 24 } else { 220 };
625            let value = if y.is_multiple_of(7) { 40 } else { base };
626            pixel[0] = value;
627            pixel[1] = value / 2;
628            pixel[2] = 255 - value;
629            pixel[3] = 255;
630        }
631        let mut rgba = bgra.clone();
632        for pixel in rgba.chunks_mut(4) {
633            pixel.swap(0, 2);
634        }
635        // The reference, built here rather than from `config`, or a
636        // `config` that still says "fast" would vouch for itself.
637        let at_effort = |method: i32| {
638            let mut reference = webp::WebPConfig::new().expect("a config");
639            reference.lossless = 0;
640            reference.alpha_compression = 1;
641            reference.quality = 83.0;
642            reference.method = method;
643            webp::Encoder::from_rgba(&rgba, WIDTH, HEIGHT)
644                .encode_advanced(&reference)
645                .expect("a reference encode")
646                .to_vec()
647        };
648        let fast = at_effort(0);
649        let default = at_effort(4);
650        // The control: an oracle that cannot tell the efforts apart proves
651        // nothing, and libwebp is deterministic at thread_level 0. **Byte
652        // lengths in the message, not the streams**: a failure here is read
653        // by a person, and the streams are kilobytes each.
654        assert!(
655            fast != default,
656            "the control: the efforts must disagree on this buffer, or the oracle is blind \
657             ({} B fast, {} B default)",
658            fast.len(),
659            default.len(),
660        );
661
662        let lossy = super::encode_webp(&bgra, WIDTH, HEIGHT, 83, false).expect("a lossy frame");
663        assert_eq!(&lossy[..4], b"RIFF");
664        assert_eq!(&lossy[8..12], b"WEBP");
665        assert!(lossy.windows(4).any(|window| window == b"VP8 "), "lossy uses VP8");
666        assert!(
667            lossy == fast,
668            "the lossy frame is the fast-effort encode, not the default's \
669             ({} B encoded, {} B fast, {} B default)",
670            lossy.len(),
671            fast.len(),
672            default.len(),
673        );
674
675        let key = super::encode_webp(&bgra, WIDTH, HEIGHT, 83, true).expect("a key frame");
676        assert!(key.windows(4).any(|window| window == b"VP8L"), "key frames are lossless");
677        assert!(super::encode_webp(&bgra, 0, 1, 83, false).is_none(), "no view, no frame");
678    }
679}