From dc0aa5aa4ac91d4d5ea063871439044cf53b0f9c Mon Sep 17 00:00:00 2001 From: Gunwoo Kim Date: Mon, 9 Nov 2026 04:10:17 +0900 Subject: [PATCH 1/2] docs(hevc): extend row-borrow proof to Main10 Signed-off-by: Gunwoo Kim --- docs/design/hevc-reference-row-borrows.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/design/hevc-reference-row-borrows.md b/docs/design/hevc-reference-row-borrows.md index 74446216..32fa30e0 100644 --- a/docs/design/hevc-reference-row-borrows.md +++ b/docs/design/hevc-reference-row-borrows.md @@ -1,11 +1,13 @@ -# HEVC eight-bit reference-row borrows +# HEVC reference-row borrows The interpolator checks its entire clipped reference support before writing output. It then gathers each source row through a clamped column map into a temporary buffer, even when the horizontal support lies entirely inside the coded picture. -For eight-bit input with an interior horizontal support, borrow the consecutive source samples directly. Construct the column map and gather only for the existing boundary-replication path. Ten-bit reconstruction keeps that path unchanged. The AVX2 kernels, scalar filter arithmetic, horizontal and vertical shifts, intermediate row ring, output writes and scratch accounting do not change. +For either supported sample depth with an interior horizontal support, borrow the consecutive source samples directly. Construct the column map and gather only for the existing boundary-replication path. The AVX2 kernels, scalar filter arithmetic, horizontal and vertical shifts, intermediate row ring, output writes and scratch accounting do not change. H.265 clause 8.5.3.3.3 and Tables 8-8 and 8-9 define consecutive taps within a row. If `x_start >= 0` and `x_start + source_width <= reference.width`, every previously gathered index is exactly `x_start + x`. A checked source slice therefore supplies the identical samples in the identical order. The existing full-support depth check still precedes both paths. Taps with zero coefficients remain part of the checked support. The support calculation remains shared with scheduling. This change only consumes the resulting start coordinate and filter extent inside the kernel. Picture-edge replication, extreme signed motion vectors, invalid samples and output padding preserve their existing behavior. No new unsafe site or scratch allocation is needed. -The preceding diagnostic compares only removal of the interior column-map and gather copies, without deleting filter arithmetic. It checks both exact decoder arms against the qualified oracle before whole-process instruction counts. Those counts motivate this bounded change but are not a wall-time speed claim. Main10 remains a separate follow-up. +Main10 samples still enter the identical `u16` filter input, and the existing horizontal shift by two and vertical shift by six remain unchanged. Borrowing rather than copying cannot change their values, intermediate range or operation order. The full clipped support is checked against the depth's maximum before either path starts. + +The preceding diagnostics compare only removal of the interior column-map and gather copies, without deleting filter arithmetic. They check both exact decoder arms against the qualified oracle before whole-process instruction counts. A Main10-only comparison keeps eight-bit input on its original path. Those counts motivate this bounded change but are not a wall-time speed claim. From 76e8e2ea31df095bb0d30ee9264ff7bb7571eeb7 Mon Sep 17 00:00:00 2001 From: Gunwoo Kim Date: Mon, 9 Nov 2026 04:12:15 +0900 Subject: [PATCH 2/2] perf(hevc): borrow Main10 reference rows Signed-off-by: Gunwoo Kim --- crates/coreav-kernels-hevc/src/inter.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/coreav-kernels-hevc/src/inter.rs b/crates/coreav-kernels-hevc/src/inter.rs index ed14a80b..0fa385ab 100644 --- a/crates/coreav-kernels-hevc/src/inter.rs +++ b/crates/coreav-kernels-hevc/src/inter.rs @@ -196,9 +196,7 @@ fn interpolate( rows: [[0; 64]; 8], }; let source_width = output.width + x_filter.len().saturating_sub(1); - let consecutive = config.depth.bits() == 8 - && x_start >= 0 - && x_start + source_width as i64 <= reference.width as i64; + let consecutive = x_start >= 0 && x_start + source_width as i64 <= reference.width as i64; if !consecutive { for (x, column) in scratch.columns.iter_mut().take(source_width).enumerate() { *column = (x_start + x as i64).clamp(0, reference.width as i64 - 1) as usize;