Real captured video pans a non-integer number of pixels per frame, so whole-pel block motion compensation always leaves a sub-pixel residual. Add half-pel MC to wai.video.int_motion: an mv_precision field (1=whole, default; 2=half) selects sub-pixel block prediction by integer bilinear interpolation — (a+b+1)>>1 on an axis, (a+b+c+d+2)>>2 on the diagonal — in pure i64. No float: the clip stays byte-exact (frame-state-equivalence, a per-frame portable hash) while the residual, and the bitstream, shrink. - decoder: int_video::predict() gated on mv_precision, wired into both decode() and decode_pframes(); existing whole-pel vectors decode unchanged (absent field => prec=1). - encoder: tools/wai_int_video_real_encode.py drives the codec from REAL footage (a sub-pixel Ken-Burns pan over a captured photograph), encodes the clip both whole-pel and half-pel with a residual-histogram-fit CDF, and reports the delta. Two-stage block search: whole-pel SAD then a ±half-pel bilinear refine. - conformance: tests/vectors/int_video/video_real_* — a 96x96x8 half-pel clip from real footage; int_video_halfpel.rs never-skips. The Rust predict() reproduces the Python encoder's integer bilinear output byte-for-byte (32% under whole-pel at the same reproducible frames). Co-Authored-By: Claude Opus 4.8 <[email protected]>
1 line
No EOL
295 B
JSON
1 line
No EOL
295 B
JSON
{"n_frames": 8, "h": 96, "w": 96, "frame_hashes": ["e45da093799bc725", "b692e8932390698d", "e0843746107a5bf2", "b12e952294a2f81f", "84eb0f7a6fb25a47", "3b5f9149f51f22eb", "71b52b7b7ac81c12", "4556a6749fb20e3e"], "clip_hash": "1ec1f0fa7da0d70f", "whole_pel_bytes": 38232, "half_pel_bytes": 27960} |