// Platform decode capabilities and browser-sink ยง4.7's choice, in a browser // (extensions/platform-decode.md, extensions/browser-sink.md). // // Build the page's bundle first, from wai/wai-web: // // cargo build --release --target wasm32-unknown-unknown --features platform_decode // wasm-bindgen --target web --out-dir demo/pkg-platform --out-name wai_platform_decode \ // target/wasm32-unknown-unknown/release/wai_web.wasm // // then, with Playwright installed under PLAYWRIGHT_HOST: // // [WAI_PLATFORM_BROWSER_CHANNEL=chrome] PLAYWRIGHT_HOST=/ \ // node wai/wai-web/demo/verify_platform_decode.mjs // // It serves wai-web/demo and wai/pack-conformance on 127.0.0.1, lists the AV1 floor // objects of the packaging corpus (WAI1 envelopes of wai.video.av1) as objects.json, // opens platform_decode.html in a headless browser and prints the page's report. It fails // on a page error, on an AV1 object that does not decode every temporal unit through // WebCodecs with the configuration the reference's query gives, on an HEVC stream the // platform's encoder wrote that does not decode back with the derived configuration, and // on a choice that is not the one the ranks give: the learned alternative without a figure // last and AV1 chosen; with the synthetic figure, the learned alternative ranked classical // and the first in the order chosen. import http from "node:http"; import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { createRequire } from "node:module"; const HERE = path.dirname(fileURLToPath(import.meta.url)); const PACKS = path.resolve(HERE, "../../pack-conformance"); const PORT = Number(process.env.PORT || 8798); const { chromium } = createRequire(process.env.PLAYWRIGHT_HOST || HERE + "/")("playwright"); /// The AV1 floor objects: WAI1 envelopes ("WAI1", a u32 manifest length, the manifest) /// whose manifest's capability is wai.video.av1. function av1Objects() { const out = []; const packs = path.join(PACKS, "packs"); for (const p of fs.readdirSync(packs).sort()) { const dir = path.join(packs, p, "package", "objects"); if (!fs.existsSync(dir)) continue; for (const f of fs.readdirSync(dir).sort()) { const b = fs.readFileSync(path.join(dir, f)); if (b.length < 8 || b.toString("latin1", 0, 4) !== "WAI1") continue; const m = JSON.parse(b.toString("utf8", 8, 8 + b.readUInt32LE(4))); if (m.model_requirement && m.model_requirement.capability === "wai.video.av1") out.push(`/pack-conformance/packs/${p}/package/objects/${f}`); } } return out; } const objects = av1Objects(); const ROOTS = { "/pack-conformance/": PACKS, "/demo/": HERE }; const MIME = { ".js": "text/javascript", ".wasm": "application/wasm", ".html": "text/html", ".json": "application/json" }; const server = http.createServer((req, res) => { const url = decodeURIComponent(req.url.split("?")[0]); if (url === "/demo/objects.json") { res.writeHead(200, { "content-type": "application/json" }); return res.end(JSON.stringify(objects)); } const prefix = Object.keys(ROOTS).find((p) => url.startsWith(p)); const root = prefix && ROOTS[prefix]; const f = root && path.resolve(root, "." + url.slice(prefix.length - 1)); if (!f || !f.startsWith(root + path.sep) || !fs.existsSync(f) || !fs.statSync(f).isFile()) { res.writeHead(404); return res.end("not found"); } res.writeHead(200, { "content-type": MIME[path.extname(f)] || "application/octet-stream" }); fs.createReadStream(f).pipe(res); }); let browser; try { if (!fs.existsSync(path.join(HERE, "pkg-platform", "wai_platform_decode.js"))) { console.error("no pkg-platform/wai_platform_decode.js; build it as this file's header says"); process.exit(2); } if (objects.length === 0) { console.error("no AV1 floor object found under pack-conformance/packs"); process.exit(2); } await new Promise((r) => server.listen(PORT, "127.0.0.1", r)); const channel = process.env.WAI_PLATFORM_BROWSER_CHANNEL || undefined; browser = await chromium.launch({ channel, args: process.platform === "darwin" ? ["--use-angle=metal"] : [] }); console.log(`browser: ${channel || "chromium"} ${browser.version()}`); const page = await browser.newPage(); const errs = []; page.on("pageerror", (e) => errs.push(String(e))); await page.goto(`http://127.0.0.1:${PORT}/demo/platform_decode.html`, { waitUntil: "domcontentloaded", timeout: 30000 }); await page.waitForFunction(() => window.platformDecode && window.platformDecode.done === true, null, { timeout: 5 * 60 * 1000, polling: 500 }); const report = await page.evaluate(() => window.platformDecode.report); console.log(report); for (const e of errs) console.log(`page error: ${e}`); const lines = report.split("\n"); const fail = []; if (errs.length || /page error/.test(report)) fail.push("a page error"); const objs = lines.filter((l) => l.startsWith("platform av1 object:")); if (objs.length !== objects.length) fail.push(`${objs.length} AV1 objects reported, ${objects.length} served`); for (const l of objs) { const m = / decoded=(\d+)\/(\d+) /.exec(l); if (!m || m[1] !== m[2] || / error=/.test(l)) fail.push(`not every unit decoded: ${l}`); } const hevc = lines.find((l) => l.startsWith("platform hevc encoder:")); if (!hevc) fail.push("no HEVC line"); else if (!/not supported/.test(hevc)) { const m = / decoded=(\d+)\/(\d+)/.exec(hevc); if (!m || m[1] !== m[2] || / error=/.test(hevc) || !/ no-preference=true /.test(hevc)) fail.push(`the derived HEVC configuration did not decode the stream back: ${hevc}`); } const parse = (l) => { const m = / order=(\[.*?\]) ranks=(\[.*?\]) chosen=(\S+)$/.exec(l || ""); return m && { order: JSON.parse(m[1]), ranks: JSON.parse(m[2]), chosen: m[3] }; }; const plain = parse(lines.find((l) => l.startsWith("platform choose: "))); if (!plain || plain.order[1] !== "int_hyper" || plain.ranks[1] !== "learned-without-budget" || plain.chosen !== "av1") fail.push(`without a figure the learned alternative was not last, or AV1 was not chosen: ${JSON.stringify(plain)}`); const fig = parse(lines.find((l) => l.startsWith("platform choose with a synthetic figure:"))); const learnedAt = fig ? fig.order.indexOf("int_hyper") : -1; if (!fig || learnedAt < 0 || fig.ranks[learnedAt] !== "classical" || fig.chosen !== fig.order[0]) fail.push(`with the synthetic figure the learned alternative was not ranked classical, or the first in the order was not chosen: ${JSON.stringify(fig)}`); for (const f of fail) console.log(`FAIL ${f}`); if (fail.length) process.exitCode = 1; } finally { if (browser) await browser.close(); server.close(); }