Ctrl K
ComunidadGuías…

capcodec/tools/verify.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env python3
import argparse
import hashlib
import os
import subprocess
import sys
import tempfile
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "bench"))

from harness.corpus import load_manifest, prepare_source  # noqa: E402

FFMPEG = os.environ.get("FFMPEG", "ffmpeg")
LDECOD = os.environ.get("LDECOD", "ldecod")


def md5_frames(path: Path, frame_bytes: int) -> list[str]:
    out = []
    with open(path, "rb") as f:
        while True:
            b = f.read(frame_bytes)
            if len(b) < frame_bytes:
                break
            out.append(hashlib.md5(b).hexdigest())
    return out


def main() -> int:
    ap = argparse.ArgumentParser(description="encode a corpus clip and check ffmpeg and JM decodes against the recon")
    ap.add_argument("clip")
    ap.add_argument("--height", type=int, default=1080)
    ap.add_argument("--seconds", type=float, default=10.0)
    ap.add_argument("--binary", default=str(ROOT / "build" / "capcodec"))
    ap.add_argument("--no-sideinfo", action="store_true")
    a, extra = ap.parse_known_args()
    clips = {c.name: c for c in load_manifest()}
    src = prepare_source(clips[a.clip], a.height, a.seconds)
    fb = src.width * src.height * 3 // 2
    with tempfile.TemporaryDirectory() as td:
        t = Path(td)
        cmd = [a.binary, "encode", "--input", str(src.path), "--output", str(t / "o.264"), "--recon", str(t / "rec.yuv"),
               "--width", str(src.width), "--height", str(src.height), "--fps", src.fps_arg] + extra
        if src.sideinfo and not a.no_sideinfo:
            cmd += ["--sideinfo", str(src.sideinfo)]
        r = subprocess.run(cmd, capture_output=True)
        if r.returncode != 0:
            print(r.stderr.decode(errors="replace"))
            return 1
        print(r.stderr.decode().strip())
        rec = md5_frames(t / "rec.yuv", fb)
        subprocess.run([FFMPEG, "-hide_banner", "-loglevel", "error", "-y", "-i", str(t / "o.264"), "-f", "rawvideo",
                        "-pix_fmt", "yuv420p", str(t / "ff.yuv")], check=True)
        ff = md5_frames(t / "ff.yuv", fb)
        jr = subprocess.run([LDECOD, "-p", f"InputFile={t / 'o.264'}", "-p", f"OutputFile={t / 'jm.yuv'}",
                             "-p", "WriteUV=1"], capture_output=True, cwd=td)
        text = (jr.stdout + jr.stderr).decode(errors="replace")
        bad = [ln for ln in text.splitlines() if "error" in ln.lower() or "warning" in ln.lower()]
        jm = md5_frames(t / "jm.yuv", fb) if (t / "jm.yuv").exists() else []
        ok_ff = ff == rec and len(rec) > 0
        ok_jm = jm == rec and not bad
        first_ff = next((i for i, (x, y) in enumerate(zip(ff, rec)) if x != y), None)
        first_jm = next((i for i, (x, y) in enumerate(zip(jm, rec)) if x != y), None)
        stream_md5 = hashlib.md5((t / "o.264").read_bytes()).hexdigest()
        print(f"frames recon {len(rec)} ffmpeg {len(ff)} jm {len(jm)}; ffmpeg match {ok_ff} (first diff {first_ff}); "
              f"jm match {ok_jm} (first diff {first_jm}) {bad[:3]}; stream md5 {stream_md5}")
        return 0 if ok_ff and ok_jm else 1


if __name__ == "__main__":
    sys.exit(main())