///|
/// Frame-level AV1 loop-filter parameters. Reduced still frames begin with
/// default reference deltas; lossless frames omit this configuration entirely.
pub(all) struct Av1LoopFilterConfig {
levels : Array[Int]
sharpness : Int
delta_enabled : Bool
ref_deltas : Array[Int]
mode_deltas : Array[Int]
}
///|
fn av1_loop_filter_config_valid(config : Av1LoopFilterConfig) -> Bool {
if config.levels.length() != 4 ||
config.ref_deltas.length() != 8 ||
config.mode_deltas.length() != 2 ||
config.sharpness < 0 ||
config.sharpness > 7 {
return false
}
for level in config.levels {
if level < 0 || level > 63 {
return false
}
}
for delta in config.ref_deltas {
if delta < -64 || delta > 63 {
return false
}
}
for delta in config.mode_deltas {
if delta < -64 || delta > 63 {
return false
}
}
true
}
///|
/// Parse loop_filter_params after coded-lossless and delta-LF gates have been
/// handled. UV levels exist only for color with at least one nonzero Y level.
fn av1_parse_loop_filter_config(
reader : Av1FrameBits,
monochrome : Bool,
ref_deltas? : Array[Int] = [],
mode_deltas? : Array[Int] = [],
) -> Av1LoopFilterConfig? {
let levels = [0, 0, 0, 0]
for i in 0..<2 {
levels[i] = match reader.take(6) {
Some(value) => value
None => return None
}
}
if !monochrome && (levels[0] != 0 || levels[1] != 0) {
for i in 2..<4 {
levels[i] = match reader.take(6) {
Some(value) => value
None => return None
}
}
}
let sharpness = match reader.take(3) {
Some(value) => value
None => return None
}
let delta_enabled = match reader.take(1) {
Some(value) => value == 1
None => return None
}
// `setup_past_independence` or `load_previous` seeds these; the update bits
// below only override the entries the frame re-codes (AV1 7.20, 7.21).
let ref_deltas = if ref_deltas.length() == 8 {
ref_deltas
} else {
av1_default_loop_filter_ref_deltas()
}
let mode_deltas = if mode_deltas.length() == 2 { mode_deltas } else { [0, 0] }
if delta_enabled {
let update = match reader.take(1) {
Some(value) => value == 1
None => return None
}
if update {
for i in 0..<8 {
match reader.take(1) {
Some(1) =>
ref_deltas[i] = match reader.signed(7) {
Some(value) => value
None => return None
}
Some(_) => ()
None => return None
}
}
for i in 0..<2 {
match reader.take(1) {
Some(1) =>
mode_deltas[i] = match reader.signed(7) {
Some(value) => value
None => return None
}
Some(_) => ()
None => return None
}
}
}
}
Some({ levels, sharpness, delta_enabled, ref_deltas, mode_deltas, })
}
///|
/// Strength selected for one edge (AV1 §7.14.5). Clamp the frame level plus
/// delta-LF first, then add and clamp the segment ALT_LF feature. Reference and
/// mode deltas scale from that resulting level, not the original frame level.
///
/// The two gates below sit *outside* the delta arithmetic: a frame whose two Y
/// levels are both zero is not deblocked at all, and §7.14.1 skips a chroma plane
/// whose own level is zero. So a delta can lift an edge whose base is zero only
/// when that plane is already being filtered; both gates were pinned down by
/// measuring dav1d, since a positive delta on a zero level would otherwise start
/// deblocking.
/// Intra blocks and unwritten neighbourhoods take the `reference == INTRA_FRAME`
/// branch and never see a mode delta, because §7.14.5 adds one only when the
/// block codes from a reference frame.
fn av1_loop_filter_edge_level(
config : Av1LoopFilterConfig,
plane : Int,
direction : Int,
reference : Int,
mode_type : Int,
segment_delta? : Int = 0,
delta_lf? : Int = 0,
) -> Int? {
if !av1_loop_filter_config_valid(config) ||
plane < 0 ||
plane > 2 ||
direction < 0 ||
direction > 1 ||
segment_delta < -63 ||
segment_delta > 63 ||
delta_lf < -63 ||
delta_lf > 63 ||
((mode_type < 0 || mode_type > 1) && reference > av1_intra_frame) {
return None
}
if plane == 0 {
if config.levels[0] == 0 && config.levels[1] == 0 {
return Some(0)
}
} else if config.levels[plane + 1] == 0 {
return Some(0)
}
let frame_level = config.levels[if plane == 0 {
direction
} else {
plane + 1
}]
let delta_level = av1_loop_filter_level_clip(frame_level + delta_lf)
let base = av1_loop_filter_level_clip(delta_level + segment_delta)
let shift = base >> 5
let level = if !config.delta_enabled {
base
} else if reference <= av1_intra_frame {
base + (config.ref_deltas[0] << shift)
} else if reference >= 8 {
return None
} else {
base +
(config.ref_deltas[reference] << shift) +
(config.mode_deltas[mode_type] << shift)
}
Some(av1_loop_filter_level_clip(level))
}
///|
fn av1_loop_filter_level_clip(level : Int) -> Int {
if level < 0 {
0
} else if level > 63 {
63
} else {
level
}
}
///|
/// Effective strength for a pure-intra, segment-zero, no-delta-LF frame.
/// Y gates both directions together; U and V each gate their own base level.
/// Mode deltas apply to inter blocks only and therefore do not enter this sum.
fn av1_loop_filter_intra_level(
config : Av1LoopFilterConfig,
plane : Int,
direction : Int,
) -> Int? {
if plane < 0 || plane > 2 || direction < 0 || direction > 1 {
return None
}
av1_loop_filter_edge_level(config, plane, direction, av1_intra_frame, 0)
}