From 626c7211afac2281633babd867aa32daf6b15455 Mon Sep 17 00:00:00 2001 From: Khyber Sen Date: Thu, 11 Apr 2024 13:59:01 -0700 Subject: [PATCH] `struct RefMvsFrame::r`: Add `DisjointMut`, removing `&mut`s of `Rav1dFrameData` added in #942. --- src/decode.rs | 73 ++++++++++++++-------------- src/ffi_safe.rs | 4 +- src/recon.rs | 16 +++---- src/refmvs.rs | 125 +++++++++++++++++++++++++++++++++--------------- 4 files changed, 133 insertions(+), 85 deletions(-) diff --git a/src/decode.rs b/src/decode.rs index 05674483f..2fb33c770 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -20,6 +20,7 @@ use crate::include::dav1d::headers::SgrIdx; use crate::include::dav1d::headers::RAV1D_MAX_SEGMENTS; use crate::include::dav1d::headers::RAV1D_PRIMARY_REF_NONE; use crate::src::align::Align16; +use crate::src::align::AlignedVec64; use crate::src::cdef::rav1d_cdef_dsp_init; use crate::src::cdf::rav1d_cdf_thread_alloc; use crate::src::cdf::rav1d_cdf_thread_copy; @@ -29,6 +30,7 @@ use crate::src::cdf::CdfMvComponent; use crate::src::cdf::CdfMvContext; use crate::src::ctx::CaseSet; use crate::src::dequant_tables::dav1d_dq_tbl; +use crate::src::disjoint_mut::DisjointMut; use crate::src::enum_map::enum_map; use crate::src::enum_map::enum_map_ty; use crate::src::enum_map::DefaultValue; @@ -149,6 +151,7 @@ use crate::src::refmvs::refmvs_block; use crate::src::refmvs::refmvs_mvpair; use crate::src::refmvs::refmvs_refpair; use crate::src::refmvs::refmvs_temporal_block; +use crate::src::refmvs::RefMvsFrame; use crate::src::tables::cfl_allowed_mask; use crate::src::tables::dav1d_al_part_ctx; use crate::src::tables::dav1d_block_dimensions; @@ -427,7 +430,7 @@ unsafe fn find_matching_ref( if have_top { let mut i = r[0] + t.b.x as usize; - let r2 = f.rf.r[i]; + let r2 = *f.rf.r.index(i); if matches(r2) { masks[0] |= 1; count = 1; @@ -446,7 +449,7 @@ unsafe fn find_matching_ref( let mut x = aw4; while x < w4 { i += aw4 as usize; - let r2 = f.rf.r[i]; + let r2 = *f.rf.r.index(i); if matches(r2) { masks[0] |= mask; count += 1; @@ -461,7 +464,7 @@ unsafe fn find_matching_ref( } } if have_left { - let get_r2 = |i: usize| f.rf.r[r[i] + t.b.x as usize - 1]; + let get_r2 = |i: usize| *f.rf.r.index(r[i] + t.b.x as usize - 1); let mut i = 1; let r2 = get_r2(i); @@ -496,20 +499,20 @@ unsafe fn find_matching_ref( } } } - if have_topleft && matches(f.rf.r[r[0] + t.b.x as usize - 1]) { + if have_topleft && matches(*f.rf.r.index(r[0] + t.b.x as usize - 1)) { masks[1] |= 1 << 32; count += 1; if count >= 8 { return; } } - if have_topright && matches(f.rf.r[r[0] + t.b.x as usize + bw4 as usize]) { + if have_topright && matches(*f.rf.r.index(r[0] + t.b.x as usize + bw4 as usize)) { masks[0] |= 1 << 32; } } unsafe fn derive_warpmv( - r: &[refmvs_block], + r: &DisjointMut>, t: &Rav1dTaskContext, bw4: c_int, bh4: c_int, @@ -524,7 +527,7 @@ unsafe fn derive_warpmv( // (and not just by a constant -1). // See `-off` below. let offset = (t.b.y & 31) + 5; - r[t.rt.r[(offset as isize + i as isize) as usize] + j as usize] + *r.index(t.rt.r[(offset as isize + i as isize) as usize] + j as usize) }; let bs = |rp: refmvs_block| dav1d_block_dimensions[rp.bs as usize]; @@ -893,7 +896,7 @@ unsafe fn get_prev_frame_segid( unsafe fn splat_oneref_mv( c: &Rav1dContext, t: &Rav1dTaskContext, - r: &mut [refmvs_block], + rf: &RefMvsFrame, bs: BlockSize, b: &Av1Block, bw4: usize, @@ -913,14 +916,14 @@ unsafe fn splat_oneref_mv( bs, mf: (mode == GLOBALMV && cmp::min(bw4, bh4) >= 2) as u8 | (mode == NEWMV) as u8 * 2, }); - c.refmvs_dsp.splat_mv(r, &t.rt, &tmpl, t.b, bw4, bh4); + c.refmvs_dsp.splat_mv(rf, &t.rt, &tmpl, t.b, bw4, bh4); } #[inline] unsafe fn splat_intrabc_mv( c: &Rav1dContext, t: &Rav1dTaskContext, - r: &mut [refmvs_block], + rf: &RefMvsFrame, bs: BlockSize, b: &Av1Block, bw4: usize, @@ -934,14 +937,14 @@ unsafe fn splat_intrabc_mv( bs, mf: 0, }); - c.refmvs_dsp.splat_mv(r, &t.rt, &tmpl, t.b, bw4, bh4); + c.refmvs_dsp.splat_mv(rf, &t.rt, &tmpl, t.b, bw4, bh4); } #[inline] unsafe fn splat_tworef_mv( c: &Rav1dContext, t: &Rav1dTaskContext, - r: &mut [refmvs_block], + rf: &RefMvsFrame, bs: BlockSize, b: &Av1Block, bw4: usize, @@ -957,14 +960,14 @@ unsafe fn splat_tworef_mv( bs, mf: (mode == GLOBALMV_GLOBALMV) as u8 | (1 << mode & 0xbc != 0) as u8 * 2, }); - c.refmvs_dsp.splat_mv(r, &t.rt, &tmpl, t.b, bw4, bh4); + c.refmvs_dsp.splat_mv(rf, &t.rt, &tmpl, t.b, bw4, bh4); } #[inline] unsafe fn splat_intraref( c: &Rav1dContext, t: &Rav1dTaskContext, - r: &mut [refmvs_block], + rf: &RefMvsFrame, bs: BlockSize, bw4: usize, bh4: usize, @@ -977,7 +980,7 @@ unsafe fn splat_intraref( bs, mf: 0, }); - c.refmvs_dsp.splat_mv(r, &t.rt, &tmpl, t.b, bw4, bh4); + c.refmvs_dsp.splat_mv(rf, &t.rt, &tmpl, t.b, bw4, bh4); } fn mc_lowest_px( @@ -1064,7 +1067,7 @@ unsafe fn affine_lowest_px_chroma( } unsafe fn obmc_lowest_px( - r: &[refmvs_block], + r: &DisjointMut>, t: &mut Rav1dTaskContext, ts: &Rav1dTileState, layout: Rav1dPixelLayout, @@ -1089,7 +1092,7 @@ unsafe fn obmc_lowest_px( let mut i = 0; let mut x = 0; while x < w4 && i < cmp::min(b_dim[2] as c_int, 4) { - let a_r = r[ri[0] + t.b.x as usize + x as usize + 1]; + let a_r = *r.index(ri[0] + t.b.x as usize + x as usize + 1); let a_b_dim = &dav1d_block_dimensions[a_r.bs as usize]; if a_r.r#ref.r#ref[0] as c_int > 0 { let oh4 = cmp::min(b_dim[1] as c_int, 16) >> 1; @@ -1110,7 +1113,7 @@ unsafe fn obmc_lowest_px( let mut i = 0; let mut y = 0; while y < h4 && i < cmp::min(b_dim[3] as c_int, 4) { - let l_r = r[ri[y as usize + 1 + 1] + t.b.x as usize - 1]; + let l_r = *r.index(ri[y as usize + 1 + 1] + t.b.x as usize - 1); let l_b_dim = &dav1d_block_dimensions[l_r.bs as usize]; if l_r.r#ref.r#ref[0] as c_int > 0 { let oh4 = iclip(l_b_dim[1] as c_int, 2, b_dim[1] as c_int); @@ -1221,16 +1224,15 @@ unsafe fn decode_b_inner( }, ); if frame_type.is_inter_or_switch() { - let r = &mut f.rf.r - [t.rt.r[(t.b.y as usize & 31) + 5 + bh4 as usize - 1] + t.b.x as usize..] - [..bw4 as usize]; + let ri = t.rt.r[(t.b.y as usize & 31) + 5 + bh4 as usize - 1] + t.b.x as usize; + let r = &mut *f.rf.r.index_mut(ri..ri + bw4 as usize); for block in r { block.r#ref.r#ref[0] = 0; block.bs = bs; } let rr = &t.rt.r[(t.b.y as usize & 31) + 5..][..bh4 as usize - 1]; for r in rr { - let block = &mut f.rf.r[r + t.b.x as usize + bw4 as usize - 1]; + let block = &mut f.rf.r.index_mut(r + t.b.x as usize + bw4 as usize - 1); block.r#ref.r#ref[0] = 0; block.bs = bs; } @@ -1296,9 +1298,8 @@ unsafe fn decode_b_inner( ); if frame_type.is_inter_or_switch() { - let r = &mut f.rf.r - [t.rt.r[(t.b.y as usize & 31) + 5 + bh4 as usize - 1] + t.b.x as usize..] - [..bw4 as usize]; + let ri = t.rt.r[(t.b.y as usize & 31) + 5 + bh4 as usize - 1] + t.b.x as usize; + let r = &mut *f.rf.r.index_mut(ri..ri + bw4 as usize); for block in r { block.r#ref.r#ref[0] = b.r#ref()[0] + 1; block.mv.mv[0] = b.mv()[0]; @@ -1306,7 +1307,7 @@ unsafe fn decode_b_inner( } let rr = &t.rt.r[(t.b.y as usize & 31) + 5..][..bh4 as usize - 1]; for r in rr { - let block = &mut f.rf.r[r + t.b.x as usize + bw4 as usize - 1]; + let block = &mut f.rf.r.index_mut(r + t.b.x as usize + bw4 as usize - 1); block.r#ref.r#ref[0] = b.r#ref()[0] + 1; block.mv.mv[0] = b.mv()[0]; block.bs = bs; @@ -1976,7 +1977,7 @@ unsafe fn decode_b_inner( } let frame_hdr = f.frame_hdr(); if frame_hdr.frame_type.is_inter_or_switch() || frame_hdr.allow_intrabc { - splat_intraref(c, t, &mut f.rf.r, bs, bw4 as usize, bh4 as usize); + splat_intraref(c, t, &f.rf, bs, bw4 as usize, bh4 as usize); } } else if frame_hdr.frame_type.is_key_or_intra() { // intra block copy @@ -2093,7 +2094,7 @@ unsafe fn decode_b_inner( bd_fn.recon_b_inter(f, t, bs, b)?; } - splat_intrabc_mv(c, t, &mut f.rf.r, bs, b, bw4 as usize, bh4 as usize); + splat_intrabc_mv(c, t, &f.rf, bs, b, bw4 as usize, bh4 as usize); CaseSet::<32, false>::many( [(&mut t.l, 1), (&mut *t.a, 0)], @@ -2947,9 +2948,9 @@ unsafe fn decode_b_inner( // context updates if is_comp { - splat_tworef_mv(c, t, &mut f.rf.r, bs, b, bw4 as usize, bh4 as usize); + splat_tworef_mv(c, t, &f.rf, bs, b, bw4 as usize, bh4 as usize); } else { - splat_oneref_mv(c, t, &mut f.rf.r, bs, b, bw4 as usize, bh4 as usize); + splat_oneref_mv(c, t, &f.rf, bs, b, bw4 as usize, bh4 as usize); } CaseSet::<32, false>::many( @@ -3079,13 +3080,13 @@ unsafe fn decode_b_inner( <[_; 2]>::try_from(&t.rt.r[(t.b.y as usize & 31) + 5 - 1..][..2]).unwrap(); if bw4 == 1 { - is_sub8x8 &= f.rf.r[r[1] + t.b.x as usize - 1].r#ref.r#ref[0] > 0; + is_sub8x8 &= f.rf.r.index(r[1] + t.b.x as usize - 1).r#ref.r#ref[0] > 0; } if bh4 == ss_ver { - is_sub8x8 &= f.rf.r[r[0] + t.b.x as usize].r#ref.r#ref[0] > 0; + is_sub8x8 &= f.rf.r.index(r[0] + t.b.x as usize).r#ref.r#ref[0] > 0; } if bw4 == 1 && bh4 == ss_ver { - is_sub8x8 &= f.rf.r[r[0] + t.b.x as usize - 1].r#ref.r#ref[0] > 0; + is_sub8x8 &= f.rf.r.index(r[0] + t.b.x as usize - 1).r#ref.r#ref[0] > 0; } r @@ -3096,7 +3097,7 @@ unsafe fn decode_b_inner( // chroma prediction if is_sub8x8 { if bw4 == 1 && bh4 == ss_ver { - let rr = f.rf.r[r[0] + t.b.x as usize - 1]; + let rr = *f.rf.r.index(r[0] + t.b.x as usize - 1); mc_lowest_px( &mut lowest_px[rr.r#ref.r#ref[0] as usize - 1][1], t.b.y - 1, @@ -3107,7 +3108,7 @@ unsafe fn decode_b_inner( ); } if bw4 == 1 { - let rr = f.rf.r[r[1] + t.b.x as usize - 1]; + let rr = *f.rf.r.index(r[1] + t.b.x as usize - 1); mc_lowest_px( &mut lowest_px[rr.r#ref.r#ref[0] as usize - 1][1], t.b.y, @@ -3118,7 +3119,7 @@ unsafe fn decode_b_inner( ); } if bh4 == ss_ver { - let rr = f.rf.r[r[0] + t.b.x as usize]; + let rr = *f.rf.r.index(r[0] + t.b.x as usize); mc_lowest_px( &mut lowest_px[rr.r#ref.r#ref[0] as usize - 1][1], t.b.y - 1, diff --git a/src/ffi_safe.rs b/src/ffi_safe.rs index 980c47a03..ca8ca7b97 100644 --- a/src/ffi_safe.rs +++ b/src/ffi_safe.rs @@ -16,7 +16,7 @@ impl<'a, T> FFISafe<'a, T> { ptr::from_ref(this).cast() } - pub fn new_mut(this: &'a mut T) -> *mut Self { + pub fn _new_mut(this: &'a mut T) -> *mut Self { ptr::from_mut(this).cast() } @@ -31,7 +31,7 @@ impl<'a, T> FFISafe<'a, T> { /// # Safety /// /// `this` must have been returned from [`Self::new_mut`]. - pub unsafe fn get_mut(this: *mut Self) -> &'a mut T { + pub unsafe fn _get_mut(this: *mut Self) -> &'a mut T { // SAFETY: `this` originally was a `&'a mut T` in `Self::new_mut`. unsafe { &mut *this.cast() } } diff --git a/src/recon.rs b/src/recon.rs index 326aa5588..8ce9d9da9 100644 --- a/src/recon.rs +++ b/src/recon.rs @@ -2227,7 +2227,7 @@ unsafe fn obmc( let mut i = 0; let mut x = 0; while x < w4 && i < cmp::min(b_dim[2], 4) { - let a_r = f.rf.r[r[0] + t.b.x as usize + x as usize + 1]; + let a_r = *f.rf.r.index(r[0] + t.b.x as usize + x as usize + 1); let a_b_dim = &dav1d_block_dimensions[a_r.bs as usize]; let step4 = clip(a_b_dim[0], 2, 16); if a_r.r#ref.r#ref[0] > 0 { @@ -2267,7 +2267,7 @@ unsafe fn obmc( let mut i = 0; let mut y = 0; while y < h4 && i < cmp::min(b_dim[3], 4) { - let l_r = f.rf.r[r[y as usize + 1 + 1] + t.b.x as usize - 1]; + let l_r = *f.rf.r.index(r[y as usize + 1 + 1] + t.b.x as usize - 1); let l_b_dim = &dav1d_block_dimensions[l_r.bs as usize]; let step4 = clip(l_b_dim[1], 2, 16); if l_r.r#ref.r#ref[0] > 0 { @@ -3554,13 +3554,13 @@ pub(crate) unsafe fn rav1d_recon_b_inter( assert!(ss_hor == 1); let r = &t.rt.r[(t.b.y as usize & 31) + 5 - 1..]; if bw4 == 1 { - is_sub8x8 &= f.rf.r[r[1] + t.b.x as usize - 1].r#ref.r#ref[0] > 0; + is_sub8x8 &= f.rf.r.index(r[1] + t.b.x as usize - 1).r#ref.r#ref[0] > 0; } if bh4 == ss_ver { - is_sub8x8 &= f.rf.r[r[0] + t.b.x as usize].r#ref.r#ref[0] > 0; + is_sub8x8 &= f.rf.r.index(r[0] + t.b.x as usize).r#ref.r#ref[0] > 0; } if bw4 == 1 && bh4 == ss_ver { - is_sub8x8 &= f.rf.r[r[0] + t.b.x as usize - 1].r#ref.r#ref[0] > 0; + is_sub8x8 &= f.rf.r.index(r[0] + t.b.x as usize - 1).r#ref.r#ref[0] > 0; } r } else { @@ -3572,7 +3572,7 @@ pub(crate) unsafe fn rav1d_recon_b_inter( let mut v_off = 0isize; if bw4 == 1 && bh4 == ss_ver { for pl in 0..2 { - let r = f.rf.r[r[0] + t.b.x as usize - 1]; + let r = *f.rf.r.index(r[0] + t.b.x as usize - 1); mc::( f, &mut t.scratch.c2rust_unnamed.emu_edge, @@ -3607,7 +3607,7 @@ pub(crate) unsafe fn rav1d_recon_b_inter( let left_filter_2d = dav1d_filter_2d[t.l.filter[1][by4 as usize] as usize] [t.l.filter[0][by4 as usize] as usize]; for pl in 0..2 { - let r = f.rf.r[r[1] + t.b.x as usize - 1]; + let r = *f.rf.r.index(r[1] + t.b.x as usize - 1); mc::( f, &mut t.scratch.c2rust_unnamed.emu_edge, @@ -3640,7 +3640,7 @@ pub(crate) unsafe fn rav1d_recon_b_inter( let top_filter_2d = dav1d_filter_2d[(*t.a).filter[1][bx4 as usize] as usize] [(*t.a).filter[0][bx4 as usize] as usize]; for pl in 0..2 { - let r = f.rf.r[r[0] + t.b.x as usize]; + let r = *f.rf.r.index(r[0] + t.b.x as usize); mc::( f, &mut t.scratch.c2rust_unnamed.emu_edge, diff --git a/src/refmvs.rs b/src/refmvs.rs index f0cf5bed7..e9909766c 100644 --- a/src/refmvs.rs +++ b/src/refmvs.rs @@ -5,10 +5,12 @@ use crate::include::dav1d::headers::Rav1dSequenceHeader; use crate::include::dav1d::headers::Rav1dWarpedMotionType; use crate::src::align::Align16; use crate::src::align::AlignedVec64; +use crate::src::disjoint_mut::DisjointMut; use crate::src::env::fix_mv_precision; use crate::src::env::get_gmv_2d; use crate::src::env::get_poc_diff; use crate::src::error::Rav1dResult; +use crate::src::ffi_safe::FFISafe; use crate::src::internal::Bxy; use crate::src::intra_edge::EdgeFlags; use crate::src::levels::mv; @@ -16,6 +18,7 @@ use crate::src::levels::BlockSize; use crate::src::tables::dav1d_block_dimensions; use cfg_if::cfg_if; use libc::ptrdiff_t; +use std::array; use std::cmp; use std::ffi::c_int; use std::ffi::c_uint; @@ -47,6 +50,8 @@ extern "C" { row_end8: c_int, col_start8: c_int, row_start8: c_int, + _r: *const FFISafe>>, + _ri: &[usize; 31], ); } @@ -89,6 +94,8 @@ extern "C" { row_end8: c_int, col_start8: c_int, row_start8: c_int, + _r: *const FFISafe>>, + _ri: &[usize; 31], ); fn dav1d_save_tmvs_avx512icl( rp: *mut refmvs_temporal_block, @@ -99,6 +106,8 @@ extern "C" { row_end8: c_int, col_start8: c_int, row_start8: c_int, + _r: *const FFISafe>>, + _ri: &[usize; 31], ); } @@ -205,7 +214,7 @@ pub(crate) struct RefMvsFrame { pub rp_ref: *const *mut refmvs_temporal_block, pub rp_proj: AlignedVec64, pub rp_stride: u32, - pub r: AlignedVec64, + pub r: DisjointMut>, pub r_stride: u32, pub n_tile_rows: u32, pub n_tile_threads: u32, @@ -289,18 +298,6 @@ pub(crate) struct refmvs_tile { pub tile_row: refmvs_tile_range, } -impl refmvs_tile { - pub fn r_ptrs(&self, r: &[refmvs_block]) -> [*const refmvs_block; 37] { - self.r - .map(|i| r.get(i).map_or_else(ptr::null, |r| r as *const _)) - } - - pub fn r_ptrs_mut(&self, r: &mut [refmvs_block]) -> [*mut refmvs_block; 37] { - self.r - .map(|i| r.get_mut(i).map_or_else(ptr::null_mut, |r| r as *mut _)) - } -} - #[derive(Copy, Clone, Default)] #[repr(C)] pub struct refmvs_candidate { @@ -326,6 +323,8 @@ pub type save_tmvs_fn = unsafe extern "C" fn( row_end8: c_int, col_start8: c_int, row_start8: c_int, + r: *const FFISafe>>, + ri: &[usize; 31], ) -> (); #[cfg(all(feature = "asm", any(target_arch = "arm", target_arch = "aarch64"),))] @@ -339,6 +338,8 @@ extern "C" { row_end8: c_int, col_start8: c_int, row_start8: c_int, + _r: *const FFISafe>>, + _ri: &[usize; 31], ); } @@ -362,15 +363,33 @@ pub(crate) struct Rav1dRefmvsDSPContext { impl Rav1dRefmvsDSPContext { pub unsafe fn splat_mv( &self, - r: &mut [refmvs_block], + rf: &RefMvsFrame, rt: &refmvs_tile, rmv: &Align16, b4: Bxy, bw4: usize, bh4: usize, ) { - let mut r = rt.r_ptrs_mut(r); - let rr = &mut r[(b4.y as usize & 31) + 5..]; + let start = (b4.y as usize & 31) + 5; + let bx4 = b4.x as usize; + let mut r: [_; 37] = array::from_fn(|i| { + if i < start { + return None; + } + let ri = rt.r[i]; + if ri > rf.r.len() { + return None; + } + // This is the range that will actually be accessed, + // but `splat_mv` expects a pointer offset `bx4` backwards. + Some(rf.r.index_mut(ri + bx4..ri + bx4 + bw4)) + }); + let mut r: [_; 37] = array::from_fn(|i| { + r[i].as_mut() + .map(|r| r.as_mut_ptr().offset(-(bx4 as isize))) + .unwrap_or_else(ptr::null_mut) + }); + let rr = &mut r[start..][..bh4]; let bx4 = b4.x as _; let bw4 = bw4 as _; let bh4 = bh4 as _; @@ -464,7 +483,9 @@ fn scan_row( cnt: &mut usize, r#ref: refmvs_refpair, gmv: &[mv; 2], - b: &[refmvs_block], + r: &DisjointMut>, + b_offset: usize, + // b: &[refmvs_block], bw4: c_int, w4: c_int, max_rows: c_int, @@ -472,7 +493,7 @@ fn scan_row( have_newmv_match: &mut c_int, have_refmv_match: &mut c_int, ) -> c_int { - let mut cand_b = b[0]; + let mut cand_b = *r.index(b_offset); let first_cand_bs = cand_b.bs; let first_cand_b_dim = &dav1d_block_dimensions[first_cand_bs as usize]; let mut cand_bw4 = first_cand_b_dim[0] as c_int; @@ -520,7 +541,7 @@ fn scan_row( if x >= w4 { return 1; } - cand_b = b[x as usize]; + cand_b = *r.index(b_offset + x as usize); cand_bw4 = dav1d_block_dimensions[cand_b.bs as usize][0] as c_int; assert!(cand_bw4 < bw4); len = cmp::max(step, cand_bw4); @@ -532,7 +553,7 @@ fn scan_col( cnt: &mut usize, r#ref: refmvs_refpair, gmv: &[mv; 2], - r: &[refmvs_block], + r: &DisjointMut>, b: &[usize], bh4: c_int, h4: c_int, @@ -542,7 +563,7 @@ fn scan_col( have_newmv_match: &mut c_int, have_refmv_match: &mut c_int, ) -> c_int { - let mut cand_b = r[b[0] + bx4 as usize]; + let mut cand_b = *r.index(b[0] + bx4 as usize); let first_cand_bs = cand_b.bs; let first_cand_b_dim = &dav1d_block_dimensions[first_cand_bs as usize]; let mut cand_bh4 = first_cand_b_dim[1] as c_int; @@ -590,7 +611,7 @@ fn scan_col( if y >= h4 { return 1; } - cand_b = r[b[y as usize] + bx4 as usize]; + cand_b = *r.index(b[y as usize] + bx4 as usize); cand_bh4 = dav1d_block_dimensions[cand_b.bs as usize][1] as c_int; assert!(cand_bh4 < bh4); len = cmp::max(step, cand_bh4); @@ -887,13 +908,14 @@ pub(crate) fn rav1d_refmvs_find( 0 => 0, _ => 1, }; - b_top = &rf.r[i - b_top_offset..]; + b_top = i - b_top_offset; n_rows = scan_row( mvstack, cnt, r#ref, &gmv, - &b_top[b_top_offset..], + &rf.r, + b_top + b_top_offset, bw4, w4, max_rows as c_int, @@ -946,7 +968,7 @@ pub(crate) fn rav1d_refmvs_find( mvstack, cnt, 4, - b_top[bw4 as usize + b_top_offset], + *rf.r.index(b_top + bw4 as usize + b_top_offset), r#ref, &gmv, &mut have_newmv, @@ -1018,7 +1040,7 @@ pub(crate) fn rav1d_refmvs_find( mvstack, cnt, 4, - b_top[b_top_offset - 1], + *rf.r.index(b_top + b_top_offset - 1), r#ref, &gmv, &mut have_dummy_newmv_match, @@ -1032,13 +1054,15 @@ pub(crate) fn rav1d_refmvs_find( let mut n_cols = n_cols; for n in 2..=3 { if n > n_rows && n <= max_rows { + let ri = + rt.r[(((by4 & 31) - 2 * n as c_int + 1 | 1) + 5) as usize] + (bx4 as usize | 1); n_rows = n_rows.wrapping_add(scan_row( mvstack, cnt, r#ref, &gmv, - &rf.r[rt.r[(((by4 & 31) - 2 * n as c_int + 1 | 1) + 5) as usize] - + (bx4 as usize | 1)..], + &rf.r, + ri, bw4, w4, (1 + max_rows - n) as _, @@ -1096,7 +1120,7 @@ pub(crate) fn rav1d_refmvs_find( if n_rows != !0 { let mut x = 0; while x < sz4 { - let cand_b = b_top[x as usize + b_top_offset]; + let cand_b = *rf.r.index(b_top + x as usize + b_top_offset); add_compound_extended_candidate( same, &mut same_count, @@ -1114,7 +1138,7 @@ pub(crate) fn rav1d_refmvs_find( if n_cols != !0 { let mut y = 0; while y < sz4 { - let cand_b = rf.r[b_left[y as usize] + bx4 as usize - 1]; + let cand_b = *rf.r.index(b_left[y as usize] + bx4 as usize - 1); add_compound_extended_candidate( same, &mut same_count, @@ -1204,7 +1228,7 @@ pub(crate) fn rav1d_refmvs_find( if n_rows != !0 { let mut x = 0; while x < sz4 && *cnt < 2 { - let cand_b = b_top[x as usize + b_top_offset]; + let cand_b = *rf.r.index(b_top + x as usize + b_top_offset); add_single_extended_candidate(mvstack, cnt, cand_b, sign, &rf.sign_bias); x += dav1d_block_dimensions[cand_b.bs as usize][0] as c_int; } @@ -1214,7 +1238,7 @@ pub(crate) fn rav1d_refmvs_find( if n_cols != !0 { let mut y = 0; while y < sz4 && *cnt < 2 { - let cand_b = rf.r[b_left[y as usize] + bx4 as usize - 1]; + let cand_b = *rf.r.index(b_left[y as usize] + bx4 as usize - 1); add_single_extended_candidate(mvstack, cnt, cand_b, sign, &rf.sign_bias); y += dav1d_block_dimensions[cand_b.bs as usize][1] as c_int; } @@ -1264,11 +1288,32 @@ pub(crate) unsafe fn rav1d_refmvs_save_tmvs( let stride = rf.rp_stride as isize; let ref_sign = &rf.mfmv_sign; let rp = rf.rp.offset(row_start8 as isize * stride); - let r = rt.r_ptrs(&rf.r); - let rr = <&[_; 31]>::try_from(&r[6..]).unwrap(); + let ri = <&[_; 31]>::try_from(&rt.r[6..]).unwrap(); + + // SAFETY: Note that for asm calls, disjointedness is unchecked here, + // even with `#[cfg(debug_assertions)]`. This is because the disjointedness + // is more fine-grained than the pointers passed to asm. + // For the Rust fallback fn, the extra args `&rf.r` and `ri` + // are passed to do allow for disjointedness checking. + let rr = &ri.map(|ri| { + if ri > rf.r.len() { + return ptr::null(); + } + // SAFETY: `.add` is in-bounds; checked above. + unsafe { rf.r.as_mut_ptr().cast_const().add(ri) } + }); (dsp.save_tmvs)( - rp, stride, rr, ref_sign, col_end8, row_end8, col_start8, row_start8, + rp, + stride, + rr, + ref_sign, + col_end8, + row_end8, + col_start8, + row_start8, + FFISafe::new(&rf.r), + ri, ); } @@ -1453,22 +1498,24 @@ unsafe extern "C" fn load_tmvs_c( unsafe extern "C" fn save_tmvs_c( mut rp: *mut refmvs_temporal_block, stride: ptrdiff_t, - rr: *const [*const refmvs_block; 31], + _rr: *const [*const refmvs_block; 31], ref_sign: *const [u8; 7], col_end8: c_int, row_end8: c_int, col_start8: c_int, row_start8: c_int, + r: *const FFISafe>>, + ri: &[usize; 31], ) { - let rr = &*rr; + let r = FFISafe::get(r); let ref_sign = &*ref_sign; let [col_end8, row_end8, col_start8, row_start8] = [col_end8, row_end8, col_start8, row_start8].map(|it| it as usize); for y in row_start8..row_end8 { - let b = rr[(y & 15) * 2]; + let b = ri[(y & 15) * 2]; let mut x = col_start8; while x < col_end8 { - let cand_b = *b.add(x * 2 + 1); + let cand_b = *r.index(b + x * 2 + 1); let bw8 = dav1d_block_dimensions[cand_b.bs as usize][0] + 1 >> 1; let block = |i: usize| { let mv = cand_b.mv.mv[i];