Skip to main content

me_oracle/
me_oracle.rs

1// Dev/test target, not shipped: a panic here IS the diagnostic (that is what an
2// assertion is). The workspace's unwrap/expect/panic denials exist to keep them
3// off the decoder's untrusted-input path, so they are relaxed for this file.
4#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
5// Dev tools also accumulate fields and helpers kept for the NEXT investigation;
6// dead code here is a scratchpad, not a defect.
7#![allow(dead_code, unused)]
8#![allow(clippy::unnecessary_unwrap, clippy::zombie_processes)]
9//! Is our motion search FINDING the best vector available to it?
10//!
11//! `enc-me` is 62% of encode and runs at x264-medium's cost per macroblock while
12//! delivering worse compression than x264-veryfast. That is either a SEARCH
13//! failure (we don't find the good vectors) or an efficiency failure elsewhere
14//! (we find them and lose the benefit downstream). This separates the two by
15//! pricing our chosen vector against an exhaustive +-24 full-pel search using the
16//! IDENTICAL cost function and sub-pel pass.
17//!
18//! ```text
19//! RFF_ME_ORACLE=1 cargo run --release -p rusty_h264-encoder --example me_oracle -- <clip.yuv> <w>x<h>
20//! ```
21use rusty_h264_common::YuvFrame;
22use rusty_h264_encoder::{Encoder, EncoderConfig, Preset};
23
24fn load(path: &str, w: usize, h: usize, n: usize) -> Vec<YuvFrame> {
25    let raw = std::fs::read(path).expect("clip");
26    let fsz = w * h * 3 / 2;
27    raw.chunks_exact(fsz)
28        .take(n)
29        .map(|c| {
30            let mut fr = YuvFrame::black(w, h);
31            fr.y.copy_from_slice(&c[..w * h]);
32            fr.u.copy_from_slice(&c[w * h..w * h + w * h / 4]);
33            fr.v.copy_from_slice(&c[w * h + w * h / 4..]);
34            fr
35        })
36        .collect()
37}
38
39fn main() {
40    let a: Vec<String> = std::env::args().skip(1).collect();
41    let (w, h) = a[1].split_once('x').unwrap();
42    let (w, h): (usize, usize) = (w.parse().unwrap(), h.parse().unwrap());
43    let nf: usize = std::env::var("RS_FRAMES").ok().and_then(|v| v.parse().ok()).unwrap_or(20);
44    let frames = load(&a[0], w, h, nf);
45
46    let preset = match std::env::var("RS_PRESET").unwrap_or_default().as_str() {
47        "fast" => Preset::Fast,
48        "quality" => Preset::Quality,
49        _ => Preset::Balanced,
50    };
51    let mut cfg = EncoderConfig::new(w, h);
52    cfg.qp = std::env::var("RS_QP").ok().and_then(|v| v.parse().ok()).unwrap_or(27);
53    cfg.gop_size = 30;
54    cfg.preset = preset;
55    let mut enc = Encoder::new(cfg).expect("encoder");
56    for f in &frames {
57        let _ = enc.encode(f);
58    }
59
60    let p: Vec<u64> = rusty_h264_encoder::ME_PROBE
61        .iter()
62        .map(|c| c.load(std::sync::atomic::Ordering::Relaxed))
63        .collect();
64    let (n, ours, oracle, worse, evals) = (p[0].max(1), p[1], p[2], p[3], p[4]);
65    let (oracle_sp, worse_sp) = (p[5], p[6]);
66    println!("ME oracle — {} ({w}x{h}, {} frames, {preset:?})\n", a[0], frames.len());
67    println!("  searches                {n}");
68    println!("  mean cost   ours        {:>10.1}", ours as f64 / n as f64);
69    println!("  mean cost   exhaustive  {:>10.1}", oracle as f64 / n as f64);
70    println!("  ---> we are {:>6.2}% above the achievable minimum",
71             100.0 * (ours as f64 - oracle as f64) / oracle as f64);
72    println!("  searches the oracle beat {:>9} ({:.1}%)", worse, 100.0 * worse as f64 / n as f64);
73    // the oracle's own 49x49 grid + 8 sub-pel probes are included in `evals`
74    println!("
75  + exhaustive SUB-PEL (all quarter-pel in +-3):");
76    println!("  mean cost   exhaustive  {:>10.1}", oracle_sp as f64 / n as f64);
77    println!("  ---> we are {:>6.2}% above the achievable minimum",
78             100.0 * (ours as f64 - oracle_sp as f64) / oracle_sp as f64);
79    println!("  searches it beat        {:>9} ({:.1}%)", worse_sp, 100.0 * worse_sp as f64 / n as f64);
80    let oracle_evals = 0;
81    println!("\n  cost() evals/search     {:>8.1}  (ours, oracle's {oracle_evals} excluded)",
82             evals as f64 / n as f64 - oracle_evals as f64);
83}