Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enum BlockLevel: Make a real enum #760

Merged
merged 8 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/cdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::src::align::Align8;
use crate::src::error::Rav1dError::ENOMEM;
use crate::src::error::Rav1dResult;
use crate::src::internal::Rav1dContext;
use crate::src::levels::N_BL_LEVELS;
use crate::src::levels::BlockLevel;
use crate::src::levels::N_BS_SIZES;
use crate::src::levels::N_COMP_INTER_PRED_MODES;
use crate::src::levels::N_INTRA_PRED_MODES;
Expand All @@ -28,6 +28,7 @@ use std::ffi::c_uint;
use std::ffi::c_void;
use std::ptr;
use std::sync::atomic::AtomicU32;
use strum::EnumCount;

#[repr(C)]
pub struct CdfContext {
Expand Down Expand Up @@ -81,7 +82,7 @@ pub struct CdfModeContext {
pub y_mode: Align32<[[u16; N_INTRA_PRED_MODES + 3]; 4]>,
pub uv_mode: Align32<[[[u16; N_UV_INTRA_PRED_MODES + 2]; N_INTRA_PRED_MODES]; 2]>,
pub wedge_idx: Align32<[[u16; 16]; 9]>,
pub partition: Align32<[[[u16; N_PARTITIONS + 6]; 4]; N_BL_LEVELS]>,
pub partition: Align32<[[[u16; N_PARTITIONS + 6]; 4]; BlockLevel::COUNT]>,
pub cfl_alpha: Align32<[[u16; 16]; 6]>,
pub txtp_inter1: Align32<[[u16; 16]; 2]>,
pub txtp_inter2: Align32<[u16; 16]>,
Expand Down Expand Up @@ -4966,7 +4967,7 @@ pub(crate) fn rav1d_cdf_thread_update(
update_cdf_3d!(2, N_INTRA_PRED_MODES, 6, m.txtp_intra1);
update_cdf_3d!(3, N_INTRA_PRED_MODES, 4, m.txtp_intra2);
update_bit_1d!(3, m.skip);
for k in 0..N_BL_LEVELS {
for k in 0..BlockLevel::COUNT {
update_cdf_2d!(4, dav1d_partition_type_count[k] as usize, m.partition[k]);
}
update_bit_2d!(N_TX_SIZES, 13, coef.skip);
Expand Down
121 changes: 65 additions & 56 deletions src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,6 @@ use crate::src::levels::BlockSize;
use crate::src::levels::MotionMode;
use crate::src::levels::RectTxfmSize;
use crate::src::levels::TxfmSize;
use crate::src::levels::BL_128X128;
use crate::src::levels::BL_64X64;
use crate::src::levels::BL_8X8;
use crate::src::levels::CFL_PRED;
use crate::src::levels::COMP_INTER_AVG;
use crate::src::levels::COMP_INTER_NONE;
Expand Down Expand Up @@ -1613,7 +1610,7 @@ unsafe fn decode_b_inner(
let cw4 = w4 + ss_hor >> ss_hor;
let ch4 = h4 + ss_ver >> ss_ver;

b.bl = bl as u8;
b.bl = bl;
b.bp = bp as u8;
b.bs = bs as u8;

Expand Down Expand Up @@ -3492,20 +3489,23 @@ unsafe fn decode_sb(
edge_index: EdgeIndex,
) -> Result<(), ()> {
let ts = &mut *t.ts;
let hsz = 16 >> bl;
let hsz = 16 >> bl as u8;
let have_h_split = f.bw > t.bx + hsz;
let have_v_split = f.bh > t.by + hsz;

let sb128 = f.seq_hdr().sb128 != 0;
let intra_edge = &IntraEdges::DEFAULT;

if !have_h_split && !have_v_split {
assert!(bl < BL_8X8);
let next_bl = bl
.decrease()
.expect("BlockLevel::BL_8X8 should never make it here");

return decode_sb(
c,
t,
f,
bl + 1,
next_bl,
intra_edge.branch(sb128, edge_index).split[0],
);
}
Expand All @@ -3519,9 +3519,9 @@ unsafe fn decode_sb(
let pc = if t.frame_thread.pass == 2 {
None
} else {
if false && bl == BL_64X64 {
if false && bl == BlockLevel::Bl64x64 {
println!(
"poc={},y={},x={},bl={},r={}",
"poc={},y={},x={},bl={:?},r={}",
frame_hdr.frame_offset, t.by, t.bx, bl, ts.msac.rng,
);
}
Expand All @@ -3548,7 +3548,7 @@ unsafe fn decode_sb(
}
if debug_block_info!(f, t) {
println!(
"poc={},y={},x={},bl={},ctx={},bp={}: r={}",
"poc={},y={},x={},bl={:?},ctx={},bp={}: r={}",
frame_hdr.frame_offset, t.by, t.bx, bl, ctx, bp, ts.msac.rng,
);
}
Expand Down Expand Up @@ -3578,41 +3578,44 @@ unsafe fn decode_sb(
t.bx -= hsz;
}
PARTITION_SPLIT => {
if bl == BL_8X8 {
let tip = intra_edge.tip(sb128, edge_index);
assert!(hsz == 1);
decode_b(c, t, f, bl, BS_4x4, bp, tip.split[0])?;
let tl_filter = t.tl_4x4_filter;
t.bx += 1;
decode_b(c, t, f, bl, BS_4x4, bp, tip.split[1])?;
t.bx -= 1;
t.by += 1;
decode_b(c, t, f, bl, BS_4x4, bp, tip.split[2])?;
t.bx += 1;
t.tl_4x4_filter = tl_filter;
decode_b(c, t, f, bl, BS_4x4, bp, tip.split[3])?;
t.bx -= 1;
t.by -= 1;
if cfg!(target_arch = "x86_64") && t.frame_thread.pass != 0 {
// In 8-bit mode with 2-pass decoding the coefficient buffer
// can end up misaligned due to skips here.
// Work around the issue by explicitly realigning the buffer.
let p = (t.frame_thread.pass & 1) as usize;
ts.frame_thread[p].cf =
(((ts.frame_thread[p].cf as uintptr_t) + 63) & !63) as *mut DynCoef;
match bl.decrease() {
None => {
let tip = intra_edge.tip(sb128, edge_index);
assert!(hsz == 1);
decode_b(c, t, f, bl, BS_4x4, bp, tip.split[0])?;
let tl_filter = t.tl_4x4_filter;
t.bx += 1;
decode_b(c, t, f, bl, BS_4x4, bp, tip.split[1])?;
t.bx -= 1;
t.by += 1;
decode_b(c, t, f, bl, BS_4x4, bp, tip.split[2])?;
t.bx += 1;
t.tl_4x4_filter = tl_filter;
decode_b(c, t, f, bl, BS_4x4, bp, tip.split[3])?;
t.bx -= 1;
t.by -= 1;
if cfg!(target_arch = "x86_64") && t.frame_thread.pass != 0 {
// In 8-bit mode with 2-pass decoding the coefficient buffer
// can end up misaligned due to skips here.
// Work around the issue by explicitly realigning the buffer.
let p = (t.frame_thread.pass & 1) as usize;
ts.frame_thread[p].cf =
(((ts.frame_thread[p].cf as uintptr_t) + 63) & !63) as *mut DynCoef;
}
}
Some(next_bl) => {
let branch = intra_edge.branch(sb128, edge_index);
decode_sb(c, t, f, next_bl, branch.split[0])?;
t.bx += hsz;
decode_sb(c, t, f, next_bl, branch.split[1])?;
t.bx -= hsz;
t.by += hsz;
decode_sb(c, t, f, next_bl, branch.split[2])?;
t.bx += hsz;
decode_sb(c, t, f, next_bl, branch.split[3])?;
t.bx -= hsz;
t.by -= hsz;
}
} else {
let branch = intra_edge.branch(sb128, edge_index);
decode_sb(c, t, f, bl + 1, branch.split[0])?;
t.bx += hsz;
decode_sb(c, t, f, bl + 1, branch.split[1])?;
t.bx -= hsz;
t.by += hsz;
decode_sb(c, t, f, bl + 1, branch.split[2])?;
t.bx += hsz;
decode_sb(c, t, f, bl + 1, branch.split[3])?;
t.bx -= hsz;
t.by -= hsz;
}
}
PARTITION_T_TOP_SPLIT => {
Expand Down Expand Up @@ -3689,7 +3692,7 @@ unsafe fn decode_sb(
is_split = rav1d_msac_decode_bool(&mut ts.msac, gather_top_partition_prob(pc, bl));
if debug_block_info!(f, t) {
println!(
"poc={},y={},x={},bl={},ctx={},bp={}: r={}",
"poc={},y={},x={},bl={:?},ctx={},bp={}: r={}",
frame_hdr.frame_offset,
t.by,
t.bx,
Expand All @@ -3708,13 +3711,16 @@ unsafe fn decode_sb(
is_split = b.bl != bl;
}

assert!(bl < BL_8X8);
let next_bl = bl
.decrease()
.expect("BlockLevel::BL_8X8 should never make it here");

if is_split {
let branch = intra_edge.branch(sb128, edge_index);
bp = PARTITION_SPLIT;
decode_sb(c, t, f, bl + 1, branch.split[0])?;
decode_sb(c, t, f, next_bl, branch.split[0])?;
t.bx += hsz;
decode_sb(c, t, f, bl + 1, branch.split[1])?;
decode_sb(c, t, f, next_bl, branch.split[1])?;
t.bx -= hsz;
} else {
let node = intra_edge.node(sb128, edge_index);
Expand All @@ -3739,7 +3745,7 @@ unsafe fn decode_sb(
}
if debug_block_info!(f, t) {
println!(
"poc={},y={},x={},bl={},ctx={},bp={}: r={}",
"poc={},y={},x={},bl={:?},ctx={},bp={}: r={}",
frame_hdr.frame_offset,
t.by,
t.bx,
Expand All @@ -3758,13 +3764,16 @@ unsafe fn decode_sb(
is_split = b.bl != bl;
}

assert!(bl < BL_8X8);
let next_bl = bl
.decrease()
.expect("BlockLevel::BL_8X8 should never make it here");

if is_split {
let branch = intra_edge.branch(sb128, edge_index);
bp = PARTITION_SPLIT;
decode_sb(c, t, f, bl + 1, branch.split[0])?;
decode_sb(c, t, f, next_bl, branch.split[0])?;
t.by += hsz;
decode_sb(c, t, f, bl + 1, branch.split[2])?;
decode_sb(c, t, f, next_bl, branch.split[2])?;
t.by -= hsz;
} else {
let node = intra_edge.node(sb128, edge_index);
Expand All @@ -3781,7 +3790,7 @@ unsafe fn decode_sb(
}
}

if t.frame_thread.pass != 2 && (bp != PARTITION_SPLIT || bl == BL_8X8) {
if t.frame_thread.pass != 2 && (bp != PARTITION_SPLIT || bl == BlockLevel::Bl8x8) {
CaseSet::<16, false>::many(
[(&mut *t.a, 0), (&mut t.l, 1)],
[hsz as usize; 2],
Expand Down Expand Up @@ -4059,9 +4068,9 @@ pub(crate) unsafe fn rav1d_decode_tile_sbrow(
) -> Result<(), ()> {
let seq_hdr = &***f.seq_hdr.as_ref().unwrap();
let root_bl = if seq_hdr.sb128 != 0 {
BL_128X128
BlockLevel::Bl128x128
} else {
BL_64X64
BlockLevel::Bl64x64
};
let ts = &mut *t.ts;
let sb_step = f.sb_step;
Expand Down Expand Up @@ -4142,7 +4151,7 @@ pub(crate) unsafe fn rav1d_decode_tile_sbrow(
return Err(());
}
let cdef_idx = &mut (*t.lf_mask).cdef_idx;
if root_bl == BL_128X128 {
if root_bl == BlockLevel::Bl128x128 {
*cdef_idx = [-1; 4];
t.cur_sb_cdef_idx_ptr = cdef_idx.as_mut_ptr();
} else {
Expand Down
11 changes: 7 additions & 4 deletions src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::src::levels::mv;
use crate::src::levels::BlockLevel;
use crate::src::levels::TxfmSize;
use crate::src::levels::TxfmType;
use crate::src::levels::BL_128X128;
use crate::src::levels::COMP_INTER_AVG;
use crate::src::levels::COMP_INTER_NONE;
use crate::src::levels::COMP_INTER_SEG;
Expand Down Expand Up @@ -101,7 +100,11 @@ pub fn get_partition_ctx(
yb8: c_int,
xb8: c_int,
) -> u8 {
(a.partition[xb8 as usize] >> (4 - bl) & 1) + ((l.partition[yb8 as usize] >> (4 - bl) & 1) << 1)
// the right-most ("index zero") bit of the partition represents the 8x8 block level,
// but the BlockLevel enum represents the variants numerically in the opposite order
// (128x128 = 0, 8x8 = 4). The shift reverses the ordering.
let has_bl = |x| (x >> (4 - bl as u8)) & 1;
has_bl(a.partition[xb8 as usize]) + 2 * has_bl(l.partition[yb8 as usize])
}

#[inline]
Expand All @@ -111,7 +114,7 @@ pub fn gather_left_partition_prob(r#in: &[u16; 16], bl: BlockLevel) -> u32 {
// PARTITION_T_BOTTOM_SPLIT and PARTITION_T_LEFT_SPLIT are neighbors.
out +=
r#in[(PARTITION_SPLIT - 1) as usize] as i32 - r#in[PARTITION_T_LEFT_SPLIT as usize] as i32;
if bl != BL_128X128 {
if bl != BlockLevel::Bl128x128 {
out += r#in[(PARTITION_H4 - 1) as usize] as i32 - r#in[PARTITION_H4 as usize] as i32;
}
out as u32
Expand All @@ -128,7 +131,7 @@ pub fn gather_top_partition_prob(r#in: &[u16; 16], bl: BlockLevel) -> u32 {
// PARTITION_V4 is always zero, and the probability for
// PARTITION_T_RIGHT_SPLIT is zero in 128x128 blocks.
out += r#in[(PARTITION_T_LEFT_SPLIT - 1) as usize] as i32;
if bl != BL_128X128 {
if bl != BlockLevel::Bl128x128 {
out += r#in[(PARTITION_V4 - 1) as usize] as i32
- r#in[PARTITION_T_RIGHT_SPLIT as usize] as i32;
}
Expand Down
33 changes: 18 additions & 15 deletions src/intra_edge.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
use crate::include::dav1d::headers::Rav1dPixelLayout;
use crate::src::enum_map::DefaultValue;
use crate::src::levels::BlockLevel;
use crate::src::levels::BL_128X128;
use crate::src::levels::BL_16X16;
use crate::src::levels::BL_32X32;
use crate::src::levels::BL_64X64;
use bitflags::bitflags;
use std::ops::Shr;

Expand Down Expand Up @@ -173,7 +169,7 @@ impl EdgeBranch {
EdgeFlags::LEFT_HAS_BOTTOM.union(
edge_flags
.intersection(EdgeFlags::I420_TOP_HAS_RIGHT)
.select(bl == BL_16X16),
.select(matches!(bl, BlockLevel::Bl16x16)),
randomPoison marked this conversation as resolved.
Show resolved Hide resolved
),
EdgeFlags::LEFT_HAS_BOTTOM,
edge_flags.intersection(EdgeFlags::LEFT_HAS_BOTTOM),
Expand All @@ -187,7 +183,7 @@ impl EdgeBranch {
EdgeFlags::I420_LEFT_HAS_BOTTOM,
EdgeFlags::I422_LEFT_HAS_BOTTOM,
]))
.select(bl == BL_16X16),
.select(matches!(bl, BlockLevel::Bl16x16)),
),
EdgeFlags::TOP_HAS_RIGHT,
edge_flags.intersection(EdgeFlags::TOP_HAS_RIGHT),
Expand Down Expand Up @@ -234,7 +230,7 @@ impl DefaultValue for EdgeTip {
}

impl DefaultValue for EdgeBranch {
const DEFAULT: Self = Self::new(EdgeFlags::empty(), 0 as BlockLevel);
const DEFAULT: Self = Self::new(EdgeFlags::empty(), BlockLevel::DEFAULT);
folkertdev marked this conversation as resolved.
Show resolved Hide resolved
}

struct EdgeIndices {
Expand Down Expand Up @@ -278,7 +274,7 @@ impl<const SB128: bool, const N_BRANCH: usize, const N_TIP: usize>
]),
bl,
);
if bl == BL_16X16 {
if matches!(bl, BlockLevel::Bl16x16) {
let mut n = 0;
while n < B as u8 {
let (tip, next) = indices.tip.pop_front();
Expand All @@ -298,7 +294,10 @@ impl<const SB128: bool, const N_BRANCH: usize, const N_TIP: usize>
branch.split[n as usize] = child_branch;
(self, indices) = self.init_mode_node(
child_branch,
bl + 1,
match bl.decrease() {
None => panic!("BlockLevel::BL_8X8 should never make it here"),
Some(next_bl) => next_bl,
},
folkertdev marked this conversation as resolved.
Show resolved Hide resolved
indices,
!(n == 3 || (n == 1 && !top_has_right)),
n == 0 || (n == 2 && left_has_bottom),
Expand All @@ -324,17 +323,21 @@ impl<const SB128: bool, const N_BRANCH: usize, const N_TIP: usize>

let sb128 = SB128 as u8;

let mut bl = BL_128X128;
while bl <= BL_32X32 {
indices.branch[bl as usize].index = level_index(bl + sb128);
let mut bl = BlockLevel::Bl128x128 as u8;
while bl <= BlockLevel::Bl32x32 as u8 {
kkysen marked this conversation as resolved.
Show resolved Hide resolved
indices.branch[bl as usize].index = level_index(bl as u8 + sb128);
bl += 1;
}

let bl = if SB128 { BL_128X128 } else { BL_64X64 };
let bl = if SB128 {
BlockLevel::Bl128x128
} else {
BlockLevel::Bl64x64
};
(self, indices) = self.init_mode_node(EdgeIndex::root(), bl, indices, true, false);

let mut bl = BL_128X128;
while bl <= BL_32X32 {
let mut bl = BlockLevel::Bl128x128 as u8;
while bl <= BlockLevel::Bl32x32 as u8 {
folkertdev marked this conversation as resolved.
Show resolved Hide resolved
let index = indices.branch[bl as usize].index;
if index != 0 {
assert!(index == level_index(1 + bl + sb128));
Expand Down
Loading
Loading