///|
/// Filter metadata assembled on the frame's luma 4x4 grid. Each MI has four
/// accumulated delta-LF values in Y-vertical, Y-horizontal, U, V order; a
/// single-delta stream broadcasts its value to all four entries when decoded.
/// Every covered MI retains its coding block's segment id and SB delta values.
pub(all) struct Av1LoopFilterBlockMap {
cols : Int
rows : Int
segment_ids : Array[Int]
deltas : Array[Int]
segmentation : Av1SegmentationParams
}
///|
fn av1_loop_filter_block_map_valid(
map : Av1LoopFilterBlockMap,
cols : Int,
rows : Int,
) -> Bool {
if map.cols != cols ||
map.rows != rows ||
map.segment_ids.length() != cols * rows ||
map.deltas.length() != cols * rows * 4 {
return false
}
for id in map.segment_ids {
if id < 0 || id >= 8 {
return false
}
}
for delta in map.deltas {
if delta < -63 || delta > 63 {
return false
}
}
let segmentation = map.segmentation
if segmentation.enabled {
if segmentation.feature_enabled.length() != 8 ||
segmentation.feature_data.length() != 8 {
return false
}
for segment in 0..<8 {
if segmentation.feature_enabled[segment].length() != 8 ||
segmentation.feature_data[segment].length() != 8 {
return false
}
for feature in 1..<5 {
let delta = segmentation.feature_data[segment][feature]
if segmentation.feature_enabled[segment][feature] &&
(delta < -63 || delta > 63) {
return false
}
}
}
}
true
}
///|
/// Chroma selects the bottom-right luma MI of its subsampled group. Luma uses
/// the addressed MI unchanged, regardless of the frame's chroma subsampling.
fn av1_loop_filter_luma_mi(
plane : Int,
x : Int,
y : Int,
sub_x : Int,
sub_y : Int,
) -> (Int, Int) {
if plane == 0 {
(y / 4, x / 4)
} else {
(((y << sub_y) / 4) | sub_y, ((x << sub_x) / 4) | sub_x)
}
}
///|
/// Select this side's segment and accumulated SB delta, then combine them with
/// its actual reference/mode state. `block_map` was validated before filtering.
fn av1_loop_filter_block_level(
config : Av1LoopFilterConfig,
field : Av1MotionField?,
block_map : Av1LoopFilterBlockMap?,
plane : Int,
direction : Int,
x : Int,
y : Int,
sub_x : Int,
sub_y : Int,
) -> Int? {
let (reference, mode_type) = av1_loop_filter_block_state(
field, plane, x, y, sub_x, sub_y,
)
let mut segment_delta = 0
let mut delta_lf = 0
match block_map {
Some(map) => {
let (row, col) = av1_loop_filter_luma_mi(plane, x, y, sub_x, sub_y)
if row < 0 || col < 0 || row >= map.rows || col >= map.cols {
return None
}
let unit = row * map.cols + col
let component = if plane == 0 { direction } else { plane + 1 }
delta_lf = map.deltas[unit * 4 + component]
let segment = map.segment_ids[unit]
let feature = component + 1
if map.segmentation.enabled &&
map.segmentation.feature_enabled[segment][feature] {
segment_delta = map.segmentation.feature_data[segment][feature]
}
}
None => ()
}
av1_loop_filter_edge_level(
config,
plane,
direction,
reference,
mode_type,
segment_delta~,
delta_lf~,
)
}