diff --git a/src/cdef_apply.rs b/src/cdef_apply.rs index bb9996ae5..1ca14cb57 100644 --- a/src/cdef_apply.rs +++ b/src/cdef_apply.rs @@ -142,11 +142,11 @@ pub(crate) fn rav1d_cdef_brow( sbrow_start: bool, sby: c_int, ) { - let bd = BD::from_c(f.bitdepth_max); + let bd = BD::from_c(f.content.bitdepth_max); let bitdepth_min_8 = match BD::BPC { BPC::BPC8 => 0, - BPC::BPC16 => f.cur.p.bpc - 8, + BPC::BPC16 => f.content.cur.p.bpc - 8, }; let mut edges: CdefEdgeFlags = if by_start > 0 { CdefEdgeFlags::HAVE_BOTTOM | CdefEdgeFlags::HAVE_TOP @@ -155,10 +155,10 @@ pub(crate) fn rav1d_cdef_brow( }; let mut ptrs = p; let sbsz = 16; - let sb64w = f.sb128w << 1; - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let sb64w = f.content.sb128w << 1; + let frame_hdr = &f.frame_hdr; let damping = frame_hdr.cdef.damping + bitdepth_min_8; - let layout: Rav1dPixelLayout = f.cur.p.layout; + let layout: Rav1dPixelLayout = f.content.cur.p.layout; let uv_idx = (Rav1dPixelLayout::I444 as c_uint).wrapping_sub(layout as c_uint) as c_int; let ss_ver = (layout == Rav1dPixelLayout::I420) as c_int; let ss_hor = (layout != Rav1dPixelLayout::I444) as c_int; @@ -167,16 +167,16 @@ pub(crate) fn rav1d_cdef_brow( let uv_dir: &[u8; 8] = &UV_DIRS[(layout == Rav1dPixelLayout::I422) as usize]; let have_tt = c.tc.len() > 1; - let sb128 = f.seq_hdr.as_ref().unwrap().sb128; + let sb128 = f.seq_hdr.sb128; let resize = frame_hdr.size.width[0] != frame_hdr.size.width[1]; - let y_stride: ptrdiff_t = BD::pxstride(f.cur.stride[0]); - let uv_stride: ptrdiff_t = BD::pxstride(f.cur.stride[1]); + let y_stride: ptrdiff_t = BD::pxstride(f.content.cur.stride[0]); + let uv_stride: ptrdiff_t = BD::pxstride(f.content.cur.stride[1]); let mut bit = false; for by in (by_start..by_end).step_by(2) { let tf = tc.top_pre_cdef_toggle != 0; let by_idx = (by & 30) >> 1; - if by + 2 >= f.bh { + if by + 2 >= f.content.bh { edges.remove(CdefEdgeFlags::HAVE_BOTTOM); } @@ -185,14 +185,14 @@ pub(crate) fn rav1d_cdef_brow( { // backup pre-filter data for next iteration let cdef_top_bak = [ - f.lf.cdef_line[!tf as usize][0] + f.content.lf.cdef_line[!tf as usize][0] .wrapping_add_signed(have_tt as isize * sby as isize * 4 * y_stride), - f.lf.cdef_line[!tf as usize][1] + f.content.lf.cdef_line[!tf as usize][1] .wrapping_add_signed(have_tt as isize * sby as isize * 8 * uv_stride), - f.lf.cdef_line[!tf as usize][2] + f.content.lf.cdef_line[!tf as usize][2] .wrapping_add_signed(have_tt as isize * sby as isize * 8 * uv_stride), ]; - backup2lines::(&f.lf.cdef_line_buf, cdef_top_bak, ptrs, layout); + backup2lines::(&f.content.lf.cdef_line_buf, cdef_top_bak, ptrs, layout); } let mut lr_bak = @@ -205,7 +205,8 @@ pub(crate) fn rav1d_cdef_brow( for sbx in 0..sb64w { let sb128x = sbx >> 1; let sb64_idx = ((by & sbsz) >> 3) + (sbx & 1); - let cdef_idx = f.lf.mask[(lflvl_offset + sb128x) as usize].cdef_idx[sb64_idx as usize] + let cdef_idx = f.content.lf.mask[(lflvl_offset + sb128x) as usize].cdef_idx + [sb64_idx as usize] .get() as c_int; if cdef_idx == -1 || frame_hdr.cdef.y_strength[cdef_idx as usize] == 0 @@ -214,8 +215,8 @@ pub(crate) fn rav1d_cdef_brow( last_skip = true; } else { // Create a complete 32-bit mask for the sb row ahead of time. - let noskip_row = - &f.lf.mask[(lflvl_offset + sb128x) as usize].noskip_mask[by_idx as usize]; + let noskip_row = &f.content.lf.mask[(lflvl_offset + sb128x) as usize].noskip_mask + [by_idx as usize]; let noskip_mask = (noskip_row[1].get() as u32) << 16 | noskip_row[0].get() as u32; let y_lvl = frame_hdr.cdef.y_strength[cdef_idx as usize]; @@ -234,8 +235,8 @@ pub(crate) fn rav1d_cdef_brow( uv_sec_lvl <<= bitdepth_min_8; let mut bptrs = iptrs; - for bx in (sbx * sbsz..cmp::min((sbx + 1) * sbsz, f.bw)).step_by(2) { - if bx + 2 >= f.bw { + for bx in (sbx * sbsz..cmp::min((sbx + 1) * sbsz, f.content.bw)).step_by(2) { + if bx + 2 >= f.content.bw { edges.remove(CdefEdgeFlags::HAVE_RIGHT); } @@ -262,7 +263,11 @@ pub(crate) fn rav1d_cdef_brow( let mut variance = 0; let dir = if y_pri_lvl != 0 || uv_pri_lvl != 0 { - f.dsp.cdef.dir.call::(bptrs[0], &mut variance, bd) + f.content + .dsp + .cdef + .dir + .call::(bptrs[0], &mut variance, bd) } else { 0 }; @@ -272,14 +277,14 @@ pub(crate) fn rav1d_cdef_brow( } else if sbrow_start && by == by_start { let top = if resize { WithOffset { - data: &f.lf.cdef_line_buf, - offset: f.lf.cdef_lpf_line[0], + data: &f.content.lf.cdef_line_buf, + offset: f.content.lf.cdef_lpf_line[0], } + ((sby - 1) * 4) as isize * y_stride + (bx * 4) as isize } else { WithOffset { - data: &f.lf.lr_line_buf, - offset: f.lf.lr_lpf_line[0], + data: &f.content.lf.lr_line_buf, + offset: f.content.lf.lr_lpf_line[0], } + (sby * (4 << sb128) - 4) as isize * y_stride + (bx * 4) as isize }; @@ -287,21 +292,21 @@ pub(crate) fn rav1d_cdef_brow( Some((top, WithOffset::pic(bottom))) } else if !sbrow_start && by + 2 >= by_end { let top = WithOffset { - data: &f.lf.cdef_line_buf, - offset: f.lf.cdef_line[tf as usize][0], + data: &f.content.lf.cdef_line_buf, + offset: f.content.lf.cdef_line[tf as usize][0], } + (sby * 4) as isize * y_stride + (bx * 4) as isize; let buf = if resize { WithOffset { - data: &f.lf.cdef_line_buf, - offset: f.lf.cdef_lpf_line[0], + data: &f.content.lf.cdef_line_buf, + offset: f.content.lf.cdef_lpf_line[0], } + (sby * 4 + 2) as isize * y_stride + (bx * 4) as isize } else { let line = sby * (4 << sb128) + 4 * sb128 as c_int + 2; WithOffset { - data: &f.lf.lr_line_buf, - offset: f.lf.lr_lpf_line[0], + data: &f.content.lf.lr_line_buf, + offset: f.content.lf.lr_lpf_line[0], } + line as isize * y_stride + (bx * 4) as isize }; @@ -321,8 +326,8 @@ pub(crate) fn rav1d_cdef_brow( let (top, bot) = top_bot.unwrap_or_else(|| { let top = WithOffset { - data: &f.lf.cdef_line_buf, - offset: f.lf.cdef_line[tf as usize][0], + data: &f.content.lf.cdef_line_buf, + offset: f.content.lf.cdef_line[tf as usize][0], } + have_tt as isize * (sby * 4) as isize * y_stride + (bx * 4) as isize; let bottom = bptrs[0] + (8 * y_stride); @@ -332,7 +337,7 @@ pub(crate) fn rav1d_cdef_brow( if y_pri_lvl != 0 { let adj_y_pri_lvl = adjust_strength(y_pri_lvl, variance); if adj_y_pri_lvl != 0 || y_sec_lvl != 0 { - f.dsp.cdef.fb[0].call::( + f.content.dsp.cdef.fb[0].call::( bptrs[0], &lr_bak[bit as usize][0], top, @@ -346,7 +351,7 @@ pub(crate) fn rav1d_cdef_brow( ); } } else if y_sec_lvl != 0 { - f.dsp.cdef.fb[0].call::( + f.content.dsp.cdef.fb[0].call::( bptrs[0], &lr_bak[bit as usize][0], top, @@ -374,15 +379,15 @@ pub(crate) fn rav1d_cdef_brow( } else if sbrow_start && by == by_start { let top = if resize { WithOffset { - data: &f.lf.cdef_line_buf, - offset: f.lf.cdef_lpf_line[pl], + data: &f.content.lf.cdef_line_buf, + offset: f.content.lf.cdef_lpf_line[pl], } + ((sby - 1) * 4) as isize * uv_stride + (bx * 4 >> ss_hor) as isize } else { let line = sby * (4 << sb128) - 4; WithOffset { - data: &f.lf.lr_line_buf, - offset: f.lf.lr_lpf_line[pl], + data: &f.content.lf.lr_line_buf, + offset: f.content.lf.lr_lpf_line[pl], } + line as isize * uv_stride + (bx * 4 >> ss_hor) as isize }; @@ -390,21 +395,21 @@ pub(crate) fn rav1d_cdef_brow( Some((top, WithOffset::pic(bottom))) } else if !sbrow_start && by + 2 >= by_end { let top = WithOffset { - data: &f.lf.cdef_line_buf, - offset: f.lf.cdef_line[tf as usize][pl], + data: &f.content.lf.cdef_line_buf, + offset: f.content.lf.cdef_line[tf as usize][pl], } + (sby * 8) as isize * uv_stride + (bx * 4 >> ss_hor) as isize; let buf = if resize { WithOffset { - data: &f.lf.cdef_line_buf, - offset: f.lf.cdef_lpf_line[pl], + data: &f.content.lf.cdef_line_buf, + offset: f.content.lf.cdef_lpf_line[pl], } + (sby * 4 + 2) as isize * uv_stride + (bx * 4 >> ss_hor) as isize } else { let line = sby * (4 << sb128) + 4 * sb128 as c_int + 2; WithOffset { - data: &f.lf.lr_line_buf, - offset: f.lf.lr_lpf_line[pl], + data: &f.content.lf.lr_line_buf, + offset: f.content.lf.lr_lpf_line[pl], } + line as isize * uv_stride + (bx * 4 >> ss_hor) as isize }; @@ -424,15 +429,15 @@ pub(crate) fn rav1d_cdef_brow( let (top, bot) = top_bot.unwrap_or_else(|| { let top = WithOffset { - data: &f.lf.cdef_line_buf, - offset: f.lf.cdef_line[tf as usize][pl], + data: &f.content.lf.cdef_line_buf, + offset: f.content.lf.cdef_line[tf as usize][pl], } + have_tt as isize * (sby * 8) as isize * uv_stride + (bx * 4 >> ss_hor) as isize; let bottom = bptrs[pl] + ((8 >> ss_ver) * uv_stride); (top, WithOffset::pic(bottom)) }); - f.dsp.cdef.fb[uv_idx as usize].call::( + f.content.dsp.cdef.fb[uv_idx as usize].call::( bptrs[pl], &lr_bak[bit as usize][pl], top, diff --git a/src/decode.rs b/src/decode.rs index 6695e9798..2c97e82f7 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -68,6 +68,7 @@ use crate::src::internal::Rav1dFrameContext; use crate::src::internal::Rav1dFrameContextFrameThread; use crate::src::internal::Rav1dFrameContextLf; use crate::src::internal::Rav1dFrameData; +use crate::src::internal::Rav1dFrameDataMaybeHeaders; use crate::src::internal::Rav1dState; use crate::src::internal::Rav1dTaskContext; use crate::src::internal::Rav1dTileState; @@ -296,7 +297,7 @@ fn read_tx_tree( if depth < 2 && from > TxfmSize::S4x4 { let cat = 2 * (TxfmSize::S64x64 as c_int - t_dim.max as c_int) - depth; - let a = ((*f.a[t.a].tx.index(bx4 as usize) as u8) < txw) as c_int; + let a = ((*f.content.a[t.a].tx.index(bx4 as usize) as u8) < txw) as c_int; let l = ((*t.l.tx.index(by4 as usize) as u8) < txh) as c_int; is_split = rav1d_msac_decode_bool_adapt( @@ -326,7 +327,7 @@ fn read_tx_tree( y_off * 2 + 0, ); t.b.x += txsw; - if txw >= txh && t.b.x < f.bw { + if txw >= txh && t.b.x < f.content.bw { read_tx_tree( t, f, @@ -340,7 +341,7 @@ fn read_tx_tree( } t.b.x -= txsw; t.b.y += txsh; - if txh >= txw && t.b.y < f.bh { + if txh >= txw && t.b.y < f.content.bh { read_tx_tree( t, f, @@ -352,7 +353,7 @@ fn read_tx_tree( y_off * 2 + 1, ); t.b.x += txsw; - if txw >= txh && t.b.x < f.bw { + if txw >= txh && t.b.x < f.content.bw { read_tx_tree( t, f, @@ -369,7 +370,7 @@ fn read_tx_tree( t.b.y -= txsh; } else { CaseSet::<16, false>::many( - [(&t.l, txh), (&f.a[t.a], txw)], + [(&t.l, txh), (&f.content.a[t.a], txw)], [t_dim.h as usize, t_dim.w as usize], [by4 as usize, bx4 as usize], |case, (dir, val)| { @@ -431,7 +432,7 @@ fn find_matching_ref( ) { let r = &t.rt.r[(t.b.y as usize & 31) + 5 - 1..]; let mut count = 0; - let ts = &f.ts[t.ts]; + let ts = &f.content.ts[t.ts]; let mut have_topleft = have_top && have_left; let mut have_topright = cmp::max(bw4, bh4) < 32 && have_top @@ -443,7 +444,7 @@ fn find_matching_ref( if have_top { let mut i = r[0] + t.b.x as usize; - let r2 = *f.rf.r.index(i); + let r2 = *f.content.rf.r.index(i); if matches(r2) { masks[0] |= 1; count = 1; @@ -462,7 +463,7 @@ fn find_matching_ref( let mut x = aw4; while x < w4 { i += aw4 as usize; - let r2 = *f.rf.r.index(i); + let r2 = *f.content.rf.r.index(i); if matches(r2) { masks[0] |= mask; count += 1; @@ -477,7 +478,7 @@ fn find_matching_ref( } } if have_left { - let get_r2 = |i: usize| *f.rf.r.index(r[i] + t.b.x as usize - 1); + let get_r2 = |i: usize| *f.content.rf.r.index(r[i] + t.b.x as usize - 1); let mut i = 1; let r2 = get_r2(i); @@ -512,14 +513,14 @@ fn find_matching_ref( } } } - if have_topleft && matches(*f.rf.r.index(r[0] + t.b.x as usize - 1)) { + if have_topleft && matches(*f.content.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.index(r[0] + t.b.x as usize + bw4 as usize)) { + if have_topright && matches(*f.content.rf.r.index(r[0] + t.b.x as usize + bw4 as usize)) { masks[0] |= 1 << 32; } } @@ -800,7 +801,7 @@ fn read_vartx_tree( // var-tx tree coding let mut tx_split = [0u16; 2]; let mut max_ytx = dav1d_max_txfm_size_for_bs[bs as usize][0]; - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; let txfm_mode = frame_hdr.txfm_mode; let uvtx; if b.skip == 0 && (frame_hdr.segmentation.lossless[b.seg_id.get()] || max_ytx == TxfmSize::S4x4) @@ -809,7 +810,7 @@ fn read_vartx_tree( max_ytx = uvtx; if txfm_mode == Rav1dTxfmMode::Switchable { CaseSet::<32, false>::many( - [&t.l, &f.a[t.a]], + [&t.l, &f.content.a[t.a]], [bh4 as usize, bw4 as usize], [by4 as usize, bx4 as usize], |case, dir| { @@ -820,7 +821,7 @@ fn read_vartx_tree( } else if txfm_mode != Rav1dTxfmMode::Switchable || b.skip != 0 { if txfm_mode == Rav1dTxfmMode::Switchable { CaseSet::<32, false>::many( - [(&t.l, 1), (&f.a[t.a], 0)], + [(&t.l, 1), (&f.content.a[t.a], 0)], [bh4 as usize, bw4 as usize], [by4 as usize, bx4 as usize], |case, (dir, dir_index)| { @@ -830,7 +831,7 @@ fn read_vartx_tree( }, ); } - uvtx = dav1d_max_txfm_size_for_bs[bs as usize][f.cur.p.layout as usize]; + uvtx = dav1d_max_txfm_size_for_bs[bs as usize][f.content.cur.p.layout as usize]; } else { assert!(bw4 <= 16 || bh4 <= 16 || max_ytx == TxfmSize::S64x64); let ytx = &dav1d_txfm_dimensions[max_ytx as usize]; @@ -854,7 +855,7 @@ fn read_vartx_tree( tx_split[0], tx_split[1], ts_c.msac.rng ); } - uvtx = dav1d_max_txfm_size_for_bs[bs as usize][f.cur.p.layout as usize]; + uvtx = dav1d_max_txfm_size_for_bs[bs as usize][f.content.cur.p.layout as usize]; } assert!(tx_split[0] & !0x33 == 0); let tx_split0 = tx_split[0] as u8; @@ -1147,7 +1148,7 @@ fn decode_b( bp: BlockPartition, intra_edge_flags: EdgeFlags, ) -> Result<(), ()> { - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); + let seq_hdr = &f.seq_hdr; use std::fmt; /// Helper struct for printing a number as a signed hexidecimal value. @@ -1163,35 +1164,36 @@ fn decode_b( let mut b_mem = Av1Block::default(); let b = if t.frame_thread.pass != 0 { &mut *f + .content .frame_thread .b - .index_mut((t.b.y as isize * f.b4_stride + t.b.x as isize) as usize) + .index_mut((t.b.y as isize * f.content.b4_stride + t.b.x as isize) as usize) } else { &mut b_mem }; - let ts = &f.ts[t.ts]; - let ta = &f.a[t.a]; + let ts = &f.content.ts[t.ts]; + let ta = &f.content.a[t.a]; let bd_fn = f.bd_fn(); let b_dim = bs.dimensions(); let bx4 = t.b.x & 31; let by4 = t.b.y & 31; - let ss_ver = (f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + let ss_ver = (f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; let cbx4 = bx4 >> ss_hor; let cby4 = by4 >> ss_ver; let bw4 = b_dim[0] as c_int; let bh4 = b_dim[1] as c_int; - let w4 = cmp::min(bw4, f.bw - t.b.x); - let h4 = cmp::min(bh4, f.bh - t.b.y); + let w4 = cmp::min(bw4, f.content.bw - t.b.x); + let h4 = cmp::min(bh4, f.content.bh - t.b.y); let cbw4 = bw4 + ss_hor >> ss_hor; let cbh4 = bh4 + ss_ver >> ss_ver; let have_left = t.b.x > ts.tiling.col_start; let have_top = t.b.y > ts.tiling.row_start; - let has_chroma = f.cur.p.layout != Rav1dPixelLayout::I400 + let has_chroma = f.content.cur.p.layout != Rav1dPixelLayout::I400 && (bw4 > ss_hor || t.b.x & 1 != 0) && (bh4 > ss_ver || t.b.y & 1 != 0); - let frame_type = f.frame_hdr.as_ref().unwrap().frame_type; + let frame_type = f.frame_hdr.frame_type; let FrameThreadPassState::First(ts_c) = pass else { match &b.ii { @@ -1215,14 +1217,18 @@ fn decode_b( ); if frame_type.is_inter_or_switch() { 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); + let r = &mut *f.content.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.index_mut(r + t.b.x as usize + bw4 as usize - 1); + let block = &mut f + .content + .rf + .r + .index_mut(r + t.b.x as usize + bw4 as usize - 1); block.r#ref.r#ref[0] = 0; block.bs = bs; } @@ -1292,7 +1298,7 @@ fn decode_b( if frame_type.is_inter_or_switch() { 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); + let r = &mut *f.content.rf.r.index_mut(ri..ri + bw4 as usize); for block in r { block.r#ref.r#ref[0] = inter.r#ref[0] + 1; block.mv.mv[0] = inter.nd.one_d.mv[0]; @@ -1300,7 +1306,11 @@ fn decode_b( } 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.index_mut(r + t.b.x as usize + bw4 as usize - 1); + let block = &mut f + .content + .rf + .r + .index_mut(r + t.b.x as usize + bw4 as usize - 1); block.r#ref.r#ref[0] = inter.r#ref[0] + 1; block.mv.mv[0] = inter.nd.one_d.mv[0]; block.bs = bs; @@ -1336,14 +1346,22 @@ fn decode_b( // segment_id (if seg_feature for skip/ref/gmv is enabled) let mut seg_pred = false; - let frame_hdr: &Rav1dFrameHeader = &f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; if frame_hdr.segmentation.enabled != 0 { if frame_hdr.segmentation.update_map == 0 { b.seg_id = f + .content .prev_segmap .as_ref() .map(|prev_segmap| { - get_prev_frame_segid(frame_hdr, t.b, w4, h4, &prev_segmap.inner, f.b4_stride) + get_prev_frame_segid( + frame_hdr, + t.b, + w4, + h4, + &prev_segmap.inner, + f.content.b4_stride, + ) }) .unwrap_or_default(); seg = Some(&frame_hdr.segmentation.seg_data.d[b.seg_id.get()]); @@ -1358,6 +1376,7 @@ fn decode_b( } { // temporal predicted seg_id b.seg_id = f + .content .prev_segmap .as_ref() .map(|prev_segmap| { @@ -1367,7 +1386,7 @@ fn decode_b( w4, h4, &prev_segmap.inner, - f.b4_stride, + f.content.b4_stride, ) }) .unwrap_or_default(); @@ -1376,8 +1395,8 @@ fn decode_b( t.b, have_top, have_left, - &f.cur_segmap.as_ref().unwrap().inner, - f.b4_stride as usize, + &f.content.cur_segmap.as_ref().unwrap().inner, + f.content.b4_stride as usize, ); let diff = rav1d_msac_decode_symbol_adapt8( &mut ts_c.msac, @@ -1450,10 +1469,18 @@ fn decode_b( } { // temporal predicted seg_id b.seg_id = f + .content .prev_segmap .as_ref() .map(|prev_segmap| { - get_prev_frame_segid(frame_hdr, t.b, w4, h4, &prev_segmap.inner, f.b4_stride) + get_prev_frame_segid( + frame_hdr, + t.b, + w4, + h4, + &prev_segmap.inner, + f.content.b4_stride, + ) }) .unwrap_or_default(); } else { @@ -1461,8 +1488,8 @@ fn decode_b( t.b, have_top, have_left, - &f.cur_segmap.as_ref().unwrap().inner, - f.b4_stride as usize, + &f.content.cur_segmap.as_ref().unwrap().inner, + f.content.b4_stride as usize, ); b.seg_id = if b.skip != 0 { pred_seg_id @@ -1497,7 +1524,7 @@ fn decode_b( } else { 0 } as usize; - let cdef_idx = &f.lf.mask[t.lf_mask.unwrap()].cdef_idx; + let cdef_idx = &f.content.lf.mask[t.lf_mask.unwrap()].cdef_idx; let cur_idx = t.cur_sb_cdef_idx + idx; if cdef_idx[cur_idx].get() == -1 { let v = rav1d_msac_decode_bools(&mut ts_c.msac, frame_hdr.cdef.n_bits) as i8; @@ -1563,7 +1590,7 @@ fn decode_b( if frame_hdr.delta.lf.present != 0 { let n_lfs = if frame_hdr.delta.lf.multi != 0 { - if f.cur.p.layout != Rav1dPixelLayout::I400 { + if f.content.cur.p.layout != Rav1dPixelLayout::I400 { 4 } else { 2 @@ -1788,11 +1815,10 @@ fn decode_b( let mut y_mode = y_mode; let mut y_angle = y_angle; - let seq_hdr = f.seq_hdr(); if y_mode == DC_PRED && pal_sz[0] == 0 && cmp::max(b_dim[2], b_dim[3]) <= 3 - && seq_hdr.filter_intra != 0 + && f.seq_hdr.filter_intra != 0 { let is_filter = rav1d_msac_decode_bool_adapt( &mut ts_c.msac, @@ -1824,6 +1850,7 @@ fn decode_b( let len = (bw4 * bh4 * 8) as u32; let pal_idx = frame_thread.pal_idx.get_update(|i| i + len); &mut *f + .content .frame_thread .pal_idx .index_mut((pal_idx as usize.., ..len as usize)) @@ -1856,7 +1883,8 @@ fn decode_b( let len = (cbw4 * cbh4 * 8) as u32; let pal_idx = frame_thread.pal_idx.get_update(|i| i + len); Some( - f.frame_thread + f.content + .frame_thread .pal_idx .index_mut((pal_idx as usize.., ..len as usize)), ) @@ -1882,14 +1910,14 @@ fn decode_b( } } - let frame_hdr = f.frame_hdr(); + let frame_hdr = &f.frame_hdr; let tx = if frame_hdr.segmentation.lossless[b.seg_id.get()] { b.uvtx = TxfmSize::S4x4; b.uvtx } else { let mut tx = dav1d_max_txfm_size_for_bs[bs as usize][0]; - b.uvtx = dav1d_max_txfm_size_for_bs[bs as usize][f.cur.p.layout as usize]; + b.uvtx = dav1d_max_txfm_size_for_bs[bs as usize][f.content.cur.p.layout as usize]; let mut t_dim = &dav1d_txfm_dimensions[tx as usize]; if frame_hdr.txfm_mode == Rav1dTxfmMode::Switchable && t_dim.max > TxfmSize::S4x4 as _ { let tctx = get_tx_ctx(ta, &t.l, t_dim, by4, bx4); @@ -1928,25 +1956,25 @@ fn decode_b( (bd_fn.recon_b_intra)(f, t, Some(ts_c), bs, intra_edge_flags, b, &intra); } - if f.frame_hdr().loopfilter.level_y != [0, 0] { + if f.frame_hdr.loopfilter.level_y != [0, 0] { let lflvl = match ts.lflvl.get() { - TileStateRef::Frame => &f.lf.lvl, + TileStateRef::Frame => &f.content.lf.lvl, TileStateRef::Local => &*ts.lflvlmem.try_read().unwrap(), }; let mut a_uv_guard; let mut l_uv_guard; rav1d_create_lf_mask_intra( - &f.lf.mask[t.lf_mask.unwrap()], - &f.lf.level, - f.b4_stride, + &f.content.lf.mask[t.lf_mask.unwrap()], + &f.content.lf.level, + f.content.b4_stride, &lflvl[b.seg_id.get()], t.b, - f.w4, - f.h4, + f.content.w4, + f.content.h4, bs, tx, b.uvtx, - f.cur.p.layout, + f.content.cur.p.layout, &mut ta.tx_lpf_y.index_mut((bx4 as usize.., ..bw4 as usize)), &mut t.l.tx_lpf_y.index_mut((by4 as usize.., ..bh4 as usize)), if has_chroma { @@ -1965,7 +1993,7 @@ fn decode_b( } else { y_mode }; - let is_inter_or_switch = f.frame_hdr().frame_type.is_inter_or_switch(); + let is_inter_or_switch = f.frame_hdr.frame_type.is_inter_or_switch(); CaseSet::<32, false>::many( [(&t.l, t_dim.lh, 1), (ta, t_dim.lw, 0)], [bh4 as usize, bw4 as usize], @@ -2017,9 +2045,9 @@ fn decode_b( ); } } - let frame_hdr = f.frame_hdr(); + let frame_hdr = &f.frame_hdr; if frame_hdr.frame_type.is_inter_or_switch() || frame_hdr.allow_intrabc { - splat_intraref(c, t, &f.rf, bs, bw4 as usize, bh4 as usize); + splat_intraref(c, t, &f.content.rf, bs, bw4 as usize, bh4 as usize); } } else if frame_hdr.frame_type.is_key_or_intra() { // intra block copy @@ -2028,7 +2056,7 @@ fn decode_b( let mut ctx = 0; rav1d_refmvs_find( &t.rt, - &f.rf, + &f.content.rf, &mut mvstack, &mut n_mvs, &mut ctx, @@ -2173,7 +2201,7 @@ fn decode_b( (bd_fn.recon_b_inter)(f, t, Some(ts_c), bs, b, &inter)?; } - splat_intrabc_mv(c, t, &f.rf, bs, r#ref, bw4 as usize, bh4 as usize); + splat_intrabc_mv(c, t, &f.content.rf, bs, r#ref, bw4 as usize, bh4 as usize); CaseSet::<32, false>::many( [(&t.l, 1), (ta, 0)], @@ -2258,7 +2286,7 @@ fn decode_b( let mut ctx = 0; rav1d_refmvs_find( &t.rt, - &f.rf, + &f.content.rf, &mut mvstack, &mut n_mvs, &mut ctx, @@ -2374,7 +2402,7 @@ fn decode_b( let mut ctx = 0; rav1d_refmvs_find( &t.rt, - &f.rf, + &f.content.rf, &mut mvstack, &mut n_mvs, &mut ctx, @@ -2515,7 +2543,7 @@ fn decode_b( if !is_segwedge { if seq_hdr.jnt_comp != 0 { let [ref0poc, ref1poc] = r#ref.map(|r#ref| { - f.refp[r#ref as usize] + f.content.refp[r#ref as usize] .p .frame_hdr .as_ref() @@ -2524,7 +2552,7 @@ fn decode_b( }); let jnt_ctx = get_jnt_comp_ctx( seq_hdr.order_hint_n_bits, - f.cur.frame_hdr.as_ref().unwrap().frame_offset as c_uint, + f.content.cur.frame_hdr.as_ref().unwrap().frame_offset as c_uint, ref0poc, ref1poc, ta, @@ -2665,7 +2693,7 @@ fn decode_b( let mut ctx = 0; rav1d_refmvs_find( &t.rt, - &f.rf, + &f.content.rf, &mut mvstack, &mut n_mvs, &mut ctx, @@ -2888,7 +2916,7 @@ fn decode_b( r#ref[0], &mut mask, ); - let allow_warp = (f.svc[r#ref[0] as usize][0].scale == 0 + let allow_warp = (f.content.svc[r#ref[0] as usize][0].scale == 0 && !frame_hdr.force_integer_mv && frame_hdr.warp_motion != 0 && mask[0] | mask[1] != 0) as c_int; @@ -2906,7 +2934,8 @@ fn decode_b( .expect("valid variant"); if motion_mode == MotionMode::Warp { has_subpel_filter = false; - t.warpmv = derive_warpmv(&f.rf.r, t, bw4, bh4, &mask, mv1d0, t.warpmv.clone()); + t.warpmv = + derive_warpmv(&f.content.rf.r, t, bw4, bh4, &mask, mv1d0, t.warpmv.clone()); if debug_block_info!(f, t.b) { println!( "[ {} {} {}\n {} {} {} ]\n\ @@ -3060,7 +3089,7 @@ fn decode_b( (bd_fn.recon_b_inter)(f, t, Some(ts_c), bs, b, &inter)?; } - let frame_hdr = f.frame_hdr(); + let frame_hdr = &f.frame_hdr; if frame_hdr.loopfilter.level_y != [0, 0] { let is_globalmv = (inter_mode == if is_comp { GLOBALMV_GLOBALMV } else { GLOBALMV }) as c_int; @@ -3072,15 +3101,15 @@ fn decode_b( uvtx = TxfmSize::S4x4; } let lflvl = match ts.lflvl.get() { - TileStateRef::Frame => &f.lf.lvl, + TileStateRef::Frame => &f.content.lf.lvl, TileStateRef::Local => &*ts.lflvlmem.try_read().unwrap(), }; let mut a_uv_guard; let mut l_uv_guard; rav1d_create_lf_mask_inter( - &f.lf.mask[t.lf_mask.unwrap()], - &f.lf.level, - f.b4_stride, + &f.content.lf.mask[t.lf_mask.unwrap()], + &f.content.lf.level, + f.content.b4_stride, // In C, the inner dimensions (`ref`, `is_gmv`) are offset, // but then cast back to a pointer to the full array, // even though the whole array is not passed. @@ -3090,14 +3119,14 @@ fn decode_b( (r#ref[0] + 1) as usize, is_globalmv == 0, t.b, - f.w4, - f.h4, + f.content.w4, + f.content.h4, b.skip != 0, bs, ytx, &tx_split, uvtx, - f.cur.p.layout, + f.content.cur.p.layout, &mut ta.tx_lpf_y.index_mut((bx4 as usize.., ..bw4 as usize)), &mut t.l.tx_lpf_y.index_mut((by4 as usize.., ..bh4 as usize)), if has_chroma { @@ -3112,9 +3141,9 @@ fn decode_b( // context updates if is_comp { - splat_tworef_mv(c, t, &f.rf, bs, &inter, bw4 as usize, bh4 as usize); + splat_tworef_mv(c, t, &f.content.rf, bs, &inter, bw4 as usize, bh4 as usize); } else { - splat_oneref_mv(c, t, &f.rf, bs, &inter, bw4 as usize, bh4 as usize); + splat_oneref_mv(c, t, &f.content.rf, bs, &inter, bw4 as usize, bh4 as usize); } CaseSet::<32, false>::many( @@ -3152,12 +3181,12 @@ fn decode_b( } // update contexts - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; if frame_hdr.segmentation.enabled != 0 && frame_hdr.segmentation.update_map != 0 { // Need checked casts here because we're using `from_raw_parts_mut` and an overflow would be UB. let [by, bx, bh4, bw4] = [t.b.y, t.b.x, bh4, bw4].map(|it| usize::try_from(it).unwrap()); - let b4_stride = usize::try_from(f.b4_stride).unwrap(); - let cur_segmap = &f.cur_segmap.as_ref().unwrap().inner; + let b4_stride = usize::try_from(f.content.b4_stride).unwrap(); + let cur_segmap = &f.content.cur_segmap.as_ref().unwrap().inner; let offset = by * b4_stride + bx; CaseSet::<32, false>::one((), bw4, 0, |case, ()| { for i in 0..bh4 { @@ -3169,7 +3198,7 @@ fn decode_b( if b.skip == 0 { let mask = !0u32 >> 32 - bw4 << (bx4 & 15); let bx_idx = (bx4 & 16) >> 4; - for noskip_mask in &f.lf.mask[t.lf_mask.unwrap()].noskip_mask[by4 as usize >> 1..] + for noskip_mask in &f.content.lf.mask[t.lf_mask.unwrap()].noskip_mask[by4 as usize >> 1..] [..(bh4 as usize + 1) / 2] { noskip_mask[bx_idx as usize].update(|it| it | mask as u16); @@ -3184,14 +3213,17 @@ fn decode_b( Av1BlockIntraInter::Inter(inter) if t.frame_thread.pass == 1 && frame_hdr.frame_type.is_inter_or_switch() => { - let sby = t.b.y - ts.tiling.row_start >> f.sb_shift; - let mut lowest_px = f.lowest_pixel_mem.index_mut(ts.lowest_pixel + sby as usize); + let sby = t.b.y - ts.tiling.row_start >> f.content.sb_shift; + let mut lowest_px = f + .content + .lowest_pixel_mem + .index_mut(ts.lowest_pixel + sby as usize); // keep track of motion vectors for each reference if inter.comp_type.is_none() { // y if cmp::min(bw4, bh4) > 1 && (inter.inter_mode == GLOBALMV - && f.gmv_warp_allowed[inter.r#ref[0] as usize] != 0 + && f.content.gmv_warp_allowed[inter.r#ref[0] as usize] != 0 || inter.motion_mode == MotionMode::Warp && t.warpmv.r#type > Rav1dWarpedMotionType::Translation) { @@ -3212,15 +3244,15 @@ fn decode_b( bh4, inter.nd.one_d.mv[0].y, 0, - &f.svc[inter.r#ref[0] as usize][1], + &f.content.svc[inter.r#ref[0] as usize][1], ); if inter.motion_mode == MotionMode::Obmc { obmc_lowest_px( - &f.rf.r, + &f.content.rf.r, t, - &f.ts[t.ts], - f.cur.p.layout, - &f.svc, + &f.content.ts[t.ts], + f.content.cur.p.layout, + &f.content.svc, &mut lowest_px, false, b_dim, @@ -3242,13 +3274,16 @@ fn decode_b( .unwrap(); if bw4 == 1 { - is_sub8x8 &= f.rf.r.index(r[1] + t.b.x as usize - 1).r#ref.r#ref[0] > 0; + is_sub8x8 &= + f.content.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.index(r[0] + t.b.x as usize).r#ref.r#ref[0] > 0; + is_sub8x8 &= + f.content.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.index(r[0] + t.b.x as usize - 1).r#ref.r#ref[0] > 0; + is_sub8x8 &= + f.content.rf.r.index(r[0] + t.b.x as usize - 1).r#ref.r#ref[0] > 0; } r @@ -3259,36 +3294,36 @@ fn decode_b( // chroma prediction if is_sub8x8 { if bw4 == 1 && bh4 == ss_ver { - let rr = *f.rf.r.index(r[0] + t.b.x as usize - 1); + let rr = *f.content.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, bh4, rr.mv.mv[0].y, ss_ver, - &f.svc[rr.r#ref.r#ref[0] as usize - 1][1], + &f.content.svc[rr.r#ref.r#ref[0] as usize - 1][1], ); } if bw4 == 1 { - let rr = *f.rf.r.index(r[1] + t.b.x as usize - 1); + let rr = *f.content.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, bh4, rr.mv.mv[0].y, ss_ver, - &f.svc[rr.r#ref.r#ref[0] as usize - 1][1], + &f.content.svc[rr.r#ref.r#ref[0] as usize - 1][1], ); } if bh4 == ss_ver { - let rr = *f.rf.r.index(r[0] + t.b.x as usize); + let rr = *f.content.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, bh4, rr.mv.mv[0].y, ss_ver, - &f.svc[rr.r#ref.r#ref[0] as usize - 1][1], + &f.content.svc[rr.r#ref.r#ref[0] as usize - 1][1], ); } mc_lowest_px( @@ -3297,17 +3332,17 @@ fn decode_b( bh4, inter.nd.one_d.mv[0].y, ss_ver, - &f.svc[inter.r#ref[0] as usize][1], + &f.content.svc[inter.r#ref[0] as usize][1], ); } else if cmp::min(cbw4, cbh4) > 1 && (inter.inter_mode == GLOBALMV - && f.gmv_warp_allowed[inter.r#ref[0] as usize] != 0 + && f.content.gmv_warp_allowed[inter.r#ref[0] as usize] != 0 || inter.motion_mode == MotionMode::Warp && t.warpmv.r#type > Rav1dWarpedMotionType::Translation) { affine_lowest_px_chroma( t, - f.cur.p.layout, + f.content.cur.p.layout, &mut lowest_px[inter.r#ref[0] as usize][1], b_dim, if inter.motion_mode == MotionMode::Warp { @@ -3323,15 +3358,15 @@ fn decode_b( bh4 << (bh4 == ss_ver) as c_int, inter.nd.one_d.mv[0].y, ss_ver, - &f.svc[inter.r#ref[0] as usize][1], + &f.content.svc[inter.r#ref[0] as usize][1], ); if inter.motion_mode == MotionMode::Obmc { obmc_lowest_px( - &f.rf.r, + &f.content.rf.r, t, - &f.ts[t.ts], - f.cur.p.layout, - &f.svc, + &f.content.ts[t.ts], + f.content.cur.p.layout, + &f.content.svc, &mut lowest_px, true, b_dim, @@ -3350,7 +3385,9 @@ fn decode_b( .map(|(r#ref, mv)| (r#ref as usize, mv)) }; for (r#ref, mv) in refmvs() { - if inter.inter_mode == GLOBALMV_GLOBALMV && f.gmv_warp_allowed[r#ref] != 0 { + if inter.inter_mode == GLOBALMV_GLOBALMV + && f.content.gmv_warp_allowed[r#ref] != 0 + { affine_lowest_px_luma( t, &mut lowest_px[r#ref][0], @@ -3364,12 +3401,14 @@ fn decode_b( bh4, mv.y, 0, - &f.svc[r#ref][1], + &f.content.svc[r#ref][1], ); } } for (r#ref, mv) in refmvs() { - if inter.inter_mode == GLOBALMV_GLOBALMV && f.gmv_warp_allowed[r#ref] != 0 { + if inter.inter_mode == GLOBALMV_GLOBALMV + && f.content.gmv_warp_allowed[r#ref] != 0 + { affine_lowest_px_luma( t, &mut lowest_px[r#ref][0], @@ -3383,7 +3422,7 @@ fn decode_b( bh4, mv.y, 0, - &f.svc[r#ref][1], + &f.content.svc[r#ref][1], ); } } @@ -3393,11 +3432,11 @@ fn decode_b( for (r#ref, mv) in refmvs() { if inter.inter_mode == GLOBALMV_GLOBALMV && cmp::min(cbw4, cbh4) > 1 - && f.gmv_warp_allowed[r#ref] != 0 + && f.content.gmv_warp_allowed[r#ref] != 0 { affine_lowest_px_chroma( t, - f.cur.p.layout, + f.content.cur.p.layout, &mut lowest_px[r#ref][1], b_dim, &frame_hdr.gmv[r#ref], @@ -3409,7 +3448,7 @@ fn decode_b( bh4, mv.y, ss_ver, - &f.svc[r#ref][1], + &f.content.svc[r#ref][1], ); } } @@ -3435,12 +3474,12 @@ fn decode_sb( bl: BlockLevel, edge_index: EdgeIndex, ) -> Result<(), ()> { - let ts = &f.ts[t.ts]; + let ts = &f.content.ts[t.ts]; let hsz = 16 >> bl as u8; - let have_h_split = f.bw > t.b.x + hsz; - let have_v_split = f.bh > t.b.y + hsz; + let have_h_split = f.content.bw > t.b.x + hsz; + let have_v_split = f.content.bh > t.b.y + hsz; - let sb128 = f.seq_hdr().sb128 != 0; + let sb128 = f.seq_hdr.sb128 != 0; let intra_edge = &IntraEdges::DEFAULT; if !have_h_split && !have_v_split { @@ -3458,7 +3497,7 @@ fn decode_sb( ); } - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; let bp; let mut bx8 = 0; @@ -3474,7 +3513,7 @@ fn decode_sb( bx8 = (t.b.x & 31) >> 1; by8 = (t.b.y & 31) >> 1; Some(( - get_partition_ctx(&f.a[t.a], &t.l, bl, by8, bx8), + get_partition_ctx(&f.content.a[t.a], &t.l, bl, by8, bx8), &mut **ts_c, )) } @@ -3490,7 +3529,7 @@ fn decode_sb( dav1d_partition_type_count[bl as usize].into(), ) as usize) .expect("valid variant"); - if f.cur.p.layout == Rav1dPixelLayout::I422 + if f.content.cur.p.layout == Rav1dPixelLayout::I422 && matches!( bp, BlockPartition::V @@ -3509,9 +3548,10 @@ fn decode_sb( } } else { let b = f + .content .frame_thread .b - .index((t.b.y as isize * f.b4_stride + t.b.x as isize) as usize); + .index((t.b.y as isize * f.content.b4_stride + t.b.x as isize) as usize); bp = if b.bl == bl { b.bp } else { @@ -3640,7 +3680,7 @@ fn decode_sb( t.b.y += hsz >> 1; decode_b(c, t, f, pass, bl, b[0], bp, EdgeFlags::ALL_LEFT_HAS_BOTTOM)?; t.b.y += hsz >> 1; - if t.b.y < f.bh { + if t.b.y < f.content.bh { decode_b(c, t, f, pass, bl, b[0], bp, node.h[1])?; } t.b.y -= hsz * 3 >> 1; @@ -3654,7 +3694,7 @@ fn decode_sb( t.b.x += hsz >> 1; decode_b(c, t, f, pass, bl, b[0], bp, EdgeFlags::ALL_TOP_HAS_RIGHT)?; t.b.x += hsz >> 1; - if t.b.x < f.bw { + if t.b.x < f.content.bw { decode_b(c, t, f, pass, bl, b[0], bp, node.v[1])?; } t.b.x -= hsz * 3 >> 1; @@ -3683,9 +3723,10 @@ fn decode_sb( } } else { let b = &f + .content .frame_thread .b - .index((t.b.y as isize * f.b4_stride + t.b.x as isize) as usize); + .index((t.b.y as isize * f.content.b4_stride + t.b.x as isize) as usize); is_split = b.bl != bl; } @@ -3720,7 +3761,7 @@ fn decode_sb( if let Some((ctx, ts_c)) = ctx { let pc = &mut ts_c.cdf.m.partition[bl as usize][ctx as usize]; is_split = rav1d_msac_decode_bool(&mut ts_c.msac, gather_left_partition_prob(pc, bl)); - if f.cur.p.layout == Rav1dPixelLayout::I422 && !is_split { + if f.content.cur.p.layout == Rav1dPixelLayout::I422 && !is_split { return Err(()); } if debug_block_info!(f, t.b) { @@ -3741,9 +3782,10 @@ fn decode_sb( } } else { let b = &f + .content .frame_thread .b - .index((t.b.y as isize * f.b4_stride + t.b.x as isize) as usize); + .index((t.b.y as isize * f.content.b4_stride + t.b.x as isize) as usize); is_split = b.bl != bl; } @@ -3778,7 +3820,7 @@ fn decode_sb( && (bp != BlockPartition::Split || bl == BlockLevel::Bl8x8) { CaseSet::<16, false>::many( - [(&f.a[t.a], 0), (&t.l, 1)], + [(&f.content.a[t.a], 0), (&t.l, 1)], [hsz as usize; 2], [bx8 as usize, by8 as usize], |case, (dir, dir_index)| { @@ -4100,36 +4142,38 @@ pub(crate) fn rav1d_decode_tile_sbrow( t: &mut Rav1dTaskContext, f: &Rav1dFrameData, ) -> Result<(), ()> { - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); + let seq_hdr = &f.seq_hdr; let root_bl = if seq_hdr.sb128 != 0 { BlockLevel::Bl128x128 } else { BlockLevel::Bl64x64 }; - let ts = &f.ts[t.ts]; - let sb_step = f.sb_step; + let ts = &f.content.ts[t.ts]; + let sb_step = f.content.sb_step; let tile_row = ts.tiling.row; let tile_col = ts.tiling.col; - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; let col_sb_start = frame_hdr.tiling.col_start_sb[tile_col as usize] as c_int; let col_sb128_start = col_sb_start >> (seq_hdr.sb128 == 0) as c_int; if frame_hdr.frame_type.is_inter_or_switch() || frame_hdr.allow_intrabc { t.rt = rav1d_refmvs_tile_sbrow_init( - &f.rf, + &f.content.rf, ts.tiling.col_start, ts.tiling.col_end, ts.tiling.row_start, ts.tiling.row_end, - t.b.y >> f.sb_shift, + t.b.y >> f.content.sb_shift, ts.tiling.row, t.frame_thread.pass, ); } if frame_hdr.frame_type.is_inter_or_switch() && c.fc.len() > 1 { - let sby = t.b.y - ts.tiling.row_start >> f.sb_shift; - *f.lowest_pixel_mem.index_mut(ts.lowest_pixel + sby as usize) = [[i32::MIN; 2]; 7]; + let sby = t.b.y - ts.tiling.row_start >> f.content.sb_shift; + *f.content + .lowest_pixel_mem + .index_mut(ts.lowest_pixel + sby as usize) = [[i32::MIN; 2]; 7]; } reset_context( @@ -4139,11 +4183,11 @@ pub(crate) fn rav1d_decode_tile_sbrow( ); if t.frame_thread.pass == 2 { let off_2pass = if c.tc.len() > 1 { - f.sb128w * frame_hdr.tiling.rows as c_int + f.content.sb128w * frame_hdr.tiling.rows as c_int } else { 0 }; - t.a = (off_2pass + col_sb128_start + tile_row * f.sb128w) as usize; + t.a = (off_2pass + col_sb128_start + tile_row * f.content.sb128w) as usize; for bx in (ts.tiling.col_start..ts.tiling.col_end).step_by(sb_step as usize) { t.b.x = bx; if c.flush.load(Ordering::Acquire) { @@ -4157,7 +4201,7 @@ pub(crate) fn rav1d_decode_tile_sbrow( root_bl, EdgeIndex::root(), )?; - if t.b.x & 16 != 0 || f.seq_hdr().sb128 != 0 { + if t.b.x & 16 != 0 || f.seq_hdr.sb128 != 0 { t.a += 1; } } @@ -4167,9 +4211,9 @@ pub(crate) fn rav1d_decode_tile_sbrow( if c.tc.len() > 1 && frame_hdr.use_ref_frame_mvs != 0 { c.dsp.refmvs.load_tmvs.call( - &f.rf, - &f.mvs, - &f.ref_mvs, + &f.content.rf, + &f.content.mvs, + &f.content.ref_mvs, ts.tiling.row, ts.tiling.col_start >> 1, ts.tiling.col_end >> 1, @@ -4179,14 +4223,14 @@ pub(crate) fn rav1d_decode_tile_sbrow( } t.pal_sz_uv[1] = Default::default(); let sb128y = t.b.y >> 5; - t.a = (col_sb128_start + tile_row * f.sb128w) as usize; - t.lf_mask = Some((sb128y * f.sb128w + col_sb128_start) as usize); + t.a = (col_sb128_start + tile_row * f.content.sb128w) as usize; + t.lf_mask = Some((sb128y * f.content.sb128w + col_sb128_start) as usize); for bx in (ts.tiling.col_start..ts.tiling.col_end).step_by(sb_step as usize) { t.b.x = bx; if c.flush.load(Ordering::Acquire) { return Err(()); } - let cdef_idx = &f.lf.mask[t.lf_mask.unwrap()].cdef_idx; + let cdef_idx = &f.content.lf.mask[t.lf_mask.unwrap()].cdef_idx; if root_bl == BlockLevel::Bl128x128 { for cdef_idx in cdef_idx { cdef_idx.set(-1); @@ -4197,18 +4241,18 @@ pub(crate) fn rav1d_decode_tile_sbrow( let cdef_idx = &cdef_idx[t.cur_sb_cdef_idx..]; cdef_idx[0].set(-1); } - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; // Restoration filter for p in 0..3 { - if (f.lf.restore_planes.bits() >> p) & 1 == 0 { + if (f.content.lf.restore_planes.bits() >> p) & 1 == 0 { continue; } - let ss_ver = (p != 0 && f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (p != 0 && f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + let ss_ver = (p != 0 && f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (p != 0 && f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; let unit_size_log2 = frame_hdr.restoration.unit_size[(p != 0) as usize]; let y = t.b.y * 4 >> ss_ver; - let h = f.cur.p.h + ss_ver >> ss_ver; + let h = f.content.cur.p.h + ss_ver >> ss_ver; let unit_size = 1 << unit_size_log2; let mask = (unit_size - 1) as c_uint; @@ -4225,7 +4269,7 @@ pub(crate) fn rav1d_decode_tile_sbrow( let frame_type = frame_hdr.restoration.r#type[p as usize]; if frame_hdr.size.width[0] != frame_hdr.size.width[1] { - let w = f.sr_cur.p.p.w + ss_hor >> ss_hor; + let w = f.content.sr_cur.p.p.w + ss_hor >> ss_hor; let n_units = cmp::max(1, w + half_unit >> unit_size_log2); let d = frame_hdr.size.super_res.width_scale_denominator as c_int; @@ -4236,9 +4280,9 @@ pub(crate) fn rav1d_decode_tile_sbrow( for x in x0..cmp::min(x1, n_units) { let px_x = x << unit_size_log2 + ss_hor as u8; - let sb_idx = (t.b.y >> 5) * f.sr_sb128w + (px_x >> 7); + let sb_idx = (t.b.y >> 5) * f.content.sr_sb128w + (px_x >> 7); let unit_idx = ((t.b.y & 16) >> 3) + ((px_x & 64) >> 6); - let mut lr = f.lf.lr_mask[sb_idx as usize].lr[p][unit_idx as usize] + let mut lr = f.content.lf.lr_mask[sb_idx as usize].lr[p][unit_idx as usize] .try_write() .unwrap(); @@ -4249,15 +4293,15 @@ pub(crate) fn rav1d_decode_tile_sbrow( if x as c_uint & mask != 0 { continue; } - let w = f.cur.p.w + ss_hor >> ss_hor; + let w = f.content.cur.p.w + ss_hor >> ss_hor; // Round half up at frame boundaries, // if there's more than one restoration unit. if x != 0 && x + half_unit > w { continue; } - let sb_idx = (t.b.y >> 5) * f.sr_sb128w + (t.b.x >> 5); + let sb_idx = (t.b.y >> 5) * f.content.sr_sb128w + (t.b.x >> 5); let unit_idx = ((t.b.y & 16) >> 3) + ((t.b.x & 16) >> 4); - let mut lr = f.lf.lr_mask[sb_idx as usize].lr[p][unit_idx as usize] + let mut lr = f.content.lf.lr_mask[sb_idx as usize].lr[p][unit_idx as usize] .try_write() .unwrap(); @@ -4268,24 +4312,22 @@ pub(crate) fn rav1d_decode_tile_sbrow( c, t, f, - &mut FrameThreadPassState::First(&mut f.ts[t.ts].context.try_lock().unwrap()), + &mut FrameThreadPassState::First(&mut f.content.ts[t.ts].context.try_lock().unwrap()), root_bl, EdgeIndex::root(), )?; - if t.b.x & 16 != 0 || f.seq_hdr().sb128 != 0 { + if t.b.x & 16 != 0 || f.seq_hdr.sb128 != 0 { t.a += 1; t.lf_mask = t.lf_mask.map(|i| i + 1); } } - if f.seq_hdr().ref_frame_mvs != 0 - && c.tc.len() > 1 - && f.frame_hdr().frame_type.is_inter_or_switch() + if f.seq_hdr.ref_frame_mvs != 0 && c.tc.len() > 1 && f.frame_hdr.frame_type.is_inter_or_switch() { c.dsp.refmvs.save_tmvs.call( &t.rt, - &f.rf, - &f.mvs, + &f.content.rf, + &f.content.mvs, ts.tiling.col_start >> 1, ts.tiling.col_end >> 1, t.b.y >> 1, @@ -4300,20 +4342,20 @@ pub(crate) fn rav1d_decode_tile_sbrow( // backup t->a/l.tx_lpf_y/uv at tile boundaries to use them to "fix" // up the initial value in neighbour tiles when running the loopfilter - let mut align_h = f.bh + 31 & !31; + let mut align_h = f.content.bh + 31 & !31; let start_y = (align_h * tile_col + t.b.y) as usize; let len_y = sb_step as usize; let start_lpf_y = (t.b.y & 16) as usize; - f.lf.tx_lpf_right_edge.copy_from_slice_y( + f.content.lf.tx_lpf_right_edge.copy_from_slice_y( start_y..start_y + len_y, &t.l.tx_lpf_y.index(start_lpf_y..start_lpf_y + len_y), ); - let ss_ver = (f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_ver = (f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; align_h >>= ss_ver; let start_uv = (align_h * tile_col + (t.b.y >> ss_ver)) as usize; let len_uv = (sb_step >> ss_ver) as usize; let lpf_uv_start = ((t.b.y & 16) >> ss_ver) as usize; - f.lf.tx_lpf_right_edge.copy_from_slice_uv( + f.content.lf.tx_lpf_right_edge.copy_from_slice_uv( start_uv..start_uv + len_uv, &t.l.tx_lpf_uv.index(lpf_uv_start..lpf_uv_start + len_uv), ); @@ -4324,8 +4366,8 @@ pub(crate) fn rav1d_decode_tile_sbrow( } if c.strict_std_compliance - && (t.b.y >> f.sb_shift) + 1 - >= f.frame_hdr().tiling.row_start_sb[tile_row as usize + 1].into() + && (t.b.y >> f.content.sb_shift) + 1 + >= f.frame_hdr.tiling.row_start_sb[tile_row as usize + 1].into() { return check_trailing_bits_after_symbol_coder(&ts.context.try_lock().unwrap().msac); } @@ -4335,17 +4377,21 @@ pub(crate) fn rav1d_decode_tile_sbrow( pub(crate) fn rav1d_decode_frame_init(c: &Rav1dContext, fc: &Rav1dFrameContext) -> Rav1dResult { let mut f = fc.data.try_write().unwrap(); let f = &mut *f; + let f = f.assert_has_headers_mut(); // TODO: Fallible allocation - f.lf.start_of_tile_row.resize(f.sbh as usize, 0); + f.content + .lf + .start_of_tile_row + .resize(f.content.sbh as usize, 0); - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; let mut sby = 0; for tile_row in 0..frame_hdr.tiling.rows { - f.lf.start_of_tile_row[sby as usize] = tile_row; + f.content.lf.start_of_tile_row[sby as usize] = tile_row; sby += 1; while sby < frame_hdr.tiling.row_start_sb[(tile_row + 1) as usize] as c_int { - f.lf.start_of_tile_row[sby as usize] = 0; + f.content.lf.start_of_tile_row[sby as usize] = 0; sby += 1; } } @@ -4353,43 +4399,47 @@ pub(crate) fn rav1d_decode_frame_init(c: &Rav1dContext, fc: &Rav1dFrameContext) let n_ts = frame_hdr.tiling.cols as c_int * frame_hdr.tiling.rows as c_int; if c.fc.len() > 1 { // TODO: Fallible allocation - f.frame_thread.tile_start_off.resize(n_ts as usize, 0); + f.content + .frame_thread + .tile_start_off + .resize(n_ts as usize, 0); } // TODO: Fallible allocation - f.ts.resize_with(n_ts as usize, Default::default); + f.content.ts.resize_with(n_ts as usize, Default::default); - let a_sz = f.sb128w + let a_sz = f.content.sb128w * frame_hdr.tiling.rows as c_int * (1 + (c.fc.len() > 1 && c.tc.len() > 1) as c_int); // TODO: Fallible allocation - f.a.resize_with(a_sz as usize, Default::default); + f.content.a.resize_with(a_sz as usize, Default::default); - let num_sb128 = f.sb128w * f.sb128h; - let size_mul = &ss_size_mul[f.cur.p.layout]; - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); + let num_sb128 = f.content.sb128w * f.content.sb128h; + let size_mul = &ss_size_mul[f.content.cur.p.layout]; + let seq_hdr = &f.seq_hdr; let hbd = (seq_hdr.hbd != 0) as c_int; if c.fc.len() > 1 { let mut tile_idx = 0; - let sb_step4 = f.sb_step as u32 * 4; + let sb_step4 = f.content.sb_step as u32 * 4; for tile_row in 0..frame_hdr.tiling.rows { let row_off = frame_hdr.tiling.row_start_sb[tile_row as usize] as u32 * sb_step4 - * f.sb128w as u32 + * f.content.sb128w as u32 * 128; let b_diff = (frame_hdr.tiling.row_start_sb[(tile_row + 1) as usize] as u32 - frame_hdr.tiling.row_start_sb[tile_row as usize] as u32) * sb_step4; for tile_col in 0..frame_hdr.tiling.cols { - f.frame_thread.tile_start_off[tile_idx] = row_off + f.content.frame_thread.tile_start_off[tile_idx] = row_off + b_diff * frame_hdr.tiling.col_start_sb[tile_col as usize] as u32 * sb_step4; tile_idx += 1; } } - let lowest_pixel_mem_sz = frame_hdr.tiling.cols as usize * f.sbh as usize; + let lowest_pixel_mem_sz = frame_hdr.tiling.cols as usize * f.content.sbh as usize; // TODO: Fallible allocation - f.lowest_pixel_mem + f.content + .lowest_pixel_mem .resize(lowest_pixel_mem_sz, Default::default()); let mut lowest_pixel_offset = 0; @@ -4398,161 +4448,175 @@ pub(crate) fn rav1d_decode_frame_init(c: &Rav1dContext, fc: &Rav1dFrameContext) let tile_row_sb_h = frame_hdr.tiling.row_start_sb[tile_row + 1] as usize - frame_hdr.tiling.row_start_sb[tile_row] as usize; for tile_col in 0..frame_hdr.tiling.cols as usize { - f.ts[tile_row_base + tile_col].lowest_pixel = lowest_pixel_offset; + f.content.ts[tile_row_base + tile_col].lowest_pixel = lowest_pixel_offset; lowest_pixel_offset += tile_row_sb_h; } } let cbi_sz = num_sb128 * size_mul[0] as c_int; // TODO: Fallible allocation - f.frame_thread + f.content + .frame_thread .cbi .resize_with(cbi_sz as usize * 32 * 32 / 4, Default::default); let cf_sz = (num_sb128 * size_mul[0] as c_int) << hbd; // TODO: Fallible allocation - f.frame_thread + f.content + .frame_thread .cf .get_mut() .resize(cf_sz as usize * 128 * 128 / 2, 0); if frame_hdr.allow_screen_content_tools { // TODO: Fallible allocation - f.frame_thread + f.content + .frame_thread .pal .resize(num_sb128 as usize * 16 * 16 << hbd); let pal_idx_sz = num_sb128 * size_mul[1] as c_int; // TODO: Fallible allocation - f.frame_thread + f.content + .frame_thread .pal_idx .resize(pal_idx_sz as usize * 128 * 128 / 8, Default::default()); - } else if !f.frame_thread.pal.is_empty() { - let _ = mem::take(&mut f.frame_thread.pal); - let _ = mem::take(&mut f.frame_thread.pal_idx); + } else if !f.content.frame_thread.pal.is_empty() { + let _ = mem::take(&mut f.content.frame_thread.pal); + let _ = mem::take(&mut f.content.frame_thread.pal_idx); } } // update allocation of block contexts for above - let mut y_stride = f.cur.stride[0]; - let mut uv_stride = f.cur.stride[1]; + let mut y_stride = f.content.cur.stride[0]; + let mut uv_stride = f.content.cur.stride[1]; let has_resize = (frame_hdr.size.width[0] != frame_hdr.size.width[1]) as c_int; let need_cdef_lpf_copy = (c.tc.len() > 1 && has_resize != 0) as c_int; let mut alloc_sz: usize = 64; - alloc_sz += (y_stride.unsigned_abs() * 4 * f.sbh as usize) << need_cdef_lpf_copy; - alloc_sz += (uv_stride.unsigned_abs() * 8 * f.sbh as usize) << need_cdef_lpf_copy; + alloc_sz += (y_stride.unsigned_abs() * 4 * f.content.sbh as usize) << need_cdef_lpf_copy; + alloc_sz += (uv_stride.unsigned_abs() * 8 * f.content.sbh as usize) << need_cdef_lpf_copy; // TODO: Fallible allocation. - f.lf.cdef_line_buf.resize(alloc_sz, 0); + f.content.lf.cdef_line_buf.resize(alloc_sz, 0); - let bpc = BPC::from_bitdepth_max(f.bitdepth_max); - let y_stride_px = bpc.pxstride(f.cur.stride[0]); - let uv_stride_px = bpc.pxstride(f.cur.stride[1]); + let bpc = BPC::from_bitdepth_max(f.content.bitdepth_max); + let y_stride_px = bpc.pxstride(f.content.cur.stride[0]); + let uv_stride_px = bpc.pxstride(f.content.cur.stride[1]); let mut offset = bpc.pxstride(32usize); if y_stride < 0 { - f.lf.cdef_line[0][0] = - offset.wrapping_add_signed(-(y_stride_px * (f.sbh as isize * 4 - 1))); - f.lf.cdef_line[1][0] = - offset.wrapping_add_signed(-(y_stride_px * (f.sbh as isize * 4 - 3))); + f.content.lf.cdef_line[0][0] = + offset.wrapping_add_signed(-(y_stride_px * (f.content.sbh as isize * 4 - 1))); + f.content.lf.cdef_line[1][0] = + offset.wrapping_add_signed(-(y_stride_px * (f.content.sbh as isize * 4 - 3))); } else { - f.lf.cdef_line[0][0] = offset.wrapping_add_signed(y_stride_px * 0); - f.lf.cdef_line[1][0] = offset.wrapping_add_signed(y_stride_px * 2); + f.content.lf.cdef_line[0][0] = offset.wrapping_add_signed(y_stride_px * 0); + f.content.lf.cdef_line[1][0] = offset.wrapping_add_signed(y_stride_px * 2); } - offset = offset.wrapping_add_signed(y_stride_px.abs() * f.sbh as isize * 4); + offset = offset.wrapping_add_signed(y_stride_px.abs() * f.content.sbh as isize * 4); if uv_stride < 0 { - f.lf.cdef_line[0][1] = - offset.wrapping_add_signed(-(uv_stride_px * (f.sbh as isize * 8 - 1))); - f.lf.cdef_line[0][2] = - offset.wrapping_add_signed(-(uv_stride_px * (f.sbh as isize * 8 - 3))); - f.lf.cdef_line[1][1] = - offset.wrapping_add_signed(-(uv_stride_px * (f.sbh as isize * 8 - 5))); - f.lf.cdef_line[1][2] = - offset.wrapping_add_signed(-(uv_stride_px * (f.sbh as isize * 8 - 7))); + f.content.lf.cdef_line[0][1] = + offset.wrapping_add_signed(-(uv_stride_px * (f.content.sbh as isize * 8 - 1))); + f.content.lf.cdef_line[0][2] = + offset.wrapping_add_signed(-(uv_stride_px * (f.content.sbh as isize * 8 - 3))); + f.content.lf.cdef_line[1][1] = + offset.wrapping_add_signed(-(uv_stride_px * (f.content.sbh as isize * 8 - 5))); + f.content.lf.cdef_line[1][2] = + offset.wrapping_add_signed(-(uv_stride_px * (f.content.sbh as isize * 8 - 7))); } else { - f.lf.cdef_line[0][1] = offset.wrapping_add_signed(uv_stride_px * 0); - f.lf.cdef_line[0][2] = offset.wrapping_add_signed(uv_stride_px * 2); - f.lf.cdef_line[1][1] = offset.wrapping_add_signed(uv_stride_px * 4); - f.lf.cdef_line[1][2] = offset.wrapping_add_signed(uv_stride_px * 6); + f.content.lf.cdef_line[0][1] = offset.wrapping_add_signed(uv_stride_px * 0); + f.content.lf.cdef_line[0][2] = offset.wrapping_add_signed(uv_stride_px * 2); + f.content.lf.cdef_line[1][1] = offset.wrapping_add_signed(uv_stride_px * 4); + f.content.lf.cdef_line[1][2] = offset.wrapping_add_signed(uv_stride_px * 6); } if need_cdef_lpf_copy != 0 { - offset = offset.wrapping_add_signed(uv_stride_px.abs() * f.sbh as isize * 8); + offset = offset.wrapping_add_signed(uv_stride_px.abs() * f.content.sbh as isize * 8); if y_stride < 0 { - f.lf.cdef_lpf_line[0] = - offset.wrapping_add_signed(-(y_stride_px * (f.sbh as isize * 4 - 1))); + f.content.lf.cdef_lpf_line[0] = + offset.wrapping_add_signed(-(y_stride_px * (f.content.sbh as isize * 4 - 1))); } else { - f.lf.cdef_lpf_line[0] = offset; + f.content.lf.cdef_lpf_line[0] = offset; } - offset = offset.wrapping_add_signed(y_stride_px.abs() * f.sbh as isize * 4); + offset = offset.wrapping_add_signed(y_stride_px.abs() * f.content.sbh as isize * 4); if uv_stride < 0 { - f.lf.cdef_lpf_line[1] = - offset.wrapping_add_signed(-(uv_stride_px * (f.sbh as isize * 4 - 1))); - f.lf.cdef_lpf_line[2] = - offset.wrapping_add_signed(-(uv_stride_px * (f.sbh as isize * 8 - 1))); + f.content.lf.cdef_lpf_line[1] = + offset.wrapping_add_signed(-(uv_stride_px * (f.content.sbh as isize * 4 - 1))); + f.content.lf.cdef_lpf_line[2] = + offset.wrapping_add_signed(-(uv_stride_px * (f.content.sbh as isize * 8 - 1))); } else { - f.lf.cdef_lpf_line[1] = offset; - f.lf.cdef_lpf_line[2] = offset.wrapping_add_signed(uv_stride_px * f.sbh as isize * 4); + f.content.lf.cdef_lpf_line[1] = offset; + f.content.lf.cdef_lpf_line[2] = + offset.wrapping_add_signed(uv_stride_px * f.content.sbh as isize * 4); } } let sb128 = seq_hdr.sb128; let num_lines = if c.tc.len() > 1 { - (f.sbh * 4) << sb128 + (f.content.sbh * 4) << sb128 } else { 12 }; - y_stride = f.sr_cur.p.stride[0]; - uv_stride = f.sr_cur.p.stride[1]; + y_stride = f.content.sr_cur.p.stride[0]; + uv_stride = f.content.sr_cur.p.stride[1]; // lr simd may overread the input, so slightly over-allocate the lpf buffer let mut alloc_sz: usize = 128; alloc_sz += y_stride.unsigned_abs() * num_lines as usize; alloc_sz += uv_stride.unsigned_abs() * num_lines as usize * 2; // TODO: Fallible allocation - f.lf.lr_line_buf.resize(alloc_sz, 0); + f.content.lf.lr_line_buf.resize(alloc_sz, 0); let y_stride_px = bpc.pxstride(y_stride); let uv_stride_px = bpc.pxstride(uv_stride); let mut offset = bpc.pxstride(64usize); if y_stride < 0 { - f.lf.lr_lpf_line[0] = offset.wrapping_add_signed(-(y_stride_px * (num_lines as isize - 1))); + f.content.lf.lr_lpf_line[0] = + offset.wrapping_add_signed(-(y_stride_px * (num_lines as isize - 1))); } else { - f.lf.lr_lpf_line[0] = offset; + f.content.lf.lr_lpf_line[0] = offset; } offset = offset.wrapping_add_signed(y_stride_px.abs() * num_lines as isize); if uv_stride < 0 { - f.lf.lr_lpf_line[1] = + f.content.lf.lr_lpf_line[1] = offset.wrapping_add_signed(-(uv_stride_px * (num_lines as isize * 1 - 1))); - f.lf.lr_lpf_line[2] = + f.content.lf.lr_lpf_line[2] = offset.wrapping_add_signed(-(uv_stride_px * (num_lines as isize * 2 - 1))); } else { - f.lf.lr_lpf_line[1] = offset; - f.lf.lr_lpf_line[2] = offset.wrapping_add_signed(uv_stride_px * num_lines as isize); + f.content.lf.lr_lpf_line[1] = offset; + f.content.lf.lr_lpf_line[2] = offset.wrapping_add_signed(uv_stride_px * num_lines as isize); } // update allocation for loopfilter masks - f.lf.mask.clear(); + f.content.lf.mask.clear(); // TODO: Fallible allocation. - f.lf.mask.resize_with(num_sb128 as usize, Default::default); + f.content + .lf + .mask + .resize_with(num_sb128 as usize, Default::default); // over-allocate by 3 bytes since some of the SIMD implementations // index this from the level type and can thus over-read by up to 3 bytes. - f.lf.level + f.content + .lf + .level .resize_with(4 * num_sb128 as usize * 32 * 32 + 3, Default::default); // TODO: Fallible allocation if c.fc.len() > 1 { // TODO: Fallible allocation - f.frame_thread + f.content + .frame_thread .b .resize_with(num_sb128 as usize * 32 * 32, Default::default); } - f.sr_sb128w = f.sr_cur.p.p.w + 127 >> 7; - let lr_mask_sz = f.sr_sb128w * f.sb128h; + f.content.sr_sb128w = f.content.sr_cur.p.p.w + 127 >> 7; + let lr_mask_sz = f.content.sr_sb128w * f.content.sb128h; // TODO: Fallible allocation - f.lf.lr_mask + f.content + .lf + .lr_mask .resize_with(lr_mask_sz as usize, Default::default); - f.lf.restore_planes = LrRestorePlanes::from_bits_truncate( + f.content.lf.restore_planes = LrRestorePlanes::from_bits_truncate( frame_hdr .restoration .r#type @@ -4561,51 +4625,53 @@ pub(crate) fn rav1d_decode_frame_init(c: &Rav1dContext, fc: &Rav1dFrameContext) .map(|(i, &r#type)| ((r#type != Rav1dRestorationType::None) as u8) << i) .sum::(), ); - if frame_hdr.loopfilter.sharpness != f.lf.last_sharpness { - rav1d_calc_eih(&mut f.lf.lim_lut.0, frame_hdr.loopfilter.sharpness); - f.lf.last_sharpness = frame_hdr.loopfilter.sharpness; + if frame_hdr.loopfilter.sharpness != f.content.lf.last_sharpness { + rav1d_calc_eih(&mut f.content.lf.lim_lut.0, frame_hdr.loopfilter.sharpness); + f.content.lf.last_sharpness = frame_hdr.loopfilter.sharpness; } - rav1d_calc_lf_values(&mut f.lf.lvl, &frame_hdr, &[0, 0, 0, 0]); + rav1d_calc_lf_values(&mut f.content.lf.lvl, &frame_hdr, &[0, 0, 0, 0]); - let ipred_edge_sz = f.sbh * f.sb128w << hbd; + let ipred_edge_sz = f.content.sbh * f.content.sb128w << hbd; // TODO: Fallible allocation - f.ipred_edge.resize(ipred_edge_sz as usize * 128 * 3, 0); - f.ipred_edge_off = bpc.pxstride(ipred_edge_sz as usize * 128); + f.content + .ipred_edge + .resize(ipred_edge_sz as usize * 128 * 3, 0); + f.content.ipred_edge_off = bpc.pxstride(ipred_edge_sz as usize * 128); - let re_sz = f.sb128h as usize * frame_hdr.tiling.cols as usize; + let re_sz = f.content.sb128h as usize * frame_hdr.tiling.cols as usize; // TODO: Fallible allocation - f.lf.tx_lpf_right_edge.resize(re_sz, 0); + f.content.lf.tx_lpf_right_edge.resize(re_sz, 0); // init ref mvs if frame_hdr.frame_type.is_inter_or_switch() || frame_hdr.allow_intrabc { rav1d_refmvs_init_frame( - &mut f.rf, + &mut f.content.rf, seq_hdr, frame_hdr, - &f.refpoc, - &f.refrefpoc, - &f.ref_mvs, + &f.content.refpoc, + &f.content.refrefpoc, + &f.content.ref_mvs, c.tc.len() as u32, c.fc.len() as u32, )?; } // setup dequant tables - init_quant_tables(&seq_hdr, &frame_hdr, frame_hdr.quant.yac, &f.dq); + init_quant_tables(&seq_hdr, &frame_hdr, frame_hdr.quant.yac, &f.content.dq); if frame_hdr.quant.qm != 0 { for i in 0..TxfmSize::COUNT { - f.qm[i][0] = dav1d_qm_tbl[frame_hdr.quant.qm_y as usize][0][i]; - f.qm[i][1] = dav1d_qm_tbl[frame_hdr.quant.qm_u as usize][1][i]; - f.qm[i][2] = dav1d_qm_tbl[frame_hdr.quant.qm_v as usize][1][i]; + f.content.qm[i][0] = dav1d_qm_tbl[frame_hdr.quant.qm_y as usize][0][i]; + f.content.qm[i][1] = dav1d_qm_tbl[frame_hdr.quant.qm_u as usize][1][i]; + f.content.qm[i][2] = dav1d_qm_tbl[frame_hdr.quant.qm_v as usize][1][i]; } } else { - f.qm = Default::default(); + f.content.qm = Default::default(); } // setup jnt_comp weights if frame_hdr.switchable_comp_refs != 0 { let ref_pocs: [_; 7] = - array::from_fn(|i| f.refp[i].p.frame_hdr.as_ref().unwrap().frame_offset); + array::from_fn(|i| f.content.refp[i].p.frame_hdr.as_ref().unwrap().frame_offset); for i in 0..ref_pocs.len() { for j in i + 1..ref_pocs.len() { let d = [j, i].map(|ij| { @@ -4613,7 +4679,7 @@ pub(crate) fn rav1d_decode_frame_init(c: &Rav1dContext, fc: &Rav1dFrameContext) (get_poc_diff( seq_hdr.order_hint_n_bits, ref_pocs[ij] as c_int, - f.cur.frame_hdr.as_ref().unwrap().frame_offset as c_int, + f.content.cur.frame_hdr.as_ref().unwrap().frame_offset as c_int, )) .unsigned_abs(), 31, @@ -4633,7 +4699,7 @@ pub(crate) fn rav1d_decode_frame_init(c: &Rav1dContext, fc: &Rav1dFrameContext) }) .unwrap_or(quant_dist_weight.len()); - f.jnt_weights[i][j] = quant_dist_lookup_table[k][order as usize]; + f.content.jnt_weights[i][j] = quant_dist_lookup_table[k][order as usize]; } } } @@ -4647,10 +4713,10 @@ pub(crate) fn rav1d_decode_frame_init_cdf( f: &mut Rav1dFrameData, in_cdf: &CdfThreadContext, ) -> Rav1dResult { - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; if frame_hdr.refresh_context != 0 { - *f.out_cdf.cdf_write() = rav1d_cdf_thread_copy(in_cdf); + *f.content.out_cdf.cdf_write() = rav1d_cdf_thread_copy(in_cdf); } let uses_2pass = c.fc.len() > 1; @@ -4660,21 +4726,21 @@ pub(crate) fn rav1d_decode_frame_init_cdf( let n_bytes = tiling.n_bytes.try_into().unwrap(); let rows: usize = tiling.rows.try_into().unwrap(); let cols = tiling.cols.try_into().unwrap(); - let sb128w: usize = f.sb128w.try_into().unwrap(); + let sb128w: usize = f.content.sb128w.try_into().unwrap(); // parse individual tiles per tile group let mut tile_row = 0; let mut tile_col = 0; fc.task_thread.update_set.set(false); - for tile in &f.tiles { + for tile in &f.content.tiles { let start = tile.hdr.start.try_into().unwrap(); let end: usize = tile.hdr.end.try_into().unwrap(); let mut data = tile.data.data.clone().unwrap(); for (j, (ts, tile_start_off)) in iter::zip( - &mut f.ts[..end + 1], + &mut f.content.ts[..end + 1], if uses_2pass { - &f.frame_thread.tile_start_off[..end + 1] + &f.content.frame_thread.tile_start_off[..end + 1] } else { &[] } @@ -4709,17 +4775,17 @@ pub(crate) fn rav1d_decode_frame_init_cdf( setup_tile( c, ts, - &***f.seq_hdr.as_ref().unwrap(), + &f.seq_hdr, frame_hdr, - f.bitdepth_max, - f.sb_shift, - &f.cur, - f.bw, - f.bh, - &f.frame_thread, - f.sr_sb128w, - f.sb128w, - &mut f.lf, + f.content.bitdepth_max, + f.content.sb_shift, + &f.content.cur, + f.content.bw, + f.content.bh, + &f.content.frame_thread, + f.content.sr_sb128w, + f.content.sb128w, + &mut f.content.lf, in_cdf, cur_data, tile_row, @@ -4740,7 +4806,7 @@ pub(crate) fn rav1d_decode_frame_init_cdf( } if c.tc.len() > 1 { - for (n, ctx) in f.a[..sb128w * rows * (1 + uses_2pass as usize)] + for (n, ctx) in f.content.a[..sb128w * rows * (1 + uses_2pass as usize)] .iter_mut() .enumerate() { @@ -4767,9 +4833,9 @@ fn rav1d_decode_frame_main(c: &Rav1dContext, f: &mut Rav1dFrameData) -> Rav1dRes }; let mut t = t.lock(); - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; - for ctx in &mut f.a[..f.sb128w as usize * frame_hdr.tiling.rows as usize] { + for ctx in &mut f.content.a[..f.content.sb128w as usize * frame_hdr.tiling.rows as usize] { reset_context(ctx, frame_hdr.frame_type.is_key_or_intra(), 0); } @@ -4783,21 +4849,21 @@ fn rav1d_decode_frame_main(c: &Rav1dContext, f: &mut Rav1dFrameData) -> Rav1dRes // Needed until #[feature(array_windows)] stabilizes; it should hopefully optimize out. let [sbh_start, sbh_end] = <[u16; 2]>::try_from(sbh_start_end).unwrap(); - let sbh_end = cmp::min(sbh_end.into(), f.sbh); + let sbh_end = cmp::min(sbh_end.into(), f.content.sbh); for sby in sbh_start.into()..sbh_end { - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let seq_hdr = &f.seq_hdr; + let frame_hdr = &f.frame_hdr; t.b.y = sby << 4 + seq_hdr.sb128; - let by_end = t.b.y + f.sb_step >> 1; + let by_end = t.b.y + f.content.sb_step >> 1; if frame_hdr.use_ref_frame_mvs != 0 { c.dsp.refmvs.load_tmvs.call( - &f.rf, - &f.mvs, - &f.ref_mvs, + &f.content.rf, + &f.content.mvs, + &f.content.ref_mvs, tile_row as c_int, 0, - f.bw >> 1, + f.content.bw >> 1, t.b.y >> 1, by_end, ); @@ -4806,11 +4872,16 @@ fn rav1d_decode_frame_main(c: &Rav1dContext, f: &mut Rav1dFrameData) -> Rav1dRes t.ts = tile_row * cols + col; rav1d_decode_tile_sbrow(c, &mut t, f).map_err(|()| EINVAL)?; } - if f.frame_hdr().frame_type.is_inter_or_switch() { - c.dsp - .refmvs - .save_tmvs - .call(&t.rt, &f.rf, &f.mvs, 0, f.bw >> 1, t.b.y >> 1, by_end); + if f.frame_hdr.frame_type.is_inter_or_switch() { + c.dsp.refmvs.save_tmvs.call( + &t.rt, + &f.content.rf, + &f.content.mvs, + 0, + f.content.bw >> 1, + t.b.y >> 1, + by_end, + ); } // loopfilter + cdef + restoration @@ -4830,48 +4901,48 @@ pub(crate) fn rav1d_decode_frame_exit( // We use a blocking lock here because we have rare contention with other // threads. let mut f = fc.data.write(); - if f.sr_cur.p.data.is_some() { + if f.content.sr_cur.p.data.is_some() { task_thread.error.store(0, Ordering::Relaxed); } - let cf = f.frame_thread.cf.get_mut(); + let cf = f.content.frame_thread.cf.get_mut(); if c.fc.len() > 1 && retval.is_err() { cf.fill_with(Default::default); } if retval.is_ok() && c.fc.len() > 1 && c.strict_std_compliance { - if f.refp.iter().any(|rf| { + if f.content.refp.iter().any(|rf| { rf.p.frame_hdr.is_some() && rf.progress.as_ref().unwrap()[1].load(Ordering::SeqCst) == FRAME_ERROR }) { retval = Err(EINVAL); task_thread.error.store(1, Ordering::SeqCst); - f.sr_cur.progress.as_mut().unwrap()[1].store(FRAME_ERROR, Ordering::SeqCst); + f.content.sr_cur.progress.as_mut().unwrap()[1].store(FRAME_ERROR, Ordering::SeqCst); } } - let _ = mem::take(&mut f.refp); - let _ = mem::take(&mut f.ref_mvs); - let _ = mem::take(&mut f.cur); - let _ = mem::take(&mut f.sr_cur); + let _ = mem::take(&mut f.content.refp); + let _ = mem::take(&mut f.content.ref_mvs); + let _ = mem::take(&mut f.content.cur); + let _ = mem::take(&mut f.content.sr_cur); let _ = mem::take(&mut *fc.in_cdf.try_write().unwrap()); if let Some(frame_hdr) = &f.frame_hdr { if frame_hdr.refresh_context != 0 { - if let Some(progress) = f.out_cdf.progress() { + if let Some(progress) = f.content.out_cdf.progress() { progress.store( if retval.is_ok() { 1 } else { TILE_ERROR as u32 }, Ordering::SeqCst, ); } - let _ = mem::take(&mut f.out_cdf); + let _ = mem::take(&mut f.content.out_cdf); } } - let _ = mem::take(&mut f.cur_segmap); - let _ = mem::take(&mut f.prev_segmap); - let _ = mem::take(&mut f.mvs); + let _ = mem::take(&mut f.content.cur_segmap); + let _ = mem::take(&mut f.content.prev_segmap); + let _ = mem::take(&mut f.content.mvs); let _ = mem::take(&mut f.seq_hdr); let _ = mem::take(&mut f.frame_hdr); - f.tiles.clear(); + f.content.tiles.clear(); task_thread.finished.store(true, Ordering::SeqCst); *task_thread.retval.try_lock().unwrap() = retval.err(); retval @@ -4884,7 +4955,8 @@ pub(crate) fn rav1d_decode_frame(c: &Rav1dContext, fc: &Rav1dFrameContext) -> Ra let mut res = rav1d_decode_frame_init(c, fc); { // scope ensures f is dropped before rav1d_decode_frame_exit is called - let mut f = fc.data.try_write().unwrap(); + let mut f_guard = fc.data.try_write().unwrap(); + let mut f = f_guard.assert_has_headers_mut(); if res.is_ok() { res = rav1d_decode_frame_init_cdf(c, fc, &mut f, &fc.in_cdf()); } @@ -4892,7 +4964,7 @@ pub(crate) fn rav1d_decode_frame(c: &Rav1dContext, fc: &Rav1dFrameContext) -> Ra if res.is_ok() { if c.tc.len() > 1 { res = rav1d_task_create_tile_sbrow(fc, &f, 0, 1); - drop(f); // release the frame data before waiting for the other threads + drop(f_guard); // release the frame data before waiting for the other threads let mut task_thread_lock = (*fc.task_thread.ttd).lock.lock(); (*fc.task_thread.ttd).cond.notify_one(); if res.is_ok() { @@ -4905,14 +4977,15 @@ pub(crate) fn rav1d_decode_frame(c: &Rav1dContext, fc: &Rav1dFrameContext) -> Ra drop(task_thread_lock); res = fc.task_thread.retval.try_lock().unwrap().err_or(()); } else { - res = rav1d_decode_frame_main(c, &mut f); - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); - if res.is_ok() && frame_hdr.refresh_context != 0 && fc.task_thread.update_set.get() + res = rav1d_decode_frame_main(c, f); + if res.is_ok() + && f.frame_hdr.refresh_context != 0 + && fc.task_thread.update_set.get() { rav1d_cdf_thread_update( - frame_hdr, - &mut f.out_cdf.cdf_write(), - &f.ts[frame_hdr.tiling.update as usize] + &f.frame_hdr, + &mut f.content.out_cdf.cdf_write(), + &f.content.ts[f.frame_hdr.tiling.update as usize] .context .try_lock() .unwrap() @@ -4980,53 +5053,49 @@ pub fn rav1d_submit_frame(c: &Rav1dContext, state: &mut Rav1dState) -> Rav1dResu (&c.fc[0], &mut state.out, None) }; - let mut f = fc.data.try_write().unwrap(); - f.seq_hdr = state.seq_hdr.clone(); - f.frame_hdr = mem::take(&mut state.frame_hdr); - let seq_hdr = f.seq_hdr.clone().unwrap(); + let mut f_guard = fc.data.try_write().unwrap(); + f_guard.seq_hdr = state.seq_hdr.clone(); + f_guard.frame_hdr = mem::take(&mut state.frame_hdr); - fn on_error( + let f = f_guard.assert_has_headers_mut(); + + fn on_error<'a>( fc: &Rav1dFrameContext, - f: &mut Rav1dFrameData, + f: impl Into<&'a mut Rav1dFrameDataMaybeHeaders>, out: &mut Rav1dThreadPicture, cached_error_props: &mut Rav1dDataProps, m: &Rav1dDataProps, ) { + let f = f.into(); fc.task_thread.error.store(1, Ordering::Relaxed); let _ = mem::take(&mut *fc.in_cdf.try_write().unwrap()); if f.frame_hdr.as_ref().unwrap().refresh_context != 0 { - let _ = mem::take(&mut f.out_cdf); + let _ = mem::take(&mut f.content.out_cdf); } for i in 0..7 { - if f.refp[i].p.frame_hdr.is_some() { - let _ = mem::take(&mut f.refp[i]); + if f.content.refp[i].p.frame_hdr.is_some() { + let _ = mem::take(&mut f.content.refp[i]); } - let _ = mem::take(&mut f.ref_mvs[i]); + let _ = mem::take(&mut f.content.ref_mvs[i]); } let _ = mem::take(out); - let _ = mem::take(&mut f.cur); - let _ = mem::take(&mut f.sr_cur); - let _ = mem::take(&mut f.mvs); + let _ = mem::take(&mut f.content.cur); + let _ = mem::take(&mut f.content.sr_cur); + let _ = mem::take(&mut f.content.mvs); let _ = mem::take(&mut f.seq_hdr); let _ = mem::take(&mut f.frame_hdr); *cached_error_props = m.clone(); - f.tiles.clear(); + f.content.tiles.clear(); fc.task_thread.finished.store(true, Ordering::SeqCst); } - let bpc = 8 + 2 * seq_hdr.hbd; + let bpc = 8 + 2 * f.seq_hdr.hbd; match Rav1dBitDepthDSPContext::get(bpc) { - Some(dsp) => f.dsp = dsp, + Some(dsp) => f.content.dsp = dsp, None => { writeln!(c.logger, "Compiled without support for {bpc}-bit decoding",); - on_error( - fc, - &mut f, - out, - &mut state.cached_error_props, - &state.in_0.m, - ); + on_error(fc, f, out, &mut state.cached_error_props, &state.in_0.m); return Err(ENOPROTOOPT); } }; @@ -5036,44 +5105,31 @@ pub fn rav1d_submit_frame(c: &Rav1dContext, state: &mut Rav1dState) -> Rav1dResu } let mut ref_coded_width = <[i32; 7]>::default(); - let frame_hdr = f.frame_hdr.as_ref().unwrap().clone(); - if frame_hdr.frame_type.is_inter_or_switch() { - if frame_hdr.primary_ref_frame != RAV1D_PRIMARY_REF_NONE { - let pri_ref = frame_hdr.refidx[frame_hdr.primary_ref_frame as usize] as usize; + if f.frame_hdr.frame_type.is_inter_or_switch() { + if f.frame_hdr.primary_ref_frame != RAV1D_PRIMARY_REF_NONE { + let pri_ref = f.frame_hdr.refidx[f.frame_hdr.primary_ref_frame as usize] as usize; if state.refs[pri_ref].p.p.data.is_none() { - on_error( - fc, - &mut f, - out, - &mut state.cached_error_props, - &state.in_0.m, - ); + on_error(fc, f, out, &mut state.cached_error_props, &state.in_0.m); return Err(EINVAL); } } for i in 0..7 { - let refidx = frame_hdr.refidx[i] as usize; + let refidx = f.frame_hdr.refidx[i] as usize; if state.refs[refidx].p.p.data.is_none() - || (frame_hdr.size.width[0] * 2) < state.refs[refidx].p.p.p.w - || (frame_hdr.size.height * 2) < state.refs[refidx].p.p.p.h - || frame_hdr.size.width[0] > state.refs[refidx].p.p.p.w * 16 - || frame_hdr.size.height > state.refs[refidx].p.p.p.h * 16 - || seq_hdr.layout != state.refs[refidx].p.p.p.layout + || (f.frame_hdr.size.width[0] * 2) < state.refs[refidx].p.p.p.w + || (f.frame_hdr.size.height * 2) < state.refs[refidx].p.p.p.h + || f.frame_hdr.size.width[0] > state.refs[refidx].p.p.p.w * 16 + || f.frame_hdr.size.height > state.refs[refidx].p.p.p.h * 16 + || f.seq_hdr.layout != state.refs[refidx].p.p.p.layout || bpc != state.refs[refidx].p.p.p.bpc { for j in 0..i { - let _ = mem::take(&mut f.refp[j]); + let _ = mem::take(&mut f.content.refp[j]); } - on_error( - fc, - &mut f, - out, - &mut state.cached_error_props, - &state.in_0.m, - ); + on_error(fc, f, out, &mut state.cached_error_props, &state.in_0.m); return Err(EINVAL); } - f.refp[i] = state.refs[refidx].p.clone(); + f.content.refp[i] = state.refs[refidx].p.clone(); ref_coded_width[i] = state.refs[refidx] .p .p @@ -5082,56 +5138,53 @@ pub fn rav1d_submit_frame(c: &Rav1dContext, state: &mut Rav1dState) -> Rav1dResu .unwrap() .size .width[0]; - if frame_hdr.size.width[0] != state.refs[refidx].p.p.p.w - || frame_hdr.size.height != state.refs[refidx].p.p.p.h + if f.frame_hdr.size.width[0] != state.refs[refidx].p.p.p.w + || f.frame_hdr.size.height != state.refs[refidx].p.p.p.h { - f.svc[i][0].scale = scale_fac(state.refs[refidx].p.p.p.w, frame_hdr.size.width[0]); - f.svc[i][1].scale = scale_fac(state.refs[refidx].p.p.p.h, frame_hdr.size.height); - f.svc[i][0].step = f.svc[i][0].scale + 8 >> 4; - f.svc[i][1].step = f.svc[i][1].scale + 8 >> 4; + f.content.svc[i][0].scale = + scale_fac(state.refs[refidx].p.p.p.w, f.frame_hdr.size.width[0]); + f.content.svc[i][1].scale = + scale_fac(state.refs[refidx].p.p.p.h, f.frame_hdr.size.height); + f.content.svc[i][0].step = f.content.svc[i][0].scale + 8 >> 4; + f.content.svc[i][1].step = f.content.svc[i][1].scale + 8 >> 4; } else { - f.svc[i][1].scale = 0; - f.svc[i][0].scale = f.svc[i][1].scale; + f.content.svc[i][1].scale = 0; + f.content.svc[i][0].scale = f.content.svc[i][1].scale; } - f.gmv_warp_allowed[i] = (frame_hdr.gmv[i].r#type > Rav1dWarpedMotionType::Translation - && !frame_hdr.force_integer_mv - && !rav1d_get_shear_params(&frame_hdr.gmv[i]) - && f.svc[i][0].scale == 0) as u8; + f.content.gmv_warp_allowed[i] = + (f.frame_hdr.gmv[i].r#type > Rav1dWarpedMotionType::Translation + && !f.frame_hdr.force_integer_mv + && !rav1d_get_shear_params(&f.frame_hdr.gmv[i]) + && f.content.svc[i][0].scale == 0) as u8; } } // setup entropy - if frame_hdr.primary_ref_frame == RAV1D_PRIMARY_REF_NONE { - *fc.in_cdf.try_write().unwrap() = rav1d_cdf_thread_init_static(frame_hdr.quant.yac); + if f.frame_hdr.primary_ref_frame == RAV1D_PRIMARY_REF_NONE { + *fc.in_cdf.try_write().unwrap() = rav1d_cdf_thread_init_static(f.frame_hdr.quant.yac); } else { - let pri_ref = frame_hdr.refidx[frame_hdr.primary_ref_frame as usize] as usize; + let pri_ref = f.frame_hdr.refidx[f.frame_hdr.primary_ref_frame as usize] as usize; *fc.in_cdf.try_write().unwrap() = state.cdf[pri_ref].clone(); } - if frame_hdr.refresh_context != 0 { + if f.frame_hdr.refresh_context != 0 { let res = rav1d_cdf_thread_alloc(c.fc.len() > 1); match res { Err(e) => { - on_error( - fc, - &mut f, - out, - &mut state.cached_error_props, - &state.in_0.m, - ); + on_error(fc, f, out, &mut state.cached_error_props, &state.in_0.m); return Err(e); } Ok(res) => { - f.out_cdf = res; + f.content.out_cdf = res; } } } // FIXME qsort so tiles are in order (for frame threading) - f.tiles.clear(); - mem::swap(&mut f.tiles, &mut state.tiles); + f.content.tiles.clear(); + mem::swap(&mut f.content.tiles, &mut state.tiles); fc.task_thread .finished - .store(f.tiles.is_empty(), Ordering::SeqCst); + .store(f.content.tiles.is_empty(), Ordering::SeqCst); // allocate frame @@ -5147,134 +5200,134 @@ pub fn rav1d_submit_frame(c: &Rav1dContext, state: &mut Rav1dState) -> Rav1dResu c.output_invisible_frames, state.max_spatial_id, &mut state.frame_flags, - &mut f, + f, bpc, itut_t35, ); if res.is_err() { - on_error( - fc, - &mut f, - out, - &mut state.cached_error_props, - &state.in_0.m, - ); + on_error(fc, f, out, &mut state.cached_error_props, &state.in_0.m); return res; } - let seq_hdr = f.seq_hdr.as_ref().unwrap().clone(); - let frame_hdr = f.frame_hdr.as_ref().unwrap().clone(); - - if frame_hdr.size.width[0] != frame_hdr.size.width[1] { + if f.frame_hdr.size.width[0] != f.frame_hdr.size.width[1] { // Re-borrow to allow independent borrows of fields let f = &mut *f; - let res = - rav1d_picture_alloc_copy(&c.logger, &mut f.cur, frame_hdr.size.width[0], &f.sr_cur.p); + let res = rav1d_picture_alloc_copy( + &c.logger, + &mut f.content.cur, + f.frame_hdr.size.width[0], + &f.content.sr_cur.p, + ); if res.is_err() { on_error(fc, f, out, &mut state.cached_error_props, &state.in_0.m); return res; } } else { - f.cur = f.sr_cur.p.clone(); + f.content.cur = f.content.sr_cur.p.clone(); } - if frame_hdr.size.width[0] != frame_hdr.size.width[1] { - f.resize_step[0] = scale_fac(f.cur.p.w, f.sr_cur.p.p.w); - let ss_hor = (f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; - let in_cw = f.cur.p.w + ss_hor >> ss_hor; - let out_cw = f.sr_cur.p.p.w + ss_hor >> ss_hor; - f.resize_step[1] = scale_fac(in_cw, out_cw); - f.resize_start[0] = get_upscale_x0(f.cur.p.w, f.sr_cur.p.p.w, f.resize_step[0]); - f.resize_start[1] = get_upscale_x0(in_cw, out_cw, f.resize_step[1]); + if f.frame_hdr.size.width[0] != f.frame_hdr.size.width[1] { + f.content.resize_step[0] = scale_fac(f.content.cur.p.w, f.content.sr_cur.p.p.w); + let ss_hor = (f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + let in_cw = f.content.cur.p.w + ss_hor >> ss_hor; + let out_cw = f.content.sr_cur.p.p.w + ss_hor >> ss_hor; + f.content.resize_step[1] = scale_fac(in_cw, out_cw); + f.content.resize_start[0] = get_upscale_x0( + f.content.cur.p.w, + f.content.sr_cur.p.p.w, + f.content.resize_step[0], + ); + f.content.resize_start[1] = get_upscale_x0(in_cw, out_cw, f.content.resize_step[1]); } // move f->cur into output queue if c.fc.len() == 1 { - if frame_hdr.show_frame != 0 || c.output_invisible_frames { - *out = f.sr_cur.clone(); - state.event_flags |= f.sr_cur.flags.into(); + if f.frame_hdr.show_frame != 0 || c.output_invisible_frames { + *out = f.content.sr_cur.clone(); + state.event_flags |= f.content.sr_cur.flags.into(); } } else { - *out = f.sr_cur.clone(); + *out = f.content.sr_cur.clone(); } - f.w4 = frame_hdr.size.width[0] + 3 >> 2; - f.h4 = frame_hdr.size.height + 3 >> 2; - f.bw = (frame_hdr.size.width[0] + 7 >> 3) << 1; - f.bh = (frame_hdr.size.height + 7 >> 3) << 1; - f.sb128w = f.bw + 31 >> 5; - f.sb128h = f.bh + 31 >> 5; - f.sb_shift = 4 + seq_hdr.sb128 as c_int; - f.sb_step = 16 << seq_hdr.sb128; - f.sbh = f.bh + f.sb_step - 1 >> f.sb_shift; - f.b4_stride = (f.bw + 31 & !31) as ptrdiff_t; - f.bitdepth_max = (1 << f.cur.p.bpc) - 1; + f.content.w4 = f.frame_hdr.size.width[0] + 3 >> 2; + f.content.h4 = f.frame_hdr.size.height + 3 >> 2; + f.content.bw = (f.frame_hdr.size.width[0] + 7 >> 3) << 1; + f.content.bh = (f.frame_hdr.size.height + 7 >> 3) << 1; + f.content.sb128w = f.content.bw + 31 >> 5; + f.content.sb128h = f.content.bh + 31 >> 5; + f.content.sb_shift = 4 + f.seq_hdr.sb128 as c_int; + f.content.sb_step = 16 << f.seq_hdr.sb128; + f.content.sbh = f.content.bh + f.content.sb_step - 1 >> f.content.sb_shift; + f.content.b4_stride = (f.content.bw + 31 & !31) as ptrdiff_t; + f.content.bitdepth_max = (1 << f.content.cur.p.bpc) - 1; fc.task_thread.error.store(0, Ordering::Relaxed); let uses_2pass = (c.fc.len() > 1) as c_int; - let cols = frame_hdr.tiling.cols; - let rows = frame_hdr.tiling.rows; + let cols = f.frame_hdr.tiling.cols; + let rows = f.frame_hdr.tiling.rows; fc.task_thread.task_counter.store( - cols as c_int * rows as c_int + f.sbh << uses_2pass, + cols as c_int * rows as c_int + f.content.sbh << uses_2pass, Ordering::SeqCst, ); // ref_mvs - if frame_hdr.frame_type.is_inter_or_switch() || frame_hdr.allow_intrabc { + if f.frame_hdr.frame_type.is_inter_or_switch() || f.frame_hdr.allow_intrabc { // TODO fallible allocation - f.mvs = Some( - (0..f.sb128h as usize * 16 * (f.b4_stride >> 1) as usize) + f.content.mvs = Some( + (0..f.content.sb128h as usize * 16 * (f.content.b4_stride >> 1) as usize) .map(|_| Default::default()) .collect(), ); - if !frame_hdr.allow_intrabc { + if !f.frame_hdr.allow_intrabc { for i in 0..7 { - f.refpoc[i] = f.refp[i].p.frame_hdr.as_ref().unwrap().frame_offset as c_uint; + f.content.refpoc[i] = + f.content.refp[i].p.frame_hdr.as_ref().unwrap().frame_offset as c_uint; } } else { - f.refpoc.fill(0); + f.content.refpoc.fill(0); } - if frame_hdr.use_ref_frame_mvs != 0 { + if f.frame_hdr.use_ref_frame_mvs != 0 { for i in 0..7 { - let refidx = frame_hdr.refidx[i] as usize; + let refidx = f.frame_hdr.refidx[i] as usize; let ref_w = (ref_coded_width[i] + 7 >> 3) << 1; - let ref_h = (f.refp[i].p.p.h + 7 >> 3) << 1; - if ref_w == f.bw && ref_h == f.bh { - f.ref_mvs[i] = state.refs[refidx].refmvs.clone(); + let ref_h = (f.content.refp[i].p.p.h + 7 >> 3) << 1; + if ref_w == f.content.bw && ref_h == f.content.bh { + f.content.ref_mvs[i] = state.refs[refidx].refmvs.clone(); } else { - f.ref_mvs[i] = None; + f.content.ref_mvs[i] = None; } - f.refrefpoc[i] = state.refs[refidx].refpoc; + f.content.refrefpoc[i] = state.refs[refidx].refpoc; } } else { - f.ref_mvs.fill_with(Default::default); + f.content.ref_mvs.fill_with(Default::default); } } else { - f.mvs = None; - f.ref_mvs.fill_with(Default::default); + f.content.mvs = None; + f.content.ref_mvs.fill_with(Default::default); } // segmap - if frame_hdr.segmentation.enabled != 0 { + if f.frame_hdr.segmentation.enabled != 0 { // By default, the previous segmentation map is not initialised. - f.prev_segmap = None; + f.content.prev_segmap = None; // We might need a previous frame's segmentation map. // This happens if there is either no update or a temporal update. - if frame_hdr.segmentation.temporal != 0 || frame_hdr.segmentation.update_map == 0 { - let pri_ref = frame_hdr.primary_ref_frame as usize; + if f.frame_hdr.segmentation.temporal != 0 || f.frame_hdr.segmentation.update_map == 0 { + let pri_ref = f.frame_hdr.primary_ref_frame as usize; assert!(pri_ref != RAV1D_PRIMARY_REF_NONE as usize); let ref_w = (ref_coded_width[pri_ref] + 7 >> 3) << 1; - let ref_h = (f.refp[pri_ref].p.p.h + 7 >> 3) << 1; - if ref_w == f.bw && ref_h == f.bh { - f.prev_segmap = state.refs[frame_hdr.refidx[pri_ref] as usize] + let ref_h = (f.content.refp[pri_ref].p.p.h + 7 >> 3) << 1; + if ref_w == f.content.bw && ref_h == f.content.bh { + f.content.prev_segmap = state.refs[f.frame_hdr.refidx[pri_ref] as usize] .segmap .clone(); } } - f.cur_segmap = Some( + f.content.cur_segmap = Some( match ( - frame_hdr.segmentation.update_map != 0, - f.prev_segmap.as_mut(), + f.frame_hdr.segmentation.update_map != 0, + f.content.prev_segmap.as_mut(), ) { (true, _) | (false, None) => { // If we're updating an existing map, @@ -5284,7 +5337,7 @@ pub fn rav1d_submit_frame(c: &Rav1dContext, state: &mut Rav1dState) -> Rav1dResu // Otherwise if there's no previous, we need to make a new map. // Allocate one here and zero it out. - let segmap_size = f.b4_stride as usize * 32 * f.sb128h as usize; + let segmap_size = f.content.b4_stride as usize * 32 * f.content.sb128h as usize; // TODO fallible allocation (0..segmap_size).map(|_| Default::default()).collect() } @@ -5296,34 +5349,34 @@ pub fn rav1d_submit_frame(c: &Rav1dContext, state: &mut Rav1dState) -> Rav1dResu }, ); } else { - f.cur_segmap = None; - f.prev_segmap = None; + f.content.cur_segmap = None; + f.content.prev_segmap = None; } // update references etc. - let refresh_frame_flags = frame_hdr.refresh_frame_flags as c_uint; + let refresh_frame_flags = f.frame_hdr.refresh_frame_flags as c_uint; for i in 0..8 { if refresh_frame_flags & (1 << i) != 0 { if state.refs[i].p.p.frame_hdr.is_some() { let _ = mem::take(&mut state.refs[i].p); } - state.refs[i].p = f.sr_cur.clone(); + state.refs[i].p = f.content.sr_cur.clone(); - if frame_hdr.refresh_context != 0 { - state.cdf[i] = f.out_cdf.clone(); + if f.frame_hdr.refresh_context != 0 { + state.cdf[i] = f.content.out_cdf.clone(); } else { state.cdf[i] = fc.in_cdf.try_read().unwrap().clone(); } - state.refs[i].segmap = f.cur_segmap.clone(); + state.refs[i].segmap = f.content.cur_segmap.clone(); let _ = mem::take(&mut state.refs[i].refmvs); - if !frame_hdr.allow_intrabc { - state.refs[i].refmvs = f.mvs.clone(); + if !f.frame_hdr.allow_intrabc { + state.refs[i].refmvs = f.content.mvs.clone(); } - state.refs[i].refpoc = f.refpoc; + state.refs[i].refpoc = f.content.refpoc; } } - drop(f); + drop(f_guard); if c.fc.len() == 1 { let res = rav1d_decode_frame(c, &fc); @@ -5342,7 +5395,7 @@ pub fn rav1d_submit_frame(c: &Rav1dContext, state: &mut Rav1dState) -> Rav1dResu let mut f = fc.data.try_write().unwrap(); on_error( fc, - &mut f, + &mut *f, &mut state.out, &mut state.cached_error_props, &state.in_0.m, diff --git a/src/internal.rs b/src/internal.rs index 7c864988c..544435157 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -749,7 +749,7 @@ pub(crate) struct Rav1dFrameContext { /// Index in [`Rav1dContext::fc`] pub index: usize, - pub data: RwLock, + pub data: RwLock, pub in_cdf: RwLock, pub task_thread: Rav1dFrameContextTaskThread, pub frame_thread_progress: Rav1dFrameContextFrameThreadProgress, @@ -783,9 +783,7 @@ impl Rav1dFrameContext { #[derive(Default)] #[repr(C)] -pub(crate) struct Rav1dFrameData { - pub seq_hdr: Option>>, - pub frame_hdr: Option>>, +pub(crate) struct Rav1dFrameContent { pub refp: [Rav1dThreadPicture; 7], // during block coding / reconstruction pub cur: Rav1dPicture, @@ -839,18 +837,71 @@ pub(crate) struct Rav1dFrameData { pub lowest_pixel_mem: DisjointMut>, } -impl Rav1dFrameData { - pub fn bd_fn(&self) -> &'static Rav1dFrameContextBdFn { - let bpc = BPC::from_bitdepth_max(self.bitdepth_max); - Rav1dFrameContextBdFn::get(bpc) +#[derive(Default)] +#[repr(C)] +pub(crate) struct Rav1dFrameDataMaybeHeaders { + pub seq_hdr: Option>>, + pub frame_hdr: Option>>, + pub content: Rav1dFrameContent, +} + +#[repr(C)] +pub(crate) struct Rav1dFrameData { + pub seq_hdr: Arc>, + pub frame_hdr: Arc>, + pub content: Rav1dFrameContent, +} + +impl Rav1dFrameDataMaybeHeaders { + pub fn assert_has_headers<'a>(&'a self) -> &'a Rav1dFrameData { + if self.seq_hdr.as_ref().is_none() { + panic!("required sequence header past this point"); + } + + if self.frame_hdr.as_ref().is_none() { + panic!("required frame header past this point"); + } + + // Safety: we just asserted that seq_hdr and frame_hdr are Some, and Option> has the + // same layout as Arc. further, `Rav1dFrameData` and `Rav1dFrameDataWithHeaders` have + // the same layout with repr(C) ensuring their field ordering is identical. + unsafe { std::mem::transmute(self) } } - pub fn frame_hdr(&self) -> &Rav1dFrameHeader { - self.frame_hdr.as_ref().unwrap() + pub fn assert_has_headers_mut<'a>(&'a mut self) -> &'a mut Rav1dFrameData { + if self.seq_hdr.as_ref().is_none() { + panic!("required sequence header past this point"); + } + + if self.frame_hdr.as_ref().is_none() { + panic!("required frame header past this point"); + } + + // Safety: we just asserted that seq_hdr and frame_hdr are Some, and Option> has the + // same layout as Arc. further, `Rav1dFrameData` and `Rav1dFrameDataWithHeaders` have + // the same layout with repr(C) ensuring their field ordering is identical. + // Same as `assert_has_headers` overall; we have the sole `&mut self`, so we maintain + // exclusivity with the returned `&'a mut` ref returned here. + unsafe { std::mem::transmute(self) } } +} + +impl<'a> From<&'a mut Rav1dFrameData> for &'a mut Rav1dFrameDataMaybeHeaders { + fn from(v: &'a mut Rav1dFrameData) -> Self { + // Safety: as an implementation detail of Rust today, Arc is just a glorified + // NonNull>. this will be niche elided into a `Some` when transmuted to + // `Option>`. this is not guaranteed to remain so, and `Arc` with non-ZST + // allocators will trivially violate this. + // + // to repeat: safe only as an implementation detail of Rust to date. + unsafe { std::mem::transmute(v) } + } +} - pub fn seq_hdr(&self) -> &Rav1dSequenceHeader { - self.seq_hdr.as_ref().unwrap() +impl Rav1dFrameData { + pub fn bd_fn(&self) -> &'static Rav1dFrameContextBdFn { + let bpc = BPC::from_bitdepth_max(self.content.bitdepth_max); + Rav1dFrameContextBdFn::get(bpc) } } diff --git a/src/lf_apply.rs b/src/lf_apply.rs index 481ad94eb..ea055a06c 100644 --- a/src/lf_apply.rs +++ b/src/lf_apply.rs @@ -153,28 +153,28 @@ pub(crate) fn rav1d_copy_lpf( src: [Rav1dPictureDataComponentOffset; 3], sby: c_int, ) { - let bd = BD::from_c(f.bitdepth_max); + let bd = BD::from_c(f.content.bitdepth_max); let have_tt = (c.tc.len() > 1) as c_int; - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; let resize = (frame_hdr.size.width[0] != frame_hdr.size.width[1]) as c_int; let offset_y = 8 * (sby != 0) as c_int; - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); + let seq_hdr = &f.seq_hdr; let tt_off = have_tt * sby * (4 << seq_hdr.sb128); - let sr_cur_data = &f.sr_cur.p.data.as_ref().unwrap().data; + let sr_cur_data = &f.content.sr_cur.p.data.as_ref().unwrap().data; let dst = array::from_fn::<_, 3, _>(|i| { let data = &sr_cur_data[i]; - let offset = - f.lf.lr_lpf_line[i].wrapping_add_signed(tt_off as isize * data.pixel_stride::()); + let offset = f.content.lf.lr_lpf_line[i] + .wrapping_add_signed(tt_off as isize * data.pixel_stride::()); Rav1dPictureDataComponentOffset { data, offset } }); // TODO Also check block level restore type to reduce copying. - let restore_planes = f.lf.restore_planes; + let restore_planes = f.content.lf.restore_planes; if seq_hdr.cdef != 0 || restore_planes.contains(LrRestorePlanes::Y) { - let h = f.cur.p.h; - let w = f.bw << 2; + let h = f.content.cur.p.h; + let w = f.content.bw << 2; let row_h = cmp::min((sby + 1) << 6 + seq_hdr.sb128, h - 1); let y_stripe = (sby << 6 + seq_hdr.sb128) - offset_y; if restore_planes.contains(LrRestorePlanes::Y) || resize == 0 { @@ -182,7 +182,7 @@ pub(crate) fn rav1d_copy_lpf( c, WithOffset { data: WithStride { - buf: &f.lf.lr_line_buf, + buf: &f.content.lf.lr_line_buf, stride: dst[0].stride(), }, offset: dst[0].offset, @@ -197,22 +197,23 @@ pub(crate) fn rav1d_copy_lpf( 0, 1, frame_hdr, - f.dsp, - f.resize_step, - f.resize_start, + f.content.dsp, + f.content.resize_step, + f.content.resize_start, bd, ); } if have_tt != 0 && resize != 0 { let cdef_off_y = (sby * 4) as isize * src[0].pixel_stride::(); - let cdef_plane_y_sz = 4 * f.sbh as isize * src[0].pixel_stride::(); + let cdef_plane_y_sz = 4 * f.content.sbh as isize * src[0].pixel_stride::(); let y_span = cdef_plane_y_sz - src[0].pixel_stride::(); - let cdef_line_start = (f.lf.cdef_lpf_line[0] as isize + cmp::min(y_span, 0)) as usize; + let cdef_line_start = + (f.content.lf.cdef_lpf_line[0] as isize + cmp::min(y_span, 0)) as usize; backup_lpf::( c, WithOffset { data: WithStride { - buf: &f.lf.cdef_line_buf, + buf: &f.content.lf.cdef_line_buf, stride: src[0].stride(), }, offset: cdef_line_start + (cdef_off_y - cmp::min(y_span, 0)) as usize, @@ -227,20 +228,20 @@ pub(crate) fn rav1d_copy_lpf( 0, 0, frame_hdr, - f.dsp, - f.resize_step, - f.resize_start, + f.content.dsp, + f.content.resize_step, + f.content.resize_start, bd, ); } } if (seq_hdr.cdef != 0 || restore_planes.intersects(LrRestorePlanes::UV)) - && f.cur.p.layout != Rav1dPixelLayout::I400 + && f.content.cur.p.layout != Rav1dPixelLayout::I400 { - let ss_ver = (f.sr_cur.p.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (f.sr_cur.p.p.layout != Rav1dPixelLayout::I444) as c_int; - let h_0 = f.cur.p.h + ss_ver >> ss_ver; - let w_0 = f.bw << 2 - ss_hor; + let ss_ver = (f.content.sr_cur.p.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (f.content.sr_cur.p.p.layout != Rav1dPixelLayout::I444) as c_int; + let h_0 = f.content.cur.p.h + ss_ver >> ss_ver; + let w_0 = f.content.bw << 2 - ss_hor; let row_h_0 = cmp::min((sby + 1) << 6 - ss_ver + seq_hdr.sb128 as c_int, h_0 - 1); let offset_uv = offset_y >> ss_ver; let y_stripe_0 = (sby << 6 - ss_ver + seq_hdr.sb128 as c_int) - offset_uv; @@ -251,7 +252,7 @@ pub(crate) fn rav1d_copy_lpf( c, WithOffset { data: WithStride { - buf: &f.lf.lr_line_buf, + buf: &f.content.lf.lr_line_buf, stride: dst[1].stride(), }, offset: dst[1].offset, @@ -266,22 +267,22 @@ pub(crate) fn rav1d_copy_lpf( ss_hor, 1, frame_hdr, - f.dsp, - f.resize_step, - f.resize_start, + f.content.dsp, + f.content.resize_step, + f.content.resize_start, bd, ); } if have_tt != 0 && resize != 0 { - let cdef_plane_uv_sz = 4 * f.sbh as isize * src[1].pixel_stride::(); + let cdef_plane_uv_sz = 4 * f.content.sbh as isize * src[1].pixel_stride::(); let uv_span = cdef_plane_uv_sz - src[1].pixel_stride::(); let cdef_line_start = - (f.lf.cdef_lpf_line[1] as isize + cmp::min(uv_span, 0)) as usize; + (f.content.lf.cdef_lpf_line[1] as isize + cmp::min(uv_span, 0)) as usize; backup_lpf::( c, WithOffset { data: WithStride { - buf: &f.lf.cdef_line_buf, + buf: &f.content.lf.cdef_line_buf, stride: src[1].stride(), }, offset: cdef_line_start + (cdef_off_uv - cmp::min(uv_span, 0)) as usize, @@ -296,9 +297,9 @@ pub(crate) fn rav1d_copy_lpf( ss_hor, 0, frame_hdr, - f.dsp, - f.resize_step, - f.resize_start, + f.content.dsp, + f.content.resize_step, + f.content.resize_start, bd, ); } @@ -309,7 +310,7 @@ pub(crate) fn rav1d_copy_lpf( c, WithOffset { data: WithStride { - buf: &f.lf.lr_line_buf, + buf: &f.content.lf.lr_line_buf, stride: dst[2].stride(), }, offset: dst[2].offset, @@ -324,22 +325,22 @@ pub(crate) fn rav1d_copy_lpf( ss_hor, 1, frame_hdr, - f.dsp, - f.resize_step, - f.resize_start, + f.content.dsp, + f.content.resize_step, + f.content.resize_start, bd, ); } if have_tt != 0 && resize != 0 { - let cdef_plane_uv_sz = 4 * f.sbh as isize * src[2].pixel_stride::(); + let cdef_plane_uv_sz = 4 * f.content.sbh as isize * src[2].pixel_stride::(); let uv_span = cdef_plane_uv_sz - src[2].pixel_stride::(); let cdef_line_start = - (f.lf.cdef_lpf_line[2] as isize + cmp::min(uv_span, 0)) as usize; + (f.content.lf.cdef_lpf_line[2] as isize + cmp::min(uv_span, 0)) as usize; backup_lpf::( c, WithOffset { data: WithStride { - buf: &f.lf.cdef_line_buf, + buf: &f.content.lf.cdef_line_buf, stride: src[2].stride(), }, offset: cdef_line_start + (cdef_off_uv - cmp::min(uv_span, 0)) as usize, @@ -354,9 +355,9 @@ pub(crate) fn rav1d_copy_lpf( ss_hor, 0, frame_hdr, - f.dsp, - f.resize_step, - f.resize_start, + f.content.dsp, + f.content.resize_step, + f.content.resize_start, bd, ); } @@ -376,7 +377,7 @@ fn filter_plane_cols_y( endy4: usize, ) { // filter edges between columns (e.g. block1 | block2) - let lf_sb = &f.dsp.lf.loop_filter_sb; + let lf_sb = &f.content.dsp.lf.loop_filter_sb; let len = endy4 - starty4; let y_dst = |x| y_dst + x * 4; y_dst(w).as_ptr::(); // Bounds check @@ -416,7 +417,7 @@ fn filter_plane_rows_y( // block1 // filter edges between rows (e.g. ------) // block2 - let lf_sb = &f.dsp.lf.loop_filter_sb; + let lf_sb = &f.content.dsp.lf.loop_filter_sb; let len = endy4 - starty4; let y_dst = |i| y_dst + (i as isize * 4 * y_dst.pixel_stride::()); y_dst(len - 1).as_ptr::(); // Bounds check @@ -447,7 +448,7 @@ fn filter_plane_cols_uv( ss_ver: c_int, ) { // filter edges between columns (e.g. block1 | block2) - let lf_sb = &f.dsp.lf.loop_filter_sb; + let lf_sb = &f.content.dsp.lf.loop_filter_sb; let len = endy4 - starty4; let u_dst = |x| u_dst + x * 4; let v_dst = |x| v_dst + x * 4; @@ -493,7 +494,7 @@ fn filter_plane_rows_uv( // block1 // filter edges between rows (e.g. ------) // block2 - let lf_sb = &f.dsp.lf.loop_filter_sb; + let lf_sb = &f.content.dsp.lf.loop_filter_sb; let len = endy4 - starty4; let u_dst = |i| u_dst + (i as isize * 4 * u_dst.pixel_stride::()); let v_dst = |i| v_dst + (i as isize * 4 * v_dst.pixel_stride::()); @@ -521,38 +522,38 @@ pub(crate) fn rav1d_loopfilter_sbrow_cols( sby: c_int, start_of_tile_row: c_int, ) { - let lflvl = &f.lf.mask[lflvl_offset..]; + let lflvl = &f.content.lf.mask[lflvl_offset..]; let mut have_left; // Don't filter outside the frame - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); + let seq_hdr = &f.seq_hdr; let is_sb64 = (seq_hdr.sb128 == 0) as c_int; let starty4 = ((sby & is_sb64) as u32) << 4; let sbsz = 32 >> is_sb64; let sbl2 = 5 - is_sb64; - let halign = (f.bh + 31 & !31) as usize; - let ss_ver = (f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + let halign = (f.content.bh + 31 & !31) as usize; + let ss_ver = (f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; let vmask = 16 >> ss_ver; let hmask = 16 >> ss_hor; let vmax = (1 as c_uint) << vmask; let hmax = (1 as c_uint) << hmask; - let endy4 = starty4 + cmp::min(f.h4 - sby * sbsz, sbsz) as u32; + let endy4 = starty4 + cmp::min(f.content.h4 - sby * sbsz, sbsz) as u32; let uv_endy4 = (endy4 + ss_ver as u32) >> ss_ver; let mut lpf_y_idx = (sby << sbl2) as usize; let mut lpf_uv_idx = (sby << sbl2 - ss_ver) as usize; - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; // fix lpf strength at tile col boundaries let mut tile_col = 1; loop { let mut x = frame_hdr.tiling.col_start_sb[tile_col as usize] as c_int; - if x << sbl2 >= f.bw { + if x << sbl2 >= f.content.bw { break; } let bx4: c_int = if x & is_sb64 != 0 { 16 } else { 0 }; let cbx4 = bx4 >> ss_hor; x >>= is_sb64; let y_hmask = &lflvl[x as usize].filter_y[0][bx4 as usize]; - let (lpf_y, lpf_uv) = f.lf.tx_lpf_right_edge.get( + let (lpf_y, lpf_uv) = f.content.lf.tx_lpf_right_edge.get( lpf_y_idx..lpf_y_idx + (endy4 - starty4) as usize, lpf_uv_idx..lpf_uv_idx + (uv_endy4 - (starty4 >> ss_ver)) as usize, ); @@ -568,7 +569,7 @@ pub(crate) fn rav1d_loopfilter_sbrow_cols( y_hmask[cmp::min(idx, lpf_y[(y - starty4) as usize] as usize)][sidx] .update(|it| it | smask); } - if f.cur.p.layout != Rav1dPixelLayout::I400 { + if f.content.cur.p.layout != Rav1dPixelLayout::I400 { let uv_hmask = &lflvl[x as usize].filter_uv[0][cbx4 as usize]; for y in starty4 >> ss_ver..uv_endy4 { let uv_mask: u32 = 1 << y; @@ -588,10 +589,10 @@ pub(crate) fn rav1d_loopfilter_sbrow_cols( // fix lpf strength at tile row boundaries if start_of_tile_row != 0 { - let mut a = &f.a[(f.sb128w * (start_of_tile_row - 1)) as usize..]; - for x in 0..f.sb128w { + let mut a = &f.content.a[(f.content.sb128w * (start_of_tile_row - 1)) as usize..]; + for x in 0..f.content.sb128w { let y_vmask = &lflvl[x as usize].filter_y[1][starty4 as usize]; - let w = cmp::min(32, f.w4 - (x << 5)) as u32; + let w = cmp::min(32, f.content.w4 - (x << 5)) as u32; for i in 0..w { let mask: u32 = 1 << i; let sidx = (mask >= 0x10000) as usize; @@ -604,7 +605,7 @@ pub(crate) fn rav1d_loopfilter_sbrow_cols( y_vmask[cmp::min(idx, *a[0].tx_lpf_y.index(i as usize) as usize)][sidx] .update(|it| it | smask); } - if f.cur.p.layout != Rav1dPixelLayout::I400 { + if f.content.cur.p.layout != Rav1dPixelLayout::I400 { let cw: c_uint = w.wrapping_add(ss_hor as c_uint) >> ss_hor; let uv_vmask = &lflvl[x as usize].filter_uv[1][(starty4 >> ss_ver) as usize]; for i in 0..cw { @@ -621,20 +622,20 @@ pub(crate) fn rav1d_loopfilter_sbrow_cols( a = &a[1..]; } } - let lflvl = &f.lf.mask[lflvl_offset..]; + let lflvl = &f.content.lf.mask[lflvl_offset..]; let lvl = WithOffset { - data: &f.lf.level, - offset: 4 * f.b4_stride as usize * (sby * sbsz) as usize, + data: &f.content.lf.level, + offset: 4 * f.content.b4_stride as usize * (sby * sbsz) as usize, }; have_left = false; - for x in 0..f.sb128w as usize { + for x in 0..f.content.sb128w as usize { filter_plane_cols_y::( f, have_left, lvl + 4 * x * 32, &lflvl[x].filter_y[0], py + x * 128, - cmp::min(32, f.w4 - x as c_int * 32) as usize, + cmp::min(32, f.content.w4 - x as c_int * 32) as usize, starty4 as usize, endy4 as usize, ); @@ -644,11 +645,11 @@ pub(crate) fn rav1d_loopfilter_sbrow_cols( return; } let lvl = WithOffset { - data: &f.lf.level, - offset: 4 * f.b4_stride as usize * (sby * sbsz >> ss_ver) as usize, + data: &f.content.lf.level, + offset: 4 * f.content.b4_stride as usize * (sby * sbsz >> ss_ver) as usize, }; have_left = false; - for x in 0..f.sb128w as usize { + for x in 0..f.content.sb128w as usize { filter_plane_cols_uv::( f, have_left, @@ -656,7 +657,7 @@ pub(crate) fn rav1d_loopfilter_sbrow_cols( &lflvl[x].filter_uv[0], pu + x * (128 >> ss_hor), pv + x * (128 >> ss_hor), - (cmp::min(32, f.w4 - x as c_int * 32) + ss_hor >> ss_hor) as usize, + (cmp::min(32, f.content.w4 - x as c_int * 32) + ss_hor >> ss_hor) as usize, starty4 as usize >> ss_ver, uv_endy4 as usize, ss_ver, @@ -671,57 +672,57 @@ pub(crate) fn rav1d_loopfilter_sbrow_rows( lflvl_offset: usize, sby: c_int, ) { - let lflvl = &f.lf.mask[lflvl_offset..]; + let lflvl = &f.content.lf.mask[lflvl_offset..]; // Don't filter outside the frame let have_top = sby > 0; - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); + let seq_hdr = &f.seq_hdr; let is_sb64 = (seq_hdr.sb128 == 0) as c_int; let starty4 = (sby & is_sb64) << 4; let sbsz = 32 >> is_sb64; - let ss_ver = (f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; - let endy4: c_uint = (starty4 + cmp::min(f.h4 - sby * sbsz, sbsz)) as c_uint; + let ss_ver = (f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + let endy4: c_uint = (starty4 + cmp::min(f.content.h4 - sby * sbsz, sbsz)) as c_uint; let uv_endy4: c_uint = endy4.wrapping_add(ss_ver as c_uint) >> ss_ver; let lvl = WithOffset { - data: &f.lf.level, - offset: 4 * f.b4_stride as usize * (sby * sbsz) as usize, + data: &f.content.lf.level, + offset: 4 * f.content.b4_stride as usize * (sby * sbsz) as usize, }; - for x in 0..f.sb128w as usize { + for x in 0..f.content.sb128w as usize { filter_plane_rows_y::( f, have_top, lvl + 4 * x * 32, - f.b4_stride as usize, + f.content.b4_stride as usize, &lflvl[x].filter_y[1], p[0] + 128 * x, - cmp::min(32, f.w4 - x as c_int * 32) as usize, + cmp::min(32, f.content.w4 - x as c_int * 32) as usize, starty4 as usize, endy4 as usize, ); } - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; if frame_hdr.loopfilter.level_u == 0 && frame_hdr.loopfilter.level_v == 0 { return; } let lvl = WithOffset { - data: &f.lf.level, - offset: 4 * f.b4_stride as usize * (sby * sbsz >> ss_ver) as usize, + data: &f.content.lf.level, + offset: 4 * f.content.b4_stride as usize * (sby * sbsz >> ss_ver) as usize, }; let [_, pu, pv] = p; - for x in 0..f.sb128w as usize { + for x in 0..f.content.sb128w as usize { filter_plane_rows_uv::( f, have_top, lvl + 4 * x * (32 >> ss_hor), - f.b4_stride as usize, + f.content.b4_stride as usize, &lflvl[x].filter_uv[1], pu + (x * 128 >> ss_hor), pv + (x * 128 >> ss_hor), - (cmp::min(32 as c_int, f.w4 - x as c_int * 32) + ss_hor >> ss_hor) as usize, + (cmp::min(32 as c_int, f.content.w4 - x as c_int * 32) + ss_hor >> ss_hor) as usize, starty4 as usize >> ss_ver, uv_endy4 as usize, ss_hor, diff --git a/src/lib.rs b/src/lib.rs index 6c9366eb0..4dedd1e06 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -232,7 +232,7 @@ pub(crate) fn rav1d_open(s: &Rav1dSettings) -> Rav1dResult> { fc.task_thread.finished = AtomicBool::new(true); fc.task_thread.ttd = Arc::clone(&task_thread); let f = fc.data.get_mut(); - f.lf.last_sharpness = u8::MAX; + f.content.lf.last_sharpness = u8::MAX; fc }) // TODO fallible allocation diff --git a/src/loopfilter.rs b/src/loopfilter.rs index c7303e14e..876e13bc8 100644 --- a/src/loopfilter.rs +++ b/src/loopfilter.rs @@ -53,10 +53,10 @@ impl loopfilter_sb::Fn { // SAFETY: `lvl.offset` is in bounds, just checked above. let lvl_ptr = unsafe { lvl.data.as_mut_ptr().add(lvl.offset) }; let lvl_ptr = lvl_ptr.cast::<[u8; 4]>(); - let b4_stride = f.b4_stride; - let lut = &f.lf.lim_lut; + let b4_stride = f.content.b4_stride; + let lut = &f.content.lf.lim_lut; let w = w as c_int; - let bd = f.bitdepth_max; + let bd = f.content.bitdepth_max; let dst = FFISafe::new(&dst); let lvl = FFISafe::new(&lvl); // SAFETY: Fallback `fn loop_filter_sb128_rust` is safe; asm is supposed to do the same. diff --git a/src/lr_apply.rs b/src/lr_apply.rs index bd61f12dc..a6245fd15 100644 --- a/src/lr_apply.rs +++ b/src/lr_apply.rs @@ -43,16 +43,16 @@ fn lr_stripe( lr: Av1RestorationUnit, mut edges: LrEdgeFlags, ) { - let bd = BD::from_c(f.bitdepth_max); + let bd = BD::from_c(f.content.bitdepth_max); - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); + let seq_hdr = &f.seq_hdr; let chroma = (plane != 0) as c_int; - let ss_ver = chroma & (f.sr_cur.p.p.layout == Rav1dPixelLayout::I420) as c_int; - let stride: ptrdiff_t = f.sr_cur.p.stride[chroma as usize]; + let ss_ver = chroma & (f.content.sr_cur.p.p.layout == Rav1dPixelLayout::I420) as c_int; + let stride: ptrdiff_t = f.content.sr_cur.p.stride[chroma as usize]; let sby = y + (if y != 0 { 8 << ss_ver } else { 0 }) >> 6 - ss_ver + seq_hdr.sb128 as c_int; let have_tt = (c.tc.len() > 1) as c_int; let lpf_stride = BD::pxstride(stride); - let mut lpf_offset = f.lf.lr_lpf_line[plane as usize] as isize; + let mut lpf_offset = f.content.lf.lr_lpf_line[plane as usize] as isize; lpf_offset += (have_tt * (sby * (4 << seq_hdr.sb128) - 4)) as isize * lpf_stride + x as isize; // The first stripe of the frame is shorter by 8 luma pixel rows. let mut stripe_h = cmp::min(64 - 8 * (y == 0) as c_int >> ss_ver, row_h - y); @@ -82,7 +82,7 @@ fn lr_stripe( filter[1][4] = lr.filter_v[2] as i16; filter[1][3] = 128 - (filter[1][0] + filter[1][1] + filter[1][2]) * 2; - lr_fn = f.dsp.lr.wiener[((filter[0][0] | filter[1][0]) == 0) as usize]; + lr_fn = f.content.dsp.lr.wiener[((filter[0][0] | filter[1][0]) == 0) as usize]; } else { let sgr_idx = assert_matches!(lr.r#type, Rav1dRestorationType::SgrProj(idx) => idx); let sgr_params = &dav1d_sgr_params[sgr_idx as usize]; @@ -92,19 +92,20 @@ fn lr_stripe( w0: lr.sgr_weights[0] as i16, w1: 128 - (lr.sgr_weights[0] as i16 + lr.sgr_weights[1] as i16), }; - lr_fn = f.dsp.lr.sgr[(sgr_params[0] != 0) as usize + (sgr_params[1] != 0) as usize * 2 - 1]; + lr_fn = f.content.dsp.lr.sgr + [(sgr_params[0] != 0) as usize + (sgr_params[1] != 0) as usize * 2 - 1]; } let mut left = &left[..]; while y + stripe_h <= row_h { edges.set( LrEdgeFlags::BOTTOM, - sby + 1 != f.sbh || y + stripe_h != row_h, + sby + 1 != f.content.sbh || y + stripe_h != row_h, ); lr_fn.call::( p, left, - &f.lf.lr_line_buf, + &f.content.lf.lr_line_buf, lpf_offset, unit_w, stripe_h, @@ -152,9 +153,9 @@ fn lr_sbrow( plane: c_int, ) { let chroma = (plane != 0) as c_int; - let ss_ver = chroma & (f.sr_cur.p.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = chroma & (f.sr_cur.p.p.layout != Rav1dPixelLayout::I444) as c_int; - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let ss_ver = chroma & (f.content.sr_cur.p.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = chroma & (f.content.sr_cur.p.p.layout != Rav1dPixelLayout::I444) as c_int; + let frame_hdr = &f.frame_hdr; let unit_size_log2 = frame_hdr.restoration.unit_size[(plane != 0) as usize]; let unit_size = (1 as c_int) << unit_size_log2; let half_unit_size = unit_size >> 1; @@ -182,9 +183,9 @@ fn lr_sbrow( aligned_unit_pos -= unit_size; } aligned_unit_pos <<= ss_ver; - let sb_idx = (aligned_unit_pos >> 7) * f.sr_sb128w; + let sb_idx = (aligned_unit_pos >> 7) * f.content.sr_sb128w; let unit_idx = (aligned_unit_pos >> 6 & 1) << 1; - lr[0] = *f.lf.lr_mask[sb_idx as usize].lr[plane as usize][unit_idx as usize] + lr[0] = *f.content.lf.lr_mask[sb_idx as usize].lr[plane as usize][unit_idx as usize] .try_read() .unwrap(); let mut restore = lr[0].r#type != Rav1dRestorationType::None; @@ -193,7 +194,7 @@ fn lr_sbrow( while x + max_unit_size <= w { let next_x = x + unit_size; let next_u_idx = unit_idx + (next_x >> shift_hor - 1 & 1); - lr[!bit as usize] = *f.lf.lr_mask[(sb_idx + (next_x >> shift_hor)) as usize].lr + lr[!bit as usize] = *f.content.lf.lr_mask[(sb_idx + (next_x >> shift_hor)) as usize].lr [plane as usize][next_u_idx as usize] .try_read() .unwrap(); @@ -252,12 +253,12 @@ pub(crate) fn rav1d_lr_sbrow( sby: c_int, ) { let offset_y = 8 * (sby != 0) as c_int; - let restore_planes = f.lf.restore_planes; - let not_last = ((sby + 1) < f.sbh) as c_int; - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); + let restore_planes = f.content.lf.restore_planes; + let not_last = ((sby + 1) < f.content.sbh) as c_int; + let seq_hdr = &f.seq_hdr; if restore_planes.contains(LrRestorePlanes::Y) { - let h = f.sr_cur.p.p.h; - let w = f.sr_cur.p.p.w; + let h = f.content.sr_cur.p.p.h; + let w = f.content.sr_cur.p.p.w; let next_row_y = (sby + 1) << 6 + seq_hdr.sb128; let row_h = cmp::min(next_row_y - 8 * not_last, h); let y_stripe = (sby << 6 + seq_hdr.sb128) - offset_y; @@ -273,10 +274,10 @@ pub(crate) fn rav1d_lr_sbrow( ); } if restore_planes.intersects(LrRestorePlanes::UV) { - let ss_ver = (f.sr_cur.p.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (f.sr_cur.p.p.layout != Rav1dPixelLayout::I444) as c_int; - let h = f.sr_cur.p.p.h + ss_ver >> ss_ver; - let w = f.sr_cur.p.p.w + ss_hor >> ss_hor; + let ss_ver = (f.content.sr_cur.p.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (f.content.sr_cur.p.p.layout != Rav1dPixelLayout::I444) as c_int; + let h = f.content.sr_cur.p.p.h + ss_ver >> ss_ver; + let w = f.content.sr_cur.p.p.w + ss_hor >> ss_hor; let next_row_y = (sby + 1) << 6 - ss_ver + seq_hdr.sb128 as c_int; let row_h = cmp::min(next_row_y - (8 >> ss_ver) * not_last, h); let offset_uv = offset_y >> ss_ver; diff --git a/src/picture.rs b/src/picture.rs index f96bd631e..36086cd00 100644 --- a/src/picture.rs +++ b/src/picture.rs @@ -220,7 +220,7 @@ fn picture_alloc_with_edges( p: &mut Rav1dPicture, w: c_int, h: c_int, - seq_hdr: Option>>, + seq_hdr: Arc>, frame_hdr: Option>>, bpc: u8, p_allocator: &Rav1dPicAllocator, @@ -230,7 +230,7 @@ fn picture_alloc_with_edges( return Err(EGeneric); } assert!(bpc > 0 && bpc <= 16); - let pic = p_allocator.alloc_picture_data(w, h, seq_hdr.unwrap(), frame_hdr)?; + let pic = p_allocator.alloc_picture_data(w, h, seq_hdr, frame_hdr)?; *p = pic; Ok(()) @@ -264,16 +264,15 @@ pub(crate) fn rav1d_thread_picture_alloc( bpc: u8, itut_t35: Arc>>, ) -> Rav1dResult { - let p = &mut f.sr_cur; + let p = &mut f.content.sr_cur; let have_frame_mt = fc.len() > 1; - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); picture_alloc_with_edges( logger, &mut p.p, - frame_hdr.size.width[1], - frame_hdr.size.height, + f.frame_hdr.size.width[1], + f.frame_hdr.size.height, f.seq_hdr.clone(), - f.frame_hdr.clone(), + Some(f.frame_hdr.clone()), bpc, allocator, )?; @@ -283,13 +282,13 @@ pub(crate) fn rav1d_thread_picture_alloc( content_light, mastering_display, Rav1dITUTT35::to_immut(itut_t35), - f.tiles[0].data.m.clone(), + f.content.tiles[0].data.m.clone(), ); // Don't clear these flags from `c.frame_flags` if the frame is not going to be output. // This way they will be added to the next visible frame too. - let flags_mask = if (frame_hdr.show_frame != 0 || output_invisible_frames) - && max_spatial_id == frame_hdr.spatial_id + let flags_mask = if (f.frame_hdr.show_frame != 0 || output_invisible_frames) + && max_spatial_id == f.frame_hdr.spatial_id { PictureFlags::empty() } else { @@ -297,8 +296,8 @@ pub(crate) fn rav1d_thread_picture_alloc( }; p.flags = *frame_flags; *frame_flags &= flags_mask; - p.visible = frame_hdr.show_frame != 0; - p.showable = frame_hdr.showable_frame != 0; + p.visible = f.frame_hdr.show_frame != 0; + p.showable = f.frame_hdr.showable_frame != 0; p.progress = if have_frame_mt { Some(Default::default()) } else { @@ -318,7 +317,7 @@ pub(crate) fn rav1d_picture_alloc_copy( dst, w, src.p.h, - src.seq_hdr.clone(), + src.seq_hdr.clone().unwrap(), src.frame_hdr.clone(), src.p.bpc, &src.data.as_ref().unwrap().allocator, diff --git a/src/recon.rs b/src/recon.rs index 8833022c9..006f93306 100644 --- a/src/recon.rs +++ b/src/recon.rs @@ -121,7 +121,7 @@ macro_rules! debug_block_info { use crate::src::internal::Bxy; let tb: Bxy = $tb; - false && $f.frame_hdr.as_ref().unwrap().frame_offset == 2 && tb.debug_block_info() + false && $f.frame_hdr.frame_offset == 2 && tb.debug_block_info() }}; } pub(crate) use debug_block_info; @@ -538,9 +538,9 @@ fn decode_coefs( let dc_sign_ctx; let dc_sign; let mut dc_dq; - let ts = &f.ts[ts]; + let ts = &f.content.ts[ts]; let chroma = plane != 0; - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; let lossless = frame_hdr.segmentation.lossless[b.seg_id.get()]; let t_dim = &dav1d_txfm_dimensions[tx as usize]; let dbg = dbg_block_info && plane != 0 && false; @@ -550,7 +550,7 @@ fn decode_coefs( } // does this block have any non-zero coefficients - let sctx = get_skip_ctx(t_dim, bs, a, l, chroma, f.cur.p.layout); + let sctx = get_skip_ctx(t_dim, bs, a, l, chroma, f.content.cur.p.layout); let all_skip = rav1d_msac_decode_bool_adapt( &mut ts_c.msac, &mut ts_c.cdf.coef.skip[t_dim.ctx as usize][sctx.get() as usize], @@ -749,6 +749,7 @@ fn decode_coefs( let cf_len = sw * 4 * sh * 4; let cf = match cf { CfSelect::Frame(offset) => &mut *f + .content .frame_thread .cf .mut_slice_as((offset as usize.., ..cf_len)), @@ -1052,12 +1053,12 @@ fn decode_coefs( // residual and sign let dq = match ts.dq.get() { - TileStateRef::Frame => &f.dq, + TileStateRef::Frame => &f.content.dq, TileStateRef::Local => &ts.dqmem, }; let dq_tbl = &dq[b.seg_id.get()][plane]; let qm_tbl = if *txtp < IDTX { - f.qm[tx as usize][plane] + f.content.qm[tx as usize][plane] } else { None }; @@ -1065,7 +1066,7 @@ fn decode_coefs( let cf_max = !(!127u32 << (match BD::BPC { BPC::BPC8 => 8, - BPC::BPC16 => f.cur.p.bpc, + BPC::BPC16 => f.content.cur.p.bpc, })) as i32; let mut cul_level: c_uint; let dc_sign_level: c_uint; @@ -1253,7 +1254,7 @@ fn decode_coefs( #[derive(Clone, Copy)] enum CfSelect { - /// Use `f.frame_thread.cf` at the specified offset. + /// Use `f.content.frame_thread.cf` at the specified offset. Frame(u32), /// Use `t.cf`. @@ -1273,9 +1274,9 @@ fn read_coef_tree( y_off: c_int, mut y_dst: Option, ) { - let bd = BD::from_c(f.bitdepth_max); + let bd = BD::from_c(f.content.bitdepth_max); - let ts = &f.ts[t.ts]; + let ts = &f.content.ts[t.ts]; let t_dim = &dav1d_txfm_dimensions[ytx as usize]; let txw = t_dim.w; let txh = t_dim.h; @@ -1303,7 +1304,7 @@ fn read_coef_tree( y_dst, ); t.b.x += txsw as c_int; - if txw >= txh && t.b.x < f.bw { + if txw >= txh && t.b.x < f.content.bw { read_coef_tree::( f, t, @@ -1320,7 +1321,7 @@ fn read_coef_tree( } t.b.x -= txsw as c_int; t.b.y += txsh as c_int; - if txh >= txw && t.b.y < f.bh { + if txh >= txw && t.b.y < f.content.bh { y_dst = y_dst.map(|dst| dst + (4 * txsh as isize * dst.pixel_stride::())); read_coef_tree::( f, @@ -1336,7 +1337,7 @@ fn read_coef_tree( y_dst, ); t.b.x += txsw as c_int; - if txw >= txh && t.b.x < f.bw { + if txw >= txh && t.b.x < f.content.bw { read_coef_tree::( f, t, @@ -1379,7 +1380,7 @@ fn read_coef_tree( debug_block_info!(f, t.b), &mut t.scratch, &mut t.cf, - &mut f.a[t.a].lcoef.index_mut(bx4..bx4 + txw as usize), + &mut f.content.a[t.a].lcoef.index_mut(bx4..bx4 + txw as usize), &mut t.l.lcoef.index_mut(by4..by4 + txh as usize), ytx, bs, @@ -1396,10 +1397,10 @@ fn read_coef_tree( ); } CaseSet::<16, true>::many( - [&t.l.lcoef, &f.a[t.a].lcoef], + [&t.l.lcoef, &f.content.a[t.a].lcoef], [ - cmp::min(txh as c_int, f.bh - t.b.y) as usize, - cmp::min(txw as c_int, f.bw - t.b.x) as usize, + cmp::min(txh as c_int, f.content.bh - t.b.y) as usize, + cmp::min(txw as c_int, f.content.bw - t.b.x) as usize, ], [by4, bx4], |case, dir| { @@ -1415,11 +1416,12 @@ fn read_coef_tree( }); if t.frame_thread.pass == 1 { let cbi_idx = ts.frame_thread[1].cbi_idx.get_update(|i| i + 1); - f.frame_thread.cbi[cbi_idx as usize].set(CodedBlockInfo::new(eob as i16, txtp)); + f.content.frame_thread.cbi[cbi_idx as usize] + .set(CodedBlockInfo::new(eob as i16, txtp)); } } else { let cbi_idx = ts.frame_thread[0].cbi_idx.get_update(|i| i + 1); - let cbi = f.frame_thread.cbi[cbi_idx as usize].get(); + let cbi = f.content.frame_thread.cbi[cbi_idx as usize].get(); eob = cbi.eob().into(); txtp = cbi.txtp(); } @@ -1430,7 +1432,11 @@ fn read_coef_tree( CfSelect::Frame(offset) => { let len = cmp::min(t_dim.h as usize, 8) * 4 * cmp::min(t_dim.w as usize, 8) * 4; - &mut *f.frame_thread.cf.mut_slice_as((offset as usize.., ..len)) + &mut *f + .content + .frame_thread + .cf + .mut_slice_as((offset as usize.., ..len)) } CfSelect::Task => t.cf.select_mut::(), }; @@ -1443,7 +1449,8 @@ fn read_coef_tree( "dq", ); } - f.dsp.itx.itxfm_add[ytx as usize][txtp as usize].call::(y_dst, cf, eob, bd); + f.content.dsp.itx.itxfm_add[ytx as usize][txtp as usize] + .call::(y_dst, cf, eob, bd); if debug_block_info!(f, t.b) && DEBUG_B_PIXELS { hex_dump_pic::(y_dst, t_dim.w as usize * 4, t_dim.h as usize * 4, "recon"); } @@ -1459,8 +1466,8 @@ pub(crate) fn rav1d_read_coef_blocks( bs: BlockSize, b: &Av1Block, ) { - let ss_ver = (f.cur.p.layout == Rav1dPixelLayout::I420) as u8; - let ss_hor = (f.cur.p.layout != Rav1dPixelLayout::I444) as u8; + let ss_ver = (f.content.cur.p.layout == Rav1dPixelLayout::I420) as u8; + let ss_hor = (f.content.cur.p.layout != Rav1dPixelLayout::I444) as u8; let bx4 = t.b.x as usize & 31; let by4 = t.b.y as usize & 31; let cbx4 = bx4 >> ss_hor; @@ -1470,13 +1477,13 @@ pub(crate) fn rav1d_read_coef_blocks( let bh4 = b_dim[1]; let cbw4 = bw4 + ss_hor >> ss_hor; let cbh4 = bh4 + ss_ver >> ss_ver; - let has_chroma = f.cur.p.layout != Rav1dPixelLayout::I400 + let has_chroma = f.content.cur.p.layout != Rav1dPixelLayout::I400 && (bw4 > ss_hor || t.b.x & 1 != 0) && (bh4 > ss_ver || t.b.y & 1 != 0); if b.skip != 0 { CaseSet::<32, false>::many( - [&t.l, &f.a[t.a]], + [&t.l, &f.content.a[t.a]], [bh4 as usize, bw4 as usize], [by4, bx4], |case, dir| { @@ -1485,7 +1492,7 @@ pub(crate) fn rav1d_read_coef_blocks( ); if has_chroma { CaseSet::<32, false>::many( - [&t.l, &f.a[t.a]], + [&t.l, &f.content.a[t.a]], [cbh4 as usize, cbw4 as usize], [cby4, cbx4], |case, dir| { @@ -1498,9 +1505,9 @@ pub(crate) fn rav1d_read_coef_blocks( return; } - let ts = &f.ts[t.ts]; - let w4 = cmp::min(bw4 as c_int, f.bw - t.b.x) as u8; - let h4 = cmp::min(bh4 as c_int, f.bh - t.b.y) as u8; + let ts = &f.content.ts[t.ts]; + let w4 = cmp::min(bw4 as c_int, f.content.bw - t.b.x) as u8; + let h4 = cmp::min(bh4 as c_int, f.content.bh - t.b.y) as u8; let cw4 = w4 + ss_hor >> ss_hor; let ch4 = h4 + ss_ver >> ss_ver; assert!(t.frame_thread.pass == 1); @@ -1562,7 +1569,7 @@ pub(crate) fn rav1d_read_coef_blocks( debug_block_info!(f, t.b), &mut t.scratch, &mut t.cf, - &mut f.a[t.a].lcoef.index_mut((a_start.., ..a_len)), + &mut f.content.a[t.a].lcoef.index_mut((a_start.., ..a_len)), &mut t.l.lcoef.index_mut((l_start.., ..l_len)), intra.tx, bs, @@ -1579,13 +1586,13 @@ pub(crate) fn rav1d_read_coef_blocks( ); } let cbi_idx = ts.frame_thread[1].cbi_idx.get_update(|i| i + 1); - f.frame_thread.cbi[cbi_idx as usize] + f.content.frame_thread.cbi[cbi_idx as usize] .set(CodedBlockInfo::new(eob as i16, txtp)); CaseSet::<16, true>::many( - [&t.l.lcoef, &f.a[t.a].lcoef], + [&t.l.lcoef, &f.content.a[t.a].lcoef], [ - cmp::min(t_dim.h as i32, f.bh - t.b.y) as usize, - cmp::min(t_dim.w as i32, f.bw - t.b.x) as usize, + cmp::min(t_dim.h as i32, f.content.bh - t.b.y) as usize, + cmp::min(t_dim.w as i32, f.content.bw - t.b.x) as usize, ], [by4 + y as usize, bx4 + x as usize], |case, dir| { @@ -1631,7 +1638,7 @@ pub(crate) fn rav1d_read_coef_blocks( }; let a_start = cbx4 + x as usize; let a_len = uv_t_dim.w as usize; - let a_ccoef = &f.a[t.a].ccoef[pl]; + let a_ccoef = &f.content.a[t.a].ccoef[pl]; let l_start = cby4 + y as usize; let l_len = uv_t_dim.h as usize; let l_ccoef = &t.l.ccoef[pl]; @@ -1660,7 +1667,7 @@ pub(crate) fn rav1d_read_coef_blocks( ); } let cbi_idx = ts.frame_thread[1].cbi_idx.get_update(|i| i + 1); - f.frame_thread.cbi[cbi_idx as usize] + f.content.frame_thread.cbi[cbi_idx as usize] .set(CodedBlockInfo::new(eob as i16, txtp)); ts.frame_thread[1] .cf @@ -1670,11 +1677,11 @@ pub(crate) fn rav1d_read_coef_blocks( [ cmp::min( uv_t_dim.h as i32, - f.bh - t.b.y + ss_ver as c_int >> ss_ver, + f.content.bh - t.b.y + ss_ver as c_int >> ss_ver, ) as usize, cmp::min( uv_t_dim.w as i32, - f.bw - t.b.x + ss_hor as c_int >> ss_hor, + f.content.bw - t.b.x + ss_hor as c_int >> ss_hor, ) as usize, ], [cby4 + y as usize, cbx4 as usize + x as usize], @@ -1721,12 +1728,12 @@ fn mc( refidx: usize, filter_2d: Filter2d, ) -> Result<(), ()> { - let bd = BD::from_c(f.bitdepth_max); + let bd = BD::from_c(f.content.bitdepth_max); let ref_data = &refp.p.data.as_ref().unwrap().data; - let cur_data = &f.cur.data.as_ref().unwrap().data; + let cur_data = &f.content.cur.data.as_ref().unwrap().data; - let ss_ver = (pl != 0 && f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (pl != 0 && f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + let ss_ver = (pl != 0 && f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (pl != 0 && f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; let h_mul = 4 >> ss_hor; let v_mul = 4 >> ss_ver; let mvx = mv.x as c_int; @@ -1734,18 +1741,18 @@ fn mc( let mx = mvx & 15 >> (ss_hor == 0) as c_int; let my = mvy & 15 >> (ss_ver == 0) as c_int; - if refp.p.p.w == f.cur.p.w && refp.p.p.h == f.cur.p.h { + if refp.p.p.w == f.content.cur.p.w && refp.p.p.h == f.content.cur.p.h { let dx = bx * h_mul + (mvx >> 3 + ss_hor); let dy = by * v_mul + (mvy >> 3 + ss_ver); let w; let h; if !ref_data[0].ref_eq(&cur_data[0]) { - w = f.cur.p.w + ss_hor >> ss_hor; - h = f.cur.p.h + ss_ver >> ss_ver; + w = f.content.cur.p.w + ss_hor >> ss_hor; + h = f.content.cur.p.h + ss_ver >> ss_ver; } else { - w = f.bw * 4 >> ss_hor; - h = f.bh * 4 >> ss_ver; + w = f.content.bw * 4 >> ss_hor; + h = f.content.bh * 4 >> ss_ver; } let r#ref = if dx < (mx != 0) as c_int * 3 || dy < (my != 0) as c_int * 3 @@ -1753,7 +1760,7 @@ fn mc( || dy + bh4 * v_mul + (my != 0) as c_int * 4 > h { let emu_edge_buf = emu_edge.buf_mut::(); - f.dsp.mc.emu_edge.call::( + f.content.dsp.mc.emu_edge.call::( (bw4 * h_mul + (mx != 0) as c_int * 7) as intptr_t, (bh4 * v_mul + (my != 0) as c_int * 7) as intptr_t, w as intptr_t, @@ -1780,14 +1787,14 @@ fn mc( let my = my << (ss_ver == 0) as u8; match dst { MaybeTempPixels::NonTemp { dst } => { - f.dsp.mc.mc[filter_2d].call::(dst, r#ref, w, h, mx, my, bd); + f.content.dsp.mc.mc[filter_2d].call::(dst, r#ref, w, h, mx, my, bd); } MaybeTempPixels::Temp { tmp, tmp_stride: _ } => { - f.dsp.mc.mct[filter_2d].call::(tmp, r#ref, w, h, mx, my, bd); + f.content.dsp.mc.mct[filter_2d].call::(tmp, r#ref, w, h, mx, my, bd); } } } else { - assert!(!ptr::eq(refp, &f.sr_cur)); + assert!(!ptr::eq(refp, &f.content.sr_cur)); let orig_pos_y = (by * v_mul << 4) + mvy * (1 << (ss_ver == 0) as c_int); let orig_pos_x = (bx * h_mul << 4) + mvx * (1 << (ss_hor == 0) as c_int); @@ -1797,12 +1804,12 @@ fn mc( apply_sign64(((tmp.abs() + 128) >> 8) as c_int, tmp) + 32 }; - let pos_x = scale_mv(orig_pos_x, f.svc[refidx][0].scale); - let pos_y = scale_mv(orig_pos_y, f.svc[refidx][1].scale); + let pos_x = scale_mv(orig_pos_x, f.content.svc[refidx][0].scale); + let pos_y = scale_mv(orig_pos_y, f.content.svc[refidx][1].scale); let left = pos_x >> 10; let top = pos_y >> 10; - let right = (pos_x + (bw4 * h_mul - 1) * (*f).svc[refidx][0].step >> 10) + 1; - let bottom = (pos_y + (bh4 * v_mul - 1) * (*f).svc[refidx][1].step >> 10) + 1; + let right = (pos_x + (bw4 * h_mul - 1) * (*f).content.svc[refidx][0].step >> 10) + 1; + let bottom = (pos_y + (bh4 * v_mul - 1) * (*f).content.svc[refidx][1].step >> 10) + 1; if debug_block_info!(f, b) { println!( @@ -1810,12 +1817,12 @@ fn mc( left, top, orig_pos_x, - f.svc[refidx][0].scale, + f.content.svc[refidx][0].scale, refidx, right - left, bottom - top, - f.svc[refidx][0].step, - f.svc[refidx][1].step, + f.content.svc[refidx][0].step, + f.content.svc[refidx][1].step, ); } @@ -1823,7 +1830,7 @@ fn mc( let h = refp.p.p.h + ss_ver >> ss_ver; let r#ref = if left < 3 || top < 3 || right + 4 > w || bottom + 4 > h { let emu_edge_buf = emu_edge.buf_mut::(); - f.dsp.mc.emu_edge.call::( + f.content.dsp.mc.emu_edge.call::( (right - left + 7) as intptr_t, (bottom - top + 7) as intptr_t, w as intptr_t, @@ -1851,14 +1858,16 @@ fn mc( let h = bh4 * v_mul; let mx = pos_x & 0x3ff; let my = pos_y & 0x3ff; - let dx = f.svc[refidx][0].step; - let dy = f.svc[refidx][1].step; + let dx = f.content.svc[refidx][0].step; + let dy = f.content.svc[refidx][1].step; match dst { MaybeTempPixels::NonTemp { dst } => { - f.dsp.mc.mc_scaled[filter_2d].call::(dst, r#ref, w, h, mx, my, dx, dy, bd); + f.content.dsp.mc.mc_scaled[filter_2d] + .call::(dst, r#ref, w, h, mx, my, dx, dy, bd); } MaybeTempPixels::Temp { tmp, tmp_stride: _ } => { - f.dsp.mc.mct_scaled[filter_2d].call::(tmp, r#ref, w, h, mx, my, dx, dy, bd); + f.content.dsp.mc.mct_scaled[filter_2d] + .call::(tmp, r#ref, w, h, mx, my, dx, dy, bd); } } } @@ -1881,11 +1890,11 @@ fn obmc( let r = &t.rt.r[(t.b.y as usize & 31) + 5 - 1..]; let scratch = t.scratch.inter_mut(); let lap = scratch.lap_inter.lap_mut::(); - let ss_ver = (pl != 0 && f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (pl != 0 && f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + let ss_ver = (pl != 0 && f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (pl != 0 && f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; let h_mul = 4 >> ss_hor; let v_mul = 4 >> ss_ver; - let ts = &f.ts[t.ts]; + let ts = &f.content.ts[t.ts]; if t.b.y > ts.tiling.row_start && (pl == 0 || b_dim[0] as c_int * h_mul + b_dim[1] as c_int * v_mul >= 16) @@ -1894,7 +1903,7 @@ fn obmc( let mut x = 0; while x < w4 && i < cmp::min(b_dim[2], 4) { // only odd blocks are considered for overlap handling, hence +1 - let a_r = *f.rf.r.index(r[0] + t.b.x as usize + x as usize + 1); + let a_r = *f.content.rf.r.index(r[0] + t.b.x as usize + x as usize + 1); let a_b_dim = a_r.bs.dimensions(); let step4 = clip(a_b_dim[0], 2, 16); @@ -1920,12 +1929,13 @@ fn obmc( t.b.y, pl, a_r.mv.mv[0], - &f.refp[a_r.r#ref.r#ref[0] as usize - 1], + &f.content.refp[a_r.r#ref.r#ref[0] as usize - 1], a_r.r#ref.r#ref[0] as usize - 1, - dav1d_filter_2d[*f.a[t.a].filter[1].index((bx4 + x + 1) as usize) as usize] - [*f.a[t.a].filter[0].index((bx4 + x + 1) as usize) as usize], + dav1d_filter_2d + [*f.content.a[t.a].filter[1].index((bx4 + x + 1) as usize) as usize] + [*f.content.a[t.a].filter[0].index((bx4 + x + 1) as usize) as usize], )?; - f.dsp.mc.blend_h.call::( + f.content.dsp.mc.blend_h.call::( dst + (x * h_mul) as usize, lap, h_mul * ow4 as c_int, @@ -1942,7 +1952,11 @@ fn obmc( let mut y = 0; while y < h4 && i < cmp::min(b_dim[3], 4) { // only odd blocks are considered for overlap handling, hence +1 - let l_r = *f.rf.r.index(r[y as usize + 1 + 1] + t.b.x as usize - 1); + let l_r = *f + .content + .rf + .r + .index(r[y as usize + 1 + 1] + t.b.x as usize - 1); let l_b_dim = l_r.bs.dimensions(); let step4 = clip(l_b_dim[1], 2, 16); @@ -1968,12 +1982,12 @@ fn obmc( t.b.y + y, pl, l_r.mv.mv[0], - &f.refp[l_r.r#ref.r#ref[0] as usize - 1], + &f.content.refp[l_r.r#ref.r#ref[0] as usize - 1], l_r.r#ref.r#ref[0] as usize - 1, dav1d_filter_2d[*t.l.filter[1].index((by4 + y + 1) as usize) as usize] [*t.l.filter[0].index((by4 + y + 1) as usize) as usize], )?; - f.dsp.mc.blend_v.call::( + f.content.dsp.mc.blend_v.call::( dst + (y * v_mul) as isize * dst.pixel_stride::(), lap, h_mul * ow4 as c_int, @@ -1998,11 +2012,11 @@ fn warp_affine( wmp: &Rav1dWarpedMotionParams, ) -> Result<(), ()> { let abcd = &wmp.abcd.get(); - let bd = BD::from_c(f.bitdepth_max); + let bd = BD::from_c(f.content.bitdepth_max); let ref_data = &refp.p.data.as_ref().unwrap().data; - let ss_ver = (pl != 0 && f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (pl != 0 && f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + let ss_ver = (pl != 0 && f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (pl != 0 && f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; let h_mul = 4 >> ss_hor; let v_mul = 4 >> ss_ver; assert!(b_dim[0] as c_int * h_mul & 7 == 0 && b_dim[1] as c_int * v_mul & 7 == 0); @@ -2030,7 +2044,7 @@ fn warp_affine( let r#ref = if dx < 3 || dx + 8 + 4 > width || dy < 3 || dy + 8 + 4 > height { let emu_edge_buf = emu_edge.buf_mut::(); - f.dsp.mc.emu_edge.call::( + f.content.dsp.mc.emu_edge.call::( 15, 15, width as intptr_t, @@ -2056,13 +2070,22 @@ fn warp_affine( ref mut tmp, tmp_stride, } => { - f.dsp - .mc - .warp8x8t - .call(&mut tmp[x..], tmp_stride, r#ref, abcd, mx, my, bd); + f.content.dsp.mc.warp8x8t.call( + &mut tmp[x..], + tmp_stride, + r#ref, + abcd, + mx, + my, + bd, + ); } MaybeTempPixels::NonTemp { dst } => { - f.dsp.mc.warp8x8.call(dst + x, r#ref, abcd, mx, my, bd); + f.content + .dsp + .mc + .warp8x8 + .call(dst + x, r#ref, abcd, mx, my, bd); } } } @@ -2088,24 +2111,24 @@ pub(crate) fn rav1d_recon_b_intra( b: &Av1Block, intra: &Av1BlockIntra, ) { - let bd = BD::from_c(f.bitdepth_max); - let cur_data = &f.cur.data.as_ref().unwrap().data; - let ts = &f.ts[t.ts]; + let bd = BD::from_c(f.content.bitdepth_max); + let cur_data = &f.content.cur.data.as_ref().unwrap().data; + let ts = &f.content.ts[t.ts]; let bx4 = t.b.x & 31; let by4 = t.b.y & 31; - let ss_ver = (f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + let ss_ver = (f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; let cbx4 = bx4 >> ss_hor; let cby4 = by4 >> ss_ver; let b_dim = bs.dimensions(); let bw4 = b_dim[0] as c_int; let bh4 = b_dim[1] as c_int; - let w4 = cmp::min(bw4, f.bw - t.b.x); - let h4 = cmp::min(bh4, f.bh - t.b.y); + let w4 = cmp::min(bw4, f.content.bw - t.b.x); + let h4 = cmp::min(bh4, f.content.bh - t.b.y); let cw4 = w4 + ss_hor >> ss_hor; let ch4 = h4 + ss_ver >> ss_ver; - let has_chroma = f.cur.p.layout != Rav1dPixelLayout::I400 + let has_chroma = f.content.cur.p.layout != Rav1dPixelLayout::I400 && (bw4 > ss_hor || t.b.x & 1 != 0) && (bh4 > ss_ver || t.b.y & 1 != 0); let t_dim = &dav1d_txfm_dimensions[intra.tx as usize]; @@ -2115,7 +2138,7 @@ pub(crate) fn rav1d_recon_b_intra( let cbw4 = bw4 + ss_hor >> ss_hor; let cbh4 = bh4 + ss_ver >> ss_ver; - let intra_edge_filter = f.seq_hdr.as_ref().unwrap().intra_edge_filter; + let intra_edge_filter = f.seq_hdr.intra_edge_filter; let intra_edge_filter_flag = (intra_edge_filter as c_int) << 10; for init_y in (0..h4).step_by(16) { @@ -2132,7 +2155,8 @@ pub(crate) fn rav1d_recon_b_intra( let frame_thread = &ts.frame_thread[p]; let len = (bw4 * bh4 * 8) as u32; let pal_idx = frame_thread.pal_idx.get_update(|i| i + len); - &*f.frame_thread + &*f.content + .frame_thread .pal_idx .index((pal_idx as usize.., ..len as usize)) } else { @@ -2141,13 +2165,15 @@ pub(crate) fn rav1d_recon_b_intra( let pal = if t.frame_thread.pass != 0 { let x = t.b.x as usize; let y = t.b.y as usize; - let index = - ((y >> 1) + (x & 1)) * (f.b4_stride as usize >> 1) + (x >> 1) + (y & 1); - &*f.frame_thread.pal.index::(index) + let index = ((y >> 1) + (x & 1)) * (f.content.b4_stride as usize >> 1) + + (x >> 1) + + (y & 1); + &*f.content.frame_thread.pal.index::(index) } else { scratch.interintra_edge_pal.pal.buf::() }; - f.dsp + f.content + .dsp .ipred .pal_pred .call::(y_dst, &pal[0], pal_idx, bw4 * 4, bh4 * 4); @@ -2156,7 +2182,7 @@ pub(crate) fn rav1d_recon_b_intra( } } - let intra_flags = sm_flag(&f.a[t.a], bx4 as usize) + let intra_flags = sm_flag(&f.content.a[t.a], bx4 as usize) | sm_flag(&mut t.l, by4 as usize) | intra_edge_filter_flag; let sb_has_tr = if (init_x + 16) < w4 { @@ -2200,11 +2226,11 @@ pub(crate) fn rav1d_recon_b_intra( !(x > init_x || (!sb_has_bl && y + t_dim.h as c_int >= sub_h4)), ), ]); - let top_sb_edge_slice = if t.b.y & f.sb_step - 1 == 0 { - let sby = t.b.y >> f.sb_shift; - let offset = f.ipred_edge_off as isize * 0 - + (f.sb128w * 128 * (sby - 1)) as isize; - Some((&f.ipred_edge, offset)) + let top_sb_edge_slice = if t.b.y & f.content.sb_step - 1 == 0 { + let sby = t.b.y >> f.content.sb_shift; + let offset = f.content.ipred_edge_off as isize * 0 + + (f.content.sb128w * 128 * (sby - 1)) as isize; + Some((&f.content.ipred_edge, offset)) } else { None }; @@ -2234,15 +2260,15 @@ pub(crate) fn rav1d_recon_b_intra( edge_offset, bd, ); - f.dsp.ipred.intra_pred[m as usize].call( + f.content.dsp.ipred.intra_pred[m as usize].call( y_dst, edge_array, edge_offset, t_dim.w as c_int * 4, t_dim.h as c_int * 4, angle | intra_flags, - 4 * f.bw - 4 * t.b.x, - 4 * f.bh - 4 * t.b.y, + 4 * f.content.bw - 4 * t.b.x, + 4 * f.content.bh - 4 * t.b.y, bd, ); @@ -2282,12 +2308,13 @@ pub(crate) fn rav1d_recon_b_intra( cmp::min(t_dim.h, 8) as u32 * 4 * cmp::min(t_dim.w, 8) as u32 * 4; let cf_idx = ts.frame_thread[p].cf.get_update(|i| i + len); cf_guard = f + .content .frame_thread .cf .mut_slice_as((cf_idx as usize.., ..len as usize)); cf = &mut *cf_guard; let cbi_idx = ts.frame_thread[p].cbi_idx.get_update(|i| i + 1); - let cbi = f.frame_thread.cbi[cbi_idx as usize].get(); + let cbi = f.content.frame_thread.cbi[cbi_idx as usize].get(); eob = cbi.eob().into(); txtp = cbi.txtp(); } else { @@ -2301,7 +2328,7 @@ pub(crate) fn rav1d_recon_b_intra( debug_block_info!(f, t.b), &mut t.scratch, &mut t.cf, - &mut f.a[t.a] + &mut f.content.a[t.a] .lcoef .index_mut(a_start..a_start + t_dim.w as usize), &mut t.l.lcoef.index_mut(l_start..l_start + t_dim.h as usize), @@ -2324,10 +2351,10 @@ pub(crate) fn rav1d_recon_b_intra( ); } CaseSet::<16, true>::many( - [&t.l, &f.a[t.a]], + [&t.l, &f.content.a[t.a]], [ - cmp::min(t_dim.h as i32, f.bh - t.b.y) as usize, - cmp::min(t_dim.w as i32, f.bw - t.b.x) as usize, + cmp::min(t_dim.h as i32, f.content.bh - t.b.y) as usize, + cmp::min(t_dim.w as i32, f.content.bw - t.b.x) as usize, ], [(by4 + y) as usize, (bx4 + x) as usize], |case, dir| { @@ -2345,7 +2372,7 @@ pub(crate) fn rav1d_recon_b_intra( "dq", ); } - f.dsp.itx.itxfm_add[intra.tx as usize][txtp as usize] + f.content.dsp.itx.itxfm_add[intra.tx as usize][txtp as usize] .call::(y_dst, cf, eob, bd); if debug_block_info!(f, t.b) && DEBUG_B_PIXELS { hex_dump_pic::( @@ -2358,7 +2385,7 @@ pub(crate) fn rav1d_recon_b_intra( } } else if t.frame_thread.pass == 0 { CaseSet::<16, false>::many( - [&t.l, &f.a[t.a]], + [&t.l, &f.content.a[t.a]], [t_dim.h as usize, t_dim.w as usize], [(by4 + y) as usize, (bx4 + x) as usize], |case, dir| { @@ -2380,7 +2407,7 @@ pub(crate) fn rav1d_recon_b_intra( continue; } - let stride = f.cur.stride[1]; + let stride = f.content.cur.stride[1]; if intra.uv_mode == CFL_PRED { assert!(init_x == 0 && init_y == 0); @@ -2397,8 +2424,8 @@ pub(crate) fn rav1d_recon_b_intra( let furthest_r = (cw4 << ss_hor) + t_dim.w as c_int - 1 & !(t_dim.w as c_int - 1); let furthest_b = (ch4 << ss_ver) + t_dim.h as c_int - 1 & !(t_dim.h as c_int - 1); - let layout = f.cur.p.layout.try_into().unwrap(); - f.dsp.ipred.cfl_ac[layout].call::( + let layout = f.content.cur.p.layout.try_into().unwrap(); + f.content.dsp.ipred.cfl_ac[layout].call::( ac, y_src, cbw4 - (furthest_r >> ss_hor), @@ -2411,11 +2438,11 @@ pub(crate) fn rav1d_recon_b_intra( continue; } let mut angle = 0; - let top_sb_edge_slice = if t.b.y & !ss_ver & f.sb_step - 1 == 0 { - let sby = t.b.y >> f.sb_shift; - let offset = (f.ipred_edge_off * (pl + 1)) as isize - + (f.sb128w * 128 * (sby - 1)) as isize; - Some((&f.ipred_edge, offset)) + let top_sb_edge_slice = if t.b.y & !ss_ver & f.content.sb_step - 1 == 0 { + let sby = t.b.y >> f.content.sb_shift; + let offset = (f.content.ipred_edge_off * (pl + 1)) as isize + + (f.content.sb128w * 128 * (sby - 1)) as isize; + Some((&f.content.ipred_edge, offset)) } else { None }; @@ -2448,7 +2475,7 @@ pub(crate) fn rav1d_recon_b_intra( edge_offset, bd, ); - f.dsp.ipred.cfl_pred[m as usize].call( + f.content.dsp.ipred.cfl_pred[m as usize].call( uv_dst, edge_array, edge_offset, @@ -2474,18 +2501,20 @@ pub(crate) fn rav1d_recon_b_intra( } else if intra.pal_sz[1] != 0 { let uv_dstoff = 4 * ((t.b.x >> ss_hor) as isize - + (t.b.y >> ss_ver) as isize * BD::pxstride(f.cur.stride[1])); + + (t.b.y >> ss_ver) as isize * BD::pxstride(f.content.cur.stride[1])); let (pal, pal_idx) = if t.frame_thread.pass != 0 { let p = (t.frame_thread.pass & 1) as usize; let x = t.b.x as usize; let y = t.b.y as usize; - let index = - ((y >> 1) + (x & 1)) * (f.b4_stride as usize >> 1) + (x >> 1) + (y & 1); + let index = ((y >> 1) + (x & 1)) * (f.content.b4_stride as usize >> 1) + + (x >> 1) + + (y & 1); let len = (cbw4 * cbh4 * 8) as u32; let pal_idx_offset = ts.frame_thread[p].pal_idx.get_update(|i| i + len); ( - &*f.frame_thread.pal.index::(index), - &*f.frame_thread + &*f.content.frame_thread.pal.index::(index), + &*f.content + .frame_thread .pal_idx .index((pal_idx_offset as usize.., ..len as usize)), ) @@ -2499,10 +2528,13 @@ pub(crate) fn rav1d_recon_b_intra( for pl in 1..3 { let uv = cur_data[pl].with_offset::() + uv_dstoff; - f.dsp - .ipred - .pal_pred - .call::(uv, &pal[pl], pal_idx, cbw4 * 4, cbh4 * 4); + f.content.dsp.ipred.pal_pred.call::( + uv, + &pal[pl], + pal_idx, + cbw4 * 4, + cbh4 * 4, + ); if debug_block_info!(f, t.b) && DEBUG_B_PIXELS { hex_dump_pic::( uv, @@ -2515,20 +2547,20 @@ pub(crate) fn rav1d_recon_b_intra( } let sm_uv_fl = - sm_uv_flag(&f.a[t.a], cbx4 as usize) | sm_uv_flag(&mut t.l, cby4 as usize); + sm_uv_flag(&f.content.a[t.a], cbx4 as usize) | sm_uv_flag(&mut t.l, cby4 as usize); let uv_sb_has_tr = if init_x + 16 >> ss_hor < cw4 { true } else if init_y != 0 { false } else { - intra_edge_flags.contains(EdgeFlags::I420_TOP_HAS_RIGHT >> f.cur.p.layout) + intra_edge_flags.contains(EdgeFlags::I420_TOP_HAS_RIGHT >> f.content.cur.p.layout) }; let uv_sb_has_bl = if init_x != 0 { false } else if init_y + 16 >> ss_ver < ch4 { true } else { - intra_edge_flags.contains(EdgeFlags::I420_LEFT_HAS_BOTTOM >> f.cur.p.layout) + intra_edge_flags.contains(EdgeFlags::I420_LEFT_HAS_BOTTOM >> f.content.cur.p.layout) }; let sub_cw4 = cmp::min(cw4, init_x + 16 >> ss_hor); for pl in 0..2 { @@ -2564,11 +2596,12 @@ pub(crate) fn rav1d_recon_b_intra( !(x > init_x >> ss_hor || !uv_sb_has_bl && y + uv_t_dim.h as c_int >= sub_ch4), ); - let top_sb_edge_slice = if t.b.y & !ss_ver & f.sb_step - 1 == 0 { - let sby = t.b.y >> f.sb_shift; - let offset = (f.ipred_edge_off * (1 + pl)) as isize - + (f.sb128w * 128 * (sby - 1)) as isize; - Some((&f.ipred_edge, offset)) + let top_sb_edge_slice = if t.b.y & !ss_ver & f.content.sb_step - 1 == 0 + { + let sby = t.b.y >> f.content.sb_shift; + let offset = (f.content.ipred_edge_off * (1 + pl)) as isize + + (f.content.sb128w * 128 * (sby - 1)) as isize; + Some((&f.content.ipred_edge, offset)) } else { None }; @@ -2608,15 +2641,15 @@ pub(crate) fn rav1d_recon_b_intra( bd, ); angle |= intra_edge_filter_flag; - f.dsp.ipred.intra_pred[m as usize].call( + f.content.dsp.ipred.intra_pred[m as usize].call( uv_dst, edge_array, edge_offset, uv_t_dim.w as c_int * 4, uv_t_dim.h as c_int * 4, angle | sm_uv_fl, - 4 * f.bw + ss_hor - 4 * (t.b.x & !ss_hor) >> ss_hor, - 4 * f.bh + ss_ver - 4 * (t.b.y & !ss_ver) >> ss_ver, + 4 * f.content.bw + ss_hor - 4 * (t.b.x & !ss_hor) >> ss_hor, + 4 * f.content.bh + ss_ver - 4 * (t.b.y & !ss_ver) >> ss_ver, bd, ); if debug_block_info!(f, t.b) && DEBUG_B_PIXELS { @@ -2654,18 +2687,19 @@ pub(crate) fn rav1d_recon_b_intra( let len = uv_t_dim.w as u32 * 4 * uv_t_dim.h as u32 * 4; let cf_idx = ts.frame_thread[p].cf.get_update(|i| i + len); cf_guard = f + .content .frame_thread .cf .mut_slice_as((cf_idx as usize.., ..len as usize)); cf = &mut *cf_guard; let cbi_idx = ts.frame_thread[p].cbi_idx.get_update(|i| i + 1); - let cbi = f.frame_thread.cbi[cbi_idx as usize].get(); + let cbi = f.content.frame_thread.cbi[cbi_idx as usize].get(); eob = cbi.eob().into(); txtp = cbi.txtp(); } else { let mut cf_ctx: u8 = 0; let a_start = (cbx4 + x) as usize; - let a_ccoef = &f.a[t.a].ccoef[pl]; + let a_ccoef = &f.content.a[t.a].ccoef[pl]; let l_start = (cby4 + y) as usize; let l_ccoef = &t.l.ccoef[pl]; eob = decode_coefs::( @@ -2701,10 +2735,14 @@ pub(crate) fn rav1d_recon_b_intra( CaseSet::<16, true>::many( [l_ccoef, a_ccoef], [ - cmp::min(uv_t_dim.h as i32, f.bh - t.b.y + ss_ver >> ss_ver) - as usize, - cmp::min(uv_t_dim.w as i32, f.bw - t.b.x + ss_hor >> ss_hor) - as usize, + cmp::min( + uv_t_dim.h as i32, + f.content.bh - t.b.y + ss_ver >> ss_ver, + ) as usize, + cmp::min( + uv_t_dim.w as i32, + f.content.bw - t.b.x + ss_hor >> ss_hor, + ) as usize, ], [(cby4 + y) as usize, (cbx4 + x) as usize], |case, dir| { @@ -2722,7 +2760,7 @@ pub(crate) fn rav1d_recon_b_intra( "dq", ); } - f.dsp.itx.itxfm_add[b.uvtx as usize][txtp as usize] + f.content.dsp.itx.itxfm_add[b.uvtx as usize][txtp as usize] .call::(uv_dst, cf, eob, bd); if debug_block_info!(f, t.b) && DEBUG_B_PIXELS { hex_dump_pic::( @@ -2735,7 +2773,7 @@ pub(crate) fn rav1d_recon_b_intra( } } else if t.frame_thread.pass == 0 { CaseSet::<16, false>::many( - [&t.l, &f.a[t.a]], + [&t.l, &f.content.a[t.a]], [uv_t_dim.h as usize, uv_t_dim.w as usize], [(cby4 + y) as usize, (cbx4 + x) as usize], |case, dir| { @@ -2765,30 +2803,31 @@ pub(crate) fn rav1d_recon_b_inter( b: &Av1Block, inter: &Av1BlockInter, ) -> Result<(), ()> { - let bd = BD::from_c(f.bitdepth_max); - let cur_data = &f.cur.data.as_ref().unwrap().data; + let bd = BD::from_c(f.content.bitdepth_max); + let cur_data = &f.content.cur.data.as_ref().unwrap().data; - let ts = &f.ts[t.ts]; + let ts = &f.content.ts[t.ts]; let bx4 = t.b.x & 31; let by4 = t.b.y & 31; - let ss_ver = (f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + let ss_ver = (f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; let cbx4 = bx4 >> ss_hor; let cby4 = by4 >> ss_ver; let b_dim = bs.dimensions(); let bw4 = b_dim[0] as c_int; let bh4 = b_dim[1] as c_int; - let w4 = cmp::min(bw4, f.bw - t.b.x); - let h4 = cmp::min(bh4, f.bh - t.b.y); - let has_chroma = f.cur.p.layout != Rav1dPixelLayout::I400 + let w4 = cmp::min(bw4, f.content.bw - t.b.x); + let h4 = cmp::min(bh4, f.content.bh - t.b.y); + let has_chroma = f.content.cur.p.layout != Rav1dPixelLayout::I400 && (bw4 > ss_hor || t.b.x & 1 != 0) && (bh4 > ss_ver || t.b.y & 1 != 0); - let chr_layout_idx = if f.cur.p.layout == Rav1dPixelLayout::I400 { + let chr_layout_idx = if f.content.cur.p.layout == Rav1dPixelLayout::I400 { Rav1dPixelLayout::I400 } else { - Rav1dPixelLayout::I444 - f.cur.p.layout + Rav1dPixelLayout::I444 - f.content.cur.p.layout } as usize; let chr_layout_idx_w_mask = f + .content .cur .p .layout @@ -2802,8 +2841,9 @@ pub(crate) fn rav1d_recon_b_inter( let mut y_dst = y_dst.with_offset::() + 4 * (t.b.y as isize * y_dst.pixel_stride::() + t.b.x as isize); let uvdstoff = 4 - * ((t.b.x >> ss_hor) as isize + (t.b.y >> ss_ver) as isize * BD::pxstride(f.cur.stride[1])); - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + * ((t.b.x >> ss_hor) as isize + + (t.b.y >> ss_ver) as isize * BD::pxstride(f.content.cur.stride[1])); + let frame_hdr = &f.frame_hdr; if frame_hdr.frame_type.is_key_or_intra() { // intrabc assert!(!frame_hdr.size.super_res.enabled); @@ -2819,7 +2859,7 @@ pub(crate) fn rav1d_recon_b_inter( t.b.y, 0, inter.nd.one_d.mv[0], - &f.sr_cur, + &f.content.sr_cur, 0, // unused Filter2d::Bilinear, )?; @@ -2838,7 +2878,7 @@ pub(crate) fn rav1d_recon_b_inter( t.b.y & !ss_ver, pl, inter.nd.one_d.mv[0], - &f.sr_cur, + &f.content.sr_cur, 0, // unused Filter2d::Bilinear, )?; @@ -2854,10 +2894,10 @@ pub(crate) fn rav1d_recon_b_inter( let seg_mask = &mut scratch_inter.seg_mask; for i in 0..2 { - let refp = &f.refp[inter.r#ref[i] as usize]; + let refp = &f.content.refp[inter.r#ref[i] as usize]; if inter.inter_mode == GLOBALMV_GLOBALMV - && f.gmv_warp_allowed[inter.r#ref[i] as usize] != 0 + && f.content.gmv_warp_allowed[inter.r#ref[i] as usize] != 0 { warp_affine::( f, @@ -2897,15 +2937,16 @@ pub(crate) fn rav1d_recon_b_inter( let mut mask = &[][..]; match comp_inter_type { CompInterType::Avg => { - f.dsp + f.content + .dsp .mc .avg .call::(y_dst, &tmp[0], &tmp[1], bw4 * 4, bh4 * 4, bd); } CompInterType::WeightedAvg => { - jnt_weight = - f.jnt_weights[inter.r#ref[0] as usize][inter.r#ref[1] as usize] as c_int; - f.dsp.mc.w_avg.call::( + jnt_weight = f.content.jnt_weights[inter.r#ref[0] as usize][inter.r#ref[1] as usize] + as c_int; + f.content.dsp.mc.w_avg.call::( y_dst, &tmp[0], &tmp[1], @@ -2916,7 +2957,7 @@ pub(crate) fn rav1d_recon_b_inter( ); } CompInterType::Seg => { - f.dsp.mc.w_mask[chr_layout_idx_w_mask].call( + f.content.dsp.mc.w_mask[chr_layout_idx_w_mask].call( y_dst, &tmp[inter.nd.one_d.mask_sign() as usize], &tmp[!inter.nd.one_d.mask_sign() as usize], @@ -2930,7 +2971,7 @@ pub(crate) fn rav1d_recon_b_inter( } CompInterType::Wedge => { mask = dav1d_wedge_masks[bs as usize][0][0][inter.nd.one_d.wedge_idx as usize]; - f.dsp.mc.mask.call::( + f.content.dsp.mc.mask.call::( y_dst, &tmp[inter.nd.one_d.mask_sign() as usize], &tmp[!inter.nd.one_d.mask_sign() as usize], @@ -2951,10 +2992,10 @@ pub(crate) fn rav1d_recon_b_inter( if has_chroma { for pl in 0..2 { for i in 0..2 { - let refp = &f.refp[inter.r#ref[i] as usize]; + let refp = &f.content.refp[inter.r#ref[i] as usize]; if inter.inter_mode == GLOBALMV_GLOBALMV && cmp::min(cbw4, cbh4) > 1 - && f.gmv_warp_allowed[inter.r#ref[i] as usize] != 0 + && f.content.gmv_warp_allowed[inter.r#ref[i] as usize] != 0 { warp_affine::( f, @@ -2994,7 +3035,7 @@ pub(crate) fn rav1d_recon_b_inter( let uv_dst = cur_data[1 + pl].with_offset::() + uvdstoff; match comp_inter_type { CompInterType::Avg => { - f.dsp.mc.avg.call::( + f.content.dsp.mc.avg.call::( uv_dst, &tmp[0], &tmp[1], @@ -3004,7 +3045,7 @@ pub(crate) fn rav1d_recon_b_inter( ); } CompInterType::WeightedAvg => { - f.dsp.mc.w_avg.call::( + f.content.dsp.mc.w_avg.call::( uv_dst, &tmp[0], &tmp[1], @@ -3015,7 +3056,7 @@ pub(crate) fn rav1d_recon_b_inter( ); } CompInterType::Seg | CompInterType::Wedge => { - f.dsp.mc.mask.call::( + f.content.dsp.mc.mask.call::( uv_dst, &tmp[inter.nd.one_d.mask_sign() as usize], &tmp[!inter.nd.one_d.mask_sign() as usize], @@ -3029,11 +3070,12 @@ pub(crate) fn rav1d_recon_b_inter( } } } else { - let refp = &f.refp[inter.r#ref[0] as usize]; + let refp = &f.content.refp[inter.r#ref[0] as usize]; let filter_2d = inter.filter2d; if cmp::min(bw4, bh4) > 1 - && (inter.inter_mode == GLOBALMV && f.gmv_warp_allowed[inter.r#ref[0] as usize] != 0 + && (inter.inter_mode == GLOBALMV + && f.content.gmv_warp_allowed[inter.r#ref[0] as usize] != 0 || inter.motion_mode == MotionMode::Warp && t.warpmv.r#type > Rav1dWarpedMotionType::Translation) { @@ -3080,11 +3122,11 @@ pub(crate) fn rav1d_recon_b_inter( mode => mode as IntraPredMode, }; let mut angle = 0; - let top_sb_edge_slice = if t.b.y & f.sb_step - 1 == 0 { - let sby = t.b.y >> f.sb_shift; - let offset = - (f.ipred_edge_off * 0) as isize + (f.sb128w * 128 * (sby - 1)) as isize; - Some((&f.ipred_edge, offset)) + let top_sb_edge_slice = if t.b.y & f.content.sb_step - 1 == 0 { + let sby = t.b.y >> f.content.sb_shift; + let offset = (f.content.ipred_edge_off * 0) as isize + + (f.content.sb128w * 128 * (sby - 1)) as isize; + Some((&f.content.ipred_edge, offset)) } else { None }; @@ -3108,7 +3150,7 @@ pub(crate) fn rav1d_recon_b_inter( bd, ); let tmp = interintra_edge_pal.interintra.buf_mut::(); - f.dsp.ipred.intra_pred[m as usize].call( + f.content.dsp.ipred.intra_pred[m as usize].call( Rav1dPictureDataComponentOffset { data: &Rav1dPictureDataComponent::wrap_buf::(tmp, 4 * bw4 as usize), offset: 0, @@ -3130,7 +3172,8 @@ pub(crate) fn rav1d_recon_b_inter( dav1d_wedge_masks[bs as usize][0][0][inter.nd.one_d.wedge_idx as usize] } }; - f.dsp + f.content + .dsp .mc .blend .call::(y_dst, tmp, bw4 * 4, bh4 * 4, ii_mask); @@ -3143,13 +3186,13 @@ pub(crate) 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.index(r[1] + t.b.x as usize - 1).r#ref.r#ref[0] > 0; + is_sub8x8 &= f.content.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.index(r[0] + t.b.x as usize).r#ref.r#ref[0] > 0; + is_sub8x8 &= f.content.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.index(r[0] + t.b.x as usize - 1).r#ref.r#ref[0] > 0; + is_sub8x8 &= f.content.rf.r.index(r[0] + t.b.x as usize - 1).r#ref.r#ref[0] > 0; } r } else { @@ -3162,7 +3205,7 @@ pub(crate) 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.index(r[0] + t.b.x as usize - 1); + let r = *f.content.rf.r.index(r[0] + t.b.x as usize - 1); mc::( f, &mut t.scratch.inter_mut().emu_edge, @@ -3176,15 +3219,16 @@ pub(crate) fn rav1d_recon_b_inter( t.b.y - 1, 1 + pl, r.mv.mv[0], - &f.refp[r.r#ref.r#ref[0] as usize - 1], + &f.content.refp[r.r#ref.r#ref[0] as usize - 1], r.r#ref.r#ref[0] as usize - 1, if t.frame_thread.pass != 2 { t.tl_4x4_filter } else { - f.frame_thread + f.content + .frame_thread .b .index( - (t.b.y as usize - 1) * f.b4_stride as usize + (t.b.y as usize - 1) * f.content.b4_stride as usize + t.b.x as usize - 1, ) @@ -3193,7 +3237,7 @@ pub(crate) fn rav1d_recon_b_inter( }, )?; } - v_off = 2 * BD::pxstride(f.cur.stride[1]); + v_off = 2 * BD::pxstride(f.content.cur.stride[1]); h_off = 2; } if bw4 == 1 { @@ -3201,7 +3245,7 @@ pub(crate) fn rav1d_recon_b_inter( [*t.l.filter[1].index(by4 as usize) as usize] [*t.l.filter[0].index(by4 as usize) as usize]; for pl in 0..2 { - let r = *f.rf.r.index(r[1] + t.b.x as usize - 1); + let r = *f.content.rf.r.index(r[1] + t.b.x as usize - 1); mc::( f, &mut t.scratch.inter_mut().emu_edge, @@ -3215,15 +3259,18 @@ pub(crate) fn rav1d_recon_b_inter( t.b.y, 1 + pl, r.mv.mv[0], - &f.refp[r.r#ref.r#ref[0] as usize - 1], + &f.content.refp[r.r#ref.r#ref[0] as usize - 1], r.r#ref.r#ref[0] as usize - 1, if t.frame_thread.pass != 2 { left_filter_2d } else { - f.frame_thread + f.content + .frame_thread .b .index( - t.b.y as usize * f.b4_stride as usize + t.b.x as usize - 1, + t.b.y as usize * f.content.b4_stride as usize + + t.b.x as usize + - 1, ) .ii .filter2d() @@ -3234,10 +3281,10 @@ pub(crate) fn rav1d_recon_b_inter( } if bh4 == ss_ver { let top_filter_2d = dav1d_filter_2d - [*f.a[t.a].filter[1].index(bx4 as usize) as usize] - [*f.a[t.a].filter[0].index(bx4 as usize) as usize]; + [*f.content.a[t.a].filter[1].index(bx4 as usize) as usize] + [*f.content.a[t.a].filter[0].index(bx4 as usize) as usize]; for pl in 0..2 { - let r = *f.rf.r.index(r[0] + t.b.x as usize); + let r = *f.content.rf.r.index(r[0] + t.b.x as usize); mc::( f, &mut t.scratch.inter_mut().emu_edge, @@ -3251,15 +3298,16 @@ pub(crate) fn rav1d_recon_b_inter( t.b.y - 1, 1 + pl, r.mv.mv[0], - &f.refp[r.r#ref.r#ref[0] as usize - 1], + &f.content.refp[r.r#ref.r#ref[0] as usize - 1], r.r#ref.r#ref[0] as usize - 1, if t.frame_thread.pass != 2 { top_filter_2d } else { - f.frame_thread + f.content + .frame_thread .b .index( - (t.b.y as usize - 1) * f.b4_stride as usize + (t.b.y as usize - 1) * f.content.b4_stride as usize + t.b.x as usize, ) .ii @@ -3267,7 +3315,7 @@ pub(crate) fn rav1d_recon_b_inter( }, )?; } - v_off = 2 * BD::pxstride(f.cur.stride[1]); + v_off = 2 * BD::pxstride(f.content.cur.stride[1]); } for pl in 0..2 { mc::( @@ -3291,7 +3339,7 @@ pub(crate) fn rav1d_recon_b_inter( } else { if cmp::min(cbw4, cbh4) > 1 && (inter.inter_mode == GLOBALMV - && f.gmv_warp_allowed[inter.r#ref[0] as usize] != 0 + && f.content.gmv_warp_allowed[inter.r#ref[0] as usize] != 0 || inter.motion_mode == MotionMode::Warp && t.warpmv.r#type > Rav1dWarpedMotionType::Translation) { @@ -3364,11 +3412,11 @@ pub(crate) fn rav1d_recon_b_inter( }; let mut angle = 0; let uv_dst = cur_data[1 + pl].with_offset::() + uvdstoff; - let top_sb_edge_slice = if t.b.y & f.sb_step - 1 == 0 { - let sby = t.b.y >> f.sb_shift; - let offset = (f.ipred_edge_off * (pl + 1)) as isize - + (f.sb128w * 128 * (sby - 1)) as isize; - Some((&f.ipred_edge, offset)) + let top_sb_edge_slice = if t.b.y & f.content.sb_step - 1 == 0 { + let sby = t.b.y >> f.content.sb_shift; + let offset = (f.content.ipred_edge_off * (pl + 1)) as isize + + (f.content.sb128w * 128 * (sby - 1)) as isize; + Some((&f.content.ipred_edge, offset)) } else { None }; @@ -3392,7 +3440,7 @@ pub(crate) fn rav1d_recon_b_inter( bd, ); let tmp = interintra_edge_pal.interintra.buf_mut::(); - f.dsp.ipred.intra_pred[m as usize].call( + f.content.dsp.ipred.intra_pred[m as usize].call( Rav1dPictureDataComponentOffset { data: &Rav1dPictureDataComponent::wrap_buf::( tmp, @@ -3409,7 +3457,8 @@ pub(crate) fn rav1d_recon_b_inter( 0, bd, ); - f.dsp + f.content + .dsp .mc .blend .call::(uv_dst, tmp, cbw4 * 4, cbh4 * 4, ii_mask); @@ -3446,7 +3495,7 @@ pub(crate) fn rav1d_recon_b_inter( if b.skip != 0 { // reset coef contexts CaseSet::<32, false>::many( - [&t.l, &f.a[t.a]], + [&t.l, &f.content.a[t.a]], [bh4 as usize, bw4 as usize], [by4 as usize, bx4 as usize], |case, dir| { @@ -3455,7 +3504,7 @@ pub(crate) fn rav1d_recon_b_inter( ); if has_chroma { CaseSet::<32, false>::many( - [&t.l, &f.a[t.a]], + [&t.l, &f.content.a[t.a]], [cbh4 as usize, cbw4 as usize], [cby4 as usize, cbx4 as usize], |case, dir| { @@ -3535,19 +3584,20 @@ pub(crate) fn rav1d_recon_b_inter( let len = uvtx.h as u32 * 4 * uvtx.w as u32 * 4; let cf_idx = ts.frame_thread[p].cf.get_update(|i| i + len); cf_guard = f + .content .frame_thread .cf .mut_slice_as((cf_idx as usize.., ..len as usize)); cf = &mut *cf_guard; let cbi_idx = ts.frame_thread[p].cbi_idx.get_update(|i| i + 1); - let cbi = f.frame_thread.cbi[cbi_idx as usize].get(); + let cbi = f.content.frame_thread.cbi[cbi_idx as usize].get(); eob = cbi.eob().into(); txtp = cbi.txtp(); } else { let mut cf_ctx = 0; txtp = t.scratch.inter_intra().ac_txtp_map.txtp_map() [((by4 + (y << ss_ver)) * 32 + bx4 + (x << ss_hor)) as usize]; - let a_ccoef = &f.a[t.a].ccoef[pl]; + let a_ccoef = &f.content.a[t.a].ccoef[pl]; let a_start = (cbx4 + x) as usize; let l_ccoef = &t.l.ccoef[pl]; let l_start = (cby4 + y) as usize; @@ -3582,10 +3632,14 @@ pub(crate) fn rav1d_recon_b_inter( CaseSet::<16, true>::many( [l_ccoef, a_ccoef], [ - cmp::min(uvtx.h as i32, f.bh - t.b.y + ss_ver >> ss_ver) - as usize, - cmp::min(uvtx.w as i32, f.bw - t.b.x + ss_hor >> ss_hor) - as usize, + cmp::min( + uvtx.h as i32, + f.content.bh - t.b.y + ss_ver >> ss_ver, + ) as usize, + cmp::min( + uvtx.w as i32, + f.content.bw - t.b.x + ss_hor >> ss_hor, + ) as usize, ], [(cby4 + y) as usize, (cbx4 + x) as usize], |case, dir| { @@ -3603,12 +3657,8 @@ pub(crate) fn rav1d_recon_b_inter( "dq", ); } - f.dsp.itx.itxfm_add[b.uvtx as usize][txtp as usize].call::( - uv_dst + 4 * x as usize, - cf, - eob, - bd, - ); + f.content.dsp.itx.itxfm_add[b.uvtx as usize][txtp as usize] + .call::(uv_dst + 4 * x as usize, cf, eob, bd); if debug_block_info!(f, t.b) && DEBUG_B_PIXELS { let uv_dst = uv_dst + (4 * x as usize); hex_dump_pic::( @@ -3645,21 +3695,21 @@ pub(crate) fn rav1d_filter_sbrow_deblock_cols( return; } - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; if frame_hdr.loopfilter.level_y == [0; 2] { return; } - let y = sby * f.sb_step * 4; - let p = f.cur.lf_offsets::(y); - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); - let mask_offset = (sby >> (seq_hdr.sb128 == 0) as c_int) * f.sb128w; + let y = sby * f.content.sb_step * 4; + let p = f.content.cur.lf_offsets::(y); + let seq_hdr = &f.seq_hdr; + let mask_offset = (sby >> (seq_hdr.sb128 == 0) as c_int) * f.content.sb128w; rav1d_loopfilter_sbrow_cols::( f, p, mask_offset as usize, sby, - f.lf.start_of_tile_row[sby as usize] as c_int, + f.content.lf.start_of_tile_row[sby as usize] as c_int, ); } @@ -3669,19 +3719,19 @@ pub(crate) fn rav1d_filter_sbrow_deblock_rows( _t: &mut Rav1dTaskContext, sby: c_int, ) { - let y = sby * f.sb_step * 4; - let p = f.cur.lf_offsets::(y); - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); + let y = sby * f.content.sb_step * 4; + let p = f.content.cur.lf_offsets::(y); + let seq_hdr = &f.seq_hdr; let sb128 = seq_hdr.sb128; let cdef = seq_hdr.cdef; - let mask_offset = (sby >> (sb128 == 0) as c_int) * f.sb128w; - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let mask_offset = (sby >> (sb128 == 0) as c_int) * f.content.sb128w; + let frame_hdr = &f.frame_hdr; if c.inloop_filters.contains(Rav1dInloopFilterType::DEBLOCK) && (frame_hdr.loopfilter.level_y != [0; 2]) { rav1d_loopfilter_sbrow_rows::(f, p, mask_offset as usize, sby); } - if cdef != 0 || !f.lf.restore_planes.is_empty() { + if cdef != 0 || !f.content.lf.restore_planes.is_empty() { // Store loop filtered pixels required by CDEF / LR. rav1d_copy_lpf::(c, f, p, sby); } @@ -3697,23 +3747,23 @@ pub(crate) fn rav1d_filter_sbrow_cdef( return; } - let sbsz = f.sb_step; + let sbsz = f.content.sb_step; let y = sby * sbsz * 4; - let p = f.cur.lf_offsets::(y); - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); - let prev_mask = (sby - 1 >> (seq_hdr.sb128 == 0) as c_int) * f.sb128w; - let mask_offset = (sby >> (seq_hdr.sb128 == 0) as c_int) * f.sb128w; + let p = f.content.cur.lf_offsets::(y); + let seq_hdr = &f.seq_hdr; + let prev_mask = (sby - 1 >> (seq_hdr.sb128 == 0) as c_int) * f.content.sb128w; + let mask_offset = (sby >> (seq_hdr.sb128 == 0) as c_int) * f.content.sb128w; let start = sby * sbsz; if sby != 0 { let p_up = array::from_fn(|i| { - let ss_ver = f.cur.p.layout == Rav1dPixelLayout::I420 && i != 0; + let ss_ver = f.content.cur.p.layout == Rav1dPixelLayout::I420 && i != 0; p[i] - ((8 * p[i].pixel_stride::()) >> ss_ver as u8) }); rav1d_cdef_brow::(c, tc, f, p_up, prev_mask, start - 2, start, true, sby); } - let n_blks = sbsz - 2 * ((sby + 1) < f.sbh) as c_int; - let end = cmp::min(start + n_blks, f.bh); + let n_blks = sbsz - 2 * ((sby + 1) < f.content.sbh) as c_int; + let end = cmp::min(start + n_blks, f.content.bh); rav1d_cdef_brow::(c, tc, f, p, mask_offset, start, end, false, sby); } @@ -3723,34 +3773,34 @@ pub(crate) fn rav1d_filter_sbrow_resize( _t: &mut Rav1dTaskContext, sby: c_int, ) { - let bd = BD::from_c(f.bitdepth_max); + let bd = BD::from_c(f.content.bitdepth_max); - let sbsz = f.sb_step; + let sbsz = f.content.sb_step; let y = sby * sbsz * 4; - let p = f.cur.lf_offsets::(y); - let sr_p = f.sr_cur.p.lf_offsets::(y); - let has_chroma = (f.cur.p.layout != Rav1dPixelLayout::I400) as usize; + let p = f.content.cur.lf_offsets::(y); + let sr_p = f.content.sr_cur.p.lf_offsets::(y); + let has_chroma = (f.content.cur.p.layout != Rav1dPixelLayout::I400) as usize; for pl in 0..1 + 2 * has_chroma { - let ss_ver = (pl != 0 && f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_ver = (pl != 0 && f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; let h_start = 8 * (sby != 0) as c_int >> ss_ver; let dst = sr_p[pl]; let dst = dst - (h_start as isize * dst.pixel_stride::()); let src = p[pl]; let src = src - (h_start as isize * src.pixel_stride::()); - let h_end = 4 * (sbsz - 2 * ((sby + 1) < f.sbh) as c_int) >> ss_ver; - let ss_hor = (pl != 0 && f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; - let dst_w = f.sr_cur.p.p.w + ss_hor >> ss_hor; - let src_w = 4 * f.bw + ss_hor >> ss_hor; - let img_h = f.cur.p.h - sbsz * 4 * sby + ss_ver >> ss_ver; + let h_end = 4 * (sbsz - 2 * ((sby + 1) < f.content.sbh) as c_int) >> ss_ver; + let ss_hor = (pl != 0 && f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + let dst_w = f.content.sr_cur.p.p.w + ss_hor >> ss_hor; + let src_w = 4 * f.content.bw + ss_hor >> ss_hor; + let img_h = f.content.cur.p.h - sbsz * 4 * sby + ss_ver >> ss_ver; - f.dsp.mc.resize.call::( + f.content.dsp.mc.resize.call::( WithOffset::pic(dst), src, dst_w as usize, (cmp::min(img_h, h_end) + h_start) as usize, src_w as usize, - f.resize_step[(pl != 0) as usize], - f.resize_start[(pl != 0) as usize], + f.content.resize_step[(pl != 0) as usize], + f.content.resize_start[(pl != 0) as usize], bd, ); } @@ -3768,8 +3818,8 @@ pub(crate) fn rav1d_filter_sbrow_lr( { return; } - let y = sby * f.sb_step * 4; - let sr_p = f.sr_cur.p.lf_offsets::(y); + let y = sby * f.content.sb_step * 4; + let sr_p = f.content.sr_cur.p.lf_offsets::(y); rav1d_lr_sbrow::(c, f, sr_p, sby); } @@ -3781,53 +3831,52 @@ pub(crate) fn rav1d_filter_sbrow( ) { rav1d_filter_sbrow_deblock_cols::(c, f, t, sby); rav1d_filter_sbrow_deblock_rows::(c, f, t, sby); - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); - if seq_hdr.cdef != 0 { + if f.seq_hdr.cdef != 0 { rav1d_filter_sbrow_cdef::(c, f, t, sby); } - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); - if frame_hdr.size.width[0] != frame_hdr.size.width[1] { + if f.frame_hdr.size.width[0] != f.frame_hdr.size.width[1] { rav1d_filter_sbrow_resize::(c, f, t, sby); } - if !f.lf.restore_planes.is_empty() { + if !f.content.lf.restore_planes.is_empty() { rav1d_filter_sbrow_lr::(c, f, t, sby); } } pub(crate) fn rav1d_backup_ipred_edge(f: &Rav1dFrameData, t: &mut Rav1dTaskContext) { - let cur_data = &f.cur.data.as_ref().unwrap().data; + let cur_data = &f.content.cur.data.as_ref().unwrap().data; - let ts = &f.ts[t.ts]; - let sby = t.b.y >> f.sb_shift; - let sby_off = f.sb128w * 128 * sby; + let ts = &f.content.ts[t.ts]; + let sby = t.b.y >> f.content.sb_shift; + let sby_off = f.content.sb128w * 128 * sby; let x_off = ts.tiling.col_start; let y = &cur_data[0]; let y = y.with_offset::() + x_off as usize * 4 - + ((t.b.y + f.sb_step) * 4 - 1) as isize * y.pixel_stride::(); - let ipred_edge_off = (f.ipred_edge_off * 0) + (sby_off + x_off * 4) as usize; + + ((t.b.y + f.content.sb_step) * 4 - 1) as isize * y.pixel_stride::(); + let ipred_edge_off = (f.content.ipred_edge_off * 0) + (sby_off + x_off * 4) as usize; let n = 4 * (ts.tiling.col_end - x_off) as usize; BD::pixel_copy( - &mut f.ipred_edge.mut_slice_as((ipred_edge_off.., ..n)), + &mut f.content.ipred_edge.mut_slice_as((ipred_edge_off.., ..n)), &y.slice::(n), n, ); - if f.cur.p.layout != Rav1dPixelLayout::I400 { - let ss_ver = (f.cur.p.layout == Rav1dPixelLayout::I420) as c_int; - let ss_hor = (f.cur.p.layout != Rav1dPixelLayout::I444) as c_int; + if f.content.cur.p.layout != Rav1dPixelLayout::I400 { + let ss_ver = (f.content.cur.p.layout == Rav1dPixelLayout::I420) as c_int; + let ss_hor = (f.content.cur.p.layout != Rav1dPixelLayout::I444) as c_int; let uv_off = (x_off * 4 >> ss_hor) as isize - + (((t.b.y + f.sb_step) * 4 >> ss_ver) - 1) as isize * BD::pxstride(f.cur.stride[1]); + + (((t.b.y + f.content.sb_step) * 4 >> ss_ver) - 1) as isize + * BD::pxstride(f.content.cur.stride[1]); for pl in 1..3 { let ipred_edge_off = - (f.ipred_edge_off * pl) + (sby_off + (x_off * 4 >> ss_hor)) as usize; + (f.content.ipred_edge_off * pl) + (sby_off + (x_off * 4 >> ss_hor)) as usize; let n = 4 * (ts.tiling.col_end - x_off) as usize >> ss_hor; let uv = &cur_data[pl]; let uv = uv.with_offset::() + uv_off; BD::pixel_copy( - &mut f.ipred_edge.mut_slice_as((ipred_edge_off.., ..n)), + &mut f.content.ipred_edge.mut_slice_as((ipred_edge_off.., ..n)), &uv.slice::(n), n, ); @@ -3846,8 +3895,8 @@ pub(crate) fn rav1d_copy_pal_block_y( let pal = if t.frame_thread.pass != 0 { let x = t.b.x as usize; let y = t.b.y as usize; - let index = ((y >> 1) + (x & 1)) * (f.b4_stride as usize >> 1) + (x >> 1) + (y & 1); - &f.frame_thread.pal.index::(index)[0] + let index = ((y >> 1) + (x & 1)) * (f.content.b4_stride as usize >> 1) + (x >> 1) + (y & 1); + &f.content.frame_thread.pal.index::(index)[0] } else { &t.scratch.inter_intra().interintra_edge_pal.pal.buf::()[0] }; @@ -3871,8 +3920,8 @@ pub(crate) fn rav1d_copy_pal_block_uv( let pal = if t.frame_thread.pass != 0 { let x = t.b.x as usize; let y = t.b.y as usize; - let index = ((y >> 1) + (x & 1)) * (f.b4_stride as usize >> 1) + (x >> 1) + (y & 1); - &*f.frame_thread.pal.index::(index) + let index = ((y >> 1) + (x & 1)) * (f.content.b4_stride as usize >> 1) + (x >> 1) + (y & 1); + &*f.content.frame_thread.pal.index::(index) } else { t.scratch.inter_intra().interintra_edge_pal.pal.buf::() }; @@ -3920,7 +3969,7 @@ pub(crate) fn rav1d_read_pal_plane( if pl { t.pal_sz_uv[0][bx4] } else { - *f.a[t.a].pal_sz.index(bx4) + *f.content.a[t.a].pal_sz.index(bx4) } } else { 0 @@ -3995,9 +4044,9 @@ pub(crate) fn rav1d_read_pal_plane( // parse new entries let pal = if t.frame_thread.pass != 0 { - let pal_start = (((t.b.y >> 1) + (t.b.x & 1)) as isize * (f.b4_stride >> 1) + let pal_start = (((t.b.y >> 1) + (t.b.x & 1)) as isize * (f.content.b4_stride >> 1) + ((t.b.x >> 1) + (t.b.y & 1)) as isize) as usize; - &mut f.frame_thread.pal.index_mut::(pal_start)[pli] + &mut f.content.frame_thread.pal.index_mut::(pal_start)[pli] } else { &mut t .scratch @@ -4008,13 +4057,14 @@ pub(crate) fn rav1d_read_pal_plane( }; let pal = &mut pal[..pal_sz]; if i < pal.len() { - let mut prev = rav1d_msac_decode_bools(&mut ts_c.msac, f.cur.p.bpc) as u16; + let mut prev = rav1d_msac_decode_bools(&mut ts_c.msac, f.content.cur.p.bpc) as u16; pal[i] = prev.as_::(); i += 1; if i < pal.len() { - let mut bits = f.cur.p.bpc + rav1d_msac_decode_bools(&mut ts_c.msac, 2) as u8 - 3; - let max = (1 << f.cur.p.bpc) - 1; + let mut bits = + f.content.cur.p.bpc + rav1d_msac_decode_bools(&mut ts_c.msac, 2) as u8 - 3; + let max = (1 << f.content.cur.p.bpc) - 1; loop { let delta = rav1d_msac_decode_bools(&mut ts_c.msac, bits) as u16; @@ -4092,8 +4142,8 @@ pub(crate) fn rav1d_read_pal_uv( // V pal coding let pal = if t.frame_thread.pass != 0 { - &mut f.frame_thread.pal.index_mut::( - (((t.b.y >> 1) + (t.b.x & 1)) as isize * (f.b4_stride >> 1) + &mut f.content.frame_thread.pal.index_mut::( + (((t.b.y >> 1) + (t.b.x & 1)) as isize * (f.content.b4_stride >> 1) + ((t.b.x >> 1) + (t.b.y & 1)) as isize) as usize, )[2] } else { @@ -4106,10 +4156,10 @@ pub(crate) fn rav1d_read_pal_uv( }; let pal = &mut pal[..pal_sz as usize]; if rav1d_msac_decode_bool_equi(&mut ts_c.msac) { - let bits = f.cur.p.bpc + rav1d_msac_decode_bools(&mut ts_c.msac, 2) as u8 - 4; - let mut prev = rav1d_msac_decode_bools(&mut ts_c.msac, f.cur.p.bpc) as u16; + let bits = f.content.cur.p.bpc + rav1d_msac_decode_bools(&mut ts_c.msac, 2) as u8 - 4; + let mut prev = rav1d_msac_decode_bools(&mut ts_c.msac, f.content.cur.p.bpc) as u16; pal[0] = prev.as_::(); - let max = (1 << f.cur.p.bpc) - 1; + let max = (1 << f.content.cur.p.bpc) - 1; for pal in &mut pal[1..] { let mut delta = rav1d_msac_decode_bools(&mut ts_c.msac, bits) as i16; if delta != 0 && rav1d_msac_decode_bool_equi(&mut ts_c.msac) { @@ -4119,7 +4169,9 @@ pub(crate) fn rav1d_read_pal_uv( *pal = prev.as_::(); } } else { - pal.fill_with(|| rav1d_msac_decode_bools(&mut ts_c.msac, f.cur.p.bpc).as_::()); + pal.fill_with(|| { + rav1d_msac_decode_bools(&mut ts_c.msac, f.content.cur.p.bpc).as_::() + }); } if debug_block_info!(f, t.b) { print!("Post-pal[pl=2]: r={} ", ts_c.msac.rng); diff --git a/src/thread_task.rs b/src/thread_task.rs index 7afb5a7ff..4df0cfc1f 100644 --- a/src/thread_task.rs +++ b/src/thread_task.rs @@ -22,6 +22,7 @@ use crate::src::internal::Rav1dContext; use crate::src::internal::Rav1dFrameContext; use crate::src::internal::Rav1dFrameContextTaskThread; use crate::src::internal::Rav1dFrameData; +use crate::src::internal::Rav1dFrameDataMaybeHeaders; use crate::src::internal::Rav1dTask; use crate::src::internal::Rav1dTaskContext; use crate::src::internal::Rav1dTaskContextTaskThread; @@ -394,16 +395,16 @@ fn merge_pending(c: &Rav1dContext) -> c_int { } fn create_filter_sbrow(fc: &Rav1dFrameContext, f: &Rav1dFrameData, pass: c_int) -> Rav1dResult { - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; let has_deblock = (frame_hdr.loopfilter.level_y != [0; 2]) as c_int; - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); + let seq_hdr = &f.seq_hdr; let has_cdef = seq_hdr.cdef; let has_resize = (frame_hdr.size.width[0] != frame_hdr.size.width[1]) as c_int; - let has_lr = !f.lf.restore_planes.is_empty(); + let has_lr = !f.content.lf.restore_planes.is_empty(); if pass & 1 != 0 { fc.frame_thread_progress.entropy.store(0, Ordering::Relaxed); } else { - let prog_sz = ((f.sbh + 31 & !(31 as c_int)) >> 5) as usize; + let prog_sz = ((f.content.sbh + 31 & !(31 as c_int)) >> 5) as usize; let mut frame = fc.frame_thread_progress.frame.try_write().unwrap(); frame.clear(); frame.resize_with(prog_sz, Default::default); @@ -414,7 +415,7 @@ fn create_filter_sbrow(fc: &Rav1dFrameContext, f: &Rav1dFrameData, pass: c_int) copy_lpf.resize_with(prog_sz, Default::default); fc.frame_thread_progress.deblock.store(0, Ordering::SeqCst); } - f.frame_thread.next_tile_row[(pass & 1) as usize].set(0); + f.content.frame_thread.next_tile_row[(pass & 1) as usize].set(0); let type_0 = if pass == 1 { TaskType::EntropyProgress } else if has_deblock != 0 { @@ -446,16 +447,16 @@ pub(crate) fn rav1d_task_create_tile_sbrow( _cond_signal: c_int, ) -> Rav1dResult { let tasks = &fc.task_thread.tasks; - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; let num_tasks = frame_hdr.tiling.cols as usize * frame_hdr.tiling.rows as usize; fc.task_thread.done[(pass & 1) as usize].store(0, Ordering::SeqCst); create_filter_sbrow(fc, f, pass)?; { let mut pending_tasks = tasks.pending_tasks.lock(); for tile_idx in 0..num_tasks { - let ts = &f.ts[tile_idx]; + let ts = &f.content.ts[tile_idx]; let t = Rav1dTask { - sby: ts.tiling.row_start >> f.sb_shift, + sby: ts.tiling.row_start >> f.content.sb_shift, recon_progress: 0, deblock_progress: 0, deps_skip: 0.into(), @@ -541,14 +542,14 @@ fn ensure_progress<'l, 'ttd: 'l>( #[inline] fn check_tile( - f: &Rav1dFrameData, + f: &Rav1dFrameDataMaybeHeaders, task_thread: &Rav1dFrameContextTaskThread, t: &Rav1dTask, frame_mt: c_int, ) -> c_int { let tp = t.type_0 == TaskType::TileEntropy; let tile_idx = t.tile_idx as usize; - let ts = &f.ts[tile_idx]; + let ts = &f.content.ts[tile_idx]; let p1 = ts.progress[tp as usize].load(Ordering::SeqCst); if p1 < t.sby { return 1; @@ -566,11 +567,12 @@ fn check_tile( let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); if error == 0 && frame_mt != 0 && !frame_hdr.frame_type.is_key_or_intra() { // check reference state - let p = &f.sr_cur; + let p = &f.content.sr_cur; let ss_ver = (p.p.p.layout == Rav1dPixelLayout::I420) as c_int; - let p_b = ((t.sby + 1) << f.sb_shift + 2) as c_uint; - let tile_sby = t.sby - (ts.tiling.row_start >> f.sb_shift); + let p_b = ((t.sby + 1) << f.content.sb_shift + 2) as c_uint; + let tile_sby = t.sby - (ts.tiling.row_start >> f.content.sb_shift); let lowest_px = f + .content .lowest_pixel_mem .index(ts.lowest_pixel + tile_sby as usize); for n in t.deps_skip.get()..7 { @@ -596,9 +598,9 @@ fn check_tile( if max == i32::MIN { break 'next; } - iclip(max, 1 as c_int, f.refp[n as usize].p.p.h) as c_uint + iclip(max, 1 as c_int, f.content.refp[n as usize].p.p.h) as c_uint }; - let p3 = f.refp[n as usize].progress.as_ref().unwrap()[!tp as usize] + let p3 = f.content.refp[n as usize].progress.as_ref().unwrap()[!tp as usize] .load(Ordering::SeqCst); if p3 < lowest { return 1; @@ -615,22 +617,23 @@ fn check_tile( } #[inline] -fn get_frame_progress(fc: &Rav1dFrameContext, f: &Rav1dFrameData) -> c_int { +fn get_frame_progress(fc: &Rav1dFrameContext, f: &Rav1dFrameDataMaybeHeaders) -> c_int { // Note that `progress.is_some() == c.fc.len() > 1`. let frame_prog = f + .content .sr_cur .progress .as_ref() .map(|progress| progress[1].load(Ordering::SeqCst)) .unwrap_or(0); if frame_prog >= FRAME_ERROR { - return f.sbh - 1; + return f.content.sbh - 1; } let frame = fc.frame_thread_progress.frame.try_read().unwrap(); let (idx, prog) = frame .iter() .enumerate() - .skip(frame_prog as usize >> (f.sb_shift + 7)) + .skip(frame_prog as usize >> (f.content.sb_shift + 7)) .find_map(|(i, progress)| { let val = !progress.load(Ordering::SeqCst); match val.trailing_zeros() { @@ -652,7 +655,7 @@ fn abort_frame(c: &Rav1dContext, fc: &Rav1dFrameContext, error: Rav1dResult) { fc.task_thread.done[1].store(1, Ordering::SeqCst); { let f = fc.data.try_read().unwrap(); - let progress = &**f.sr_cur.progress.as_ref().unwrap(); + let progress = &**f.content.sr_cur.progress.as_ref().unwrap(); progress[0].store(FRAME_ERROR, Ordering::SeqCst); progress[1].store(FRAME_ERROR, Ordering::SeqCst); } @@ -897,7 +900,7 @@ pub fn rav1d_worker_task(task_thread: Arc) { assert!(done == 0 || error != 0, "done: {done}, error: {error}"); let frame_hdr = fc.frame_hdr(); let tile_row_base = frame_hdr.tiling.cols as c_int - * f.frame_thread.next_tile_row[p as usize].get(); + * f.content.frame_thread.next_tile_row[p as usize].get(); if p { let p1_0 = fc.frame_thread_progress.entropy.load(Ordering::SeqCst); if p1_0 < t.sby { @@ -908,7 +911,7 @@ pub fn rav1d_worker_task(task_thread: Arc) { .fetch_or((p1_0 == TILE_ERROR) as c_int, Ordering::SeqCst); } for tc_0 in 0..frame_hdr.tiling.cols { - let ts = &f.ts[(tile_row_base + tc_0 as c_int) as usize]; + let ts = &f.content.ts[(tile_row_base + tc_0 as c_int) as usize]; let p2 = ts.progress[p as usize].load(Ordering::SeqCst); if p2 < t.recon_progress { break 'next; @@ -917,17 +920,18 @@ pub fn rav1d_worker_task(task_thread: Arc) { .error .fetch_or((p2 == TILE_ERROR) as c_int, Ordering::SeqCst); } - if (t.sby + 1) < f.sbh { + if (t.sby + 1) < f.content.sbh { // add sby+1 to list to replace this one let next_t = Rav1dTask { sby: t.sby + 1, recon_progress: t.sby + 2, ..t.without_next() }; - let ntr = f.frame_thread.next_tile_row[p as usize].get() + 1; + let ntr = + f.content.frame_thread.next_tile_row[p as usize].get() + 1; let start = frame_hdr.tiling.row_start_sb[ntr as usize] as c_int; if next_t.sby == start { - f.frame_thread.next_tile_row[p as usize].set(ntr); + f.content.frame_thread.next_tile_row[p as usize].set(ntr); } drop(t); fc.task_thread.insert_task(c, next_t, 0); @@ -1028,13 +1032,14 @@ pub fn rav1d_worker_task(task_thread: Arc) { unreachable!(); } let mut res_0 = Err(EINVAL); - let mut f = fc.data.try_write().unwrap(); + let mut f_guard = fc.data.try_write().unwrap(); + let f = f_guard.assert_has_headers_mut(); if fc.task_thread.error.load(Ordering::SeqCst) == 0 { - res_0 = rav1d_decode_frame_init_cdf(c, fc, &mut f, &fc.in_cdf()); + res_0 = rav1d_decode_frame_init_cdf(c, fc, f, &fc.in_cdf()); } - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; if frame_hdr.refresh_context != 0 && !fc.task_thread.update_set.get() { - f.out_cdf.progress().unwrap().store( + f.content.out_cdf.progress().unwrap().store( (if res_0.is_err() { TILE_ERROR } else { @@ -1043,14 +1048,15 @@ pub fn rav1d_worker_task(task_thread: Arc) { Ordering::SeqCst, ); } - drop(f); + drop(f_guard); if res_0.is_ok() { if !(c.fc.len() > 1) { unreachable!(); } let mut p_0 = 1; while p_0 <= 2 { - let f = fc.data.try_read().unwrap(); + let f_guard = fc.data.try_read().unwrap(); + let f = f_guard.assert_has_headers(); let res_1 = rav1d_task_create_tile_sbrow(fc, &f, p_0, 0); if res_1.is_err() { assert!( @@ -1062,16 +1068,16 @@ pub fn rav1d_worker_task(task_thread: Arc) { fc.task_thread.done[(2 - p_0) as usize] .store(1 as c_int, Ordering::SeqCst); fc.task_thread.error.store(-(1 as c_int), Ordering::SeqCst); - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let frame_hdr = &f.frame_hdr; fc.task_thread.task_counter.fetch_sub( frame_hdr.tiling.cols as c_int * frame_hdr.tiling.rows as c_int - + f.sbh, + + f.content.sbh, Ordering::SeqCst, ); // Note that `progress.is_some() == c.fc.len() > 1`. - let progress = &**f.sr_cur.progress.as_ref().unwrap(); + let progress = &**f.content.sr_cur.progress.as_ref().unwrap(); progress[(p_0 - 1) as usize] .store(FRAME_ERROR, Ordering::SeqCst); if p_0 == 2 @@ -1080,7 +1086,7 @@ pub fn rav1d_worker_task(task_thread: Arc) { if fc.task_thread.task_counter.load(Ordering::SeqCst) != 0 { unreachable!(); } - drop(f); + drop(f_guard); let _ = rav1d_decode_frame_exit(c, fc, Err(ENOMEM)); fc.task_thread.cond.notify_one(); } else { @@ -1108,9 +1114,9 @@ pub fn rav1d_worker_task(task_thread: Arc) { let f = fc.data.try_read().unwrap(); let p_1 = t.type_0 == TaskType::TileEntropy; let tile_idx = t.tile_idx as usize; - let ts = &f.ts[tile_idx]; + let ts = &f.content.ts[tile_idx]; tc.ts = tile_idx; - tc.b.y = sby << f.sb_shift; + tc.b.y = sby << f.content.sb_shift; let uses_2pass = (c.fc.len() > 1) as c_int; tc.frame_thread.pass = if uses_2pass == 0 { 0 as c_int @@ -1118,6 +1124,7 @@ pub fn rav1d_worker_task(task_thread: Arc) { 1 as c_int + (t.type_0 == TaskType::TileReconstruction) as c_int }; if error_0 == 0 { + let f = f.assert_has_headers(); error_0 = match rav1d_decode_tile_sbrow(c, &mut tc, &f) { Ok(()) => 0, Err(()) => 1, @@ -1127,7 +1134,7 @@ pub fn rav1d_worker_task(task_thread: Arc) { // signal progress fc.task_thread.error.fetch_or(error_0, Ordering::SeqCst); - if (sby + 1) << f.sb_shift < ts.tiling.row_end { + if (sby + 1) << f.content.sb_shift < ts.tiling.row_end { t.sby += 1; t.deps_skip = 0.into(); if check_tile(&f, &fc.task_thread, &t, uses_2pass) == 0 { @@ -1158,15 +1165,15 @@ pub fn rav1d_worker_task(task_thread: Arc) { if error_0 == 0 { rav1d_cdf_thread_update( frame_hdr, - &mut f.out_cdf.cdf_write(), - &f.ts[frame_hdr.tiling.update as usize] + &mut f.content.out_cdf.cdf_write(), + &f.content.ts[frame_hdr.tiling.update as usize] .context .try_lock() .unwrap() .cdf, ); } - if let Some(progress) = f.out_cdf.progress() { + if let Some(progress) = f.content.out_cdf.progress() { progress.store( (if error_0 != 0 { TILE_ERROR } else { 1 as c_int }) as c_uint, @@ -1206,6 +1213,7 @@ pub fn rav1d_worker_task(task_thread: Arc) { TaskType::DeblockCols => { { let f = fc.data.try_read().unwrap(); + let f = f.assert_has_headers(); if fc.task_thread.error.load(Ordering::SeqCst) == 0 { (f.bd_fn().filter_sbrow_deblock_cols)(c, &f, &mut tc, sby); } @@ -1225,15 +1233,16 @@ pub fn rav1d_worker_task(task_thread: Arc) { continue 'fallthrough; } TaskType::DeblockRows => { - let f = fc.data.try_read().unwrap(); + let f_guard = fc.data.try_read().unwrap(); + let f = f_guard.assert_has_headers(); if fc.task_thread.error.load(Ordering::SeqCst) == 0 { (f.bd_fn().filter_sbrow_deblock_rows)(c, &f, &mut tc, sby); } // signal deblock progress - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); + let seq_hdr = &f.seq_hdr; + let frame_hdr = &f.frame_hdr; if frame_hdr.loopfilter.level_y != [0; 2] { - drop(f); + drop(f_guard); error_0 = fc.task_thread.error.load(Ordering::SeqCst); fc.frame_thread_progress.deblock.store( if error_0 != 0 { TILE_ERROR } else { sby + 1 }, @@ -1243,8 +1252,8 @@ pub fn rav1d_worker_task(task_thread: Arc) { if ttd.cond_signaled.fetch_or(1, Ordering::SeqCst) == 0 { ttd.cond.notify_one(); } - } else if seq_hdr.cdef != 0 || !f.lf.restore_planes.is_empty() { - drop(f); + } else if seq_hdr.cdef != 0 || !f.content.lf.restore_planes.is_empty() { + drop(f_guard); let copy_lpf = fc.frame_thread_progress.copy_lpf.try_read().unwrap(); copy_lpf[(sby >> 5) as usize] .fetch_or((1 as c_uint) << (sby & 31), Ordering::SeqCst); @@ -1271,13 +1280,13 @@ pub fn rav1d_worker_task(task_thread: Arc) { continue 'fallthrough; } TaskType::Cdef => { - let f = fc.data.try_read().unwrap(); - let seq_hdr = &***f.seq_hdr.as_ref().unwrap(); - if seq_hdr.cdef != 0 { + let f_guard = fc.data.try_read().unwrap(); + let f = f_guard.assert_has_headers(); + if f.seq_hdr.cdef != 0 { if fc.task_thread.error.load(Ordering::SeqCst) == 0 { (f.bd_fn().filter_sbrow_cdef)(c, &f, &mut tc, sby); } - drop(f); + drop(f_guard); reset_task_cur_async(ttd, t.frame_idx, c.fc.len() as u32); if ttd.cond_signaled.fetch_or(1, Ordering::SeqCst) == 0 { ttd.cond.notify_one(); @@ -1288,8 +1297,8 @@ pub fn rav1d_worker_task(task_thread: Arc) { } TaskType::SuperResolution => { let f = fc.data.try_read().unwrap(); - let frame_hdr = &***f.frame_hdr.as_ref().unwrap(); - if frame_hdr.size.width[0] != frame_hdr.size.width[1] { + let f = f.assert_has_headers(); + if f.frame_hdr.size.width[0] != f.frame_hdr.size.width[1] { if fc.task_thread.error.load(Ordering::SeqCst) == 0 { (f.bd_fn().filter_sbrow_resize)(c, &f, &mut tc, sby); } @@ -1299,8 +1308,9 @@ pub fn rav1d_worker_task(task_thread: Arc) { } TaskType::LoopRestoration => { let f = fc.data.try_read().unwrap(); + let f = f.assert_has_headers(); if fc.task_thread.error.load(Ordering::SeqCst) == 0 - && !f.lf.restore_planes.is_empty() + && !f.content.lf.restore_planes.is_empty() { (f.bd_fn().filter_sbrow_lr)(c, &f, &mut tc, sby); } @@ -1322,8 +1332,8 @@ pub fn rav1d_worker_task(task_thread: Arc) { // if task completed [typically LR], signal picture progress as per below let f = fc.data.try_read().unwrap(); let uses_2pass_0 = (c.fc.len() > 1) as c_int; - let sbh = f.sbh; - let sbsz = f.sb_step * 4; + let sbh = f.content.sbh; + let sbsz = f.content.sb_step * 4; if t.type_0 == TaskType::EntropyProgress { error_0 = fc.task_thread.error.load(Ordering::SeqCst); let y: c_uint = if sby + 1 == sbh { @@ -1332,8 +1342,8 @@ pub fn rav1d_worker_task(task_thread: Arc) { ((sby + 1) as c_uint).wrapping_mul(sbsz as c_uint) }; // Note that `progress.is_some() == c.fc.len() > 1`. - let progress = &**f.sr_cur.progress.as_ref().unwrap(); - if f.sr_cur.p.data.is_some() { + let progress = &**f.content.sr_cur.progress.as_ref().unwrap(); + if f.content.sr_cur.p.data.is_some() { progress[0].store(if error_0 != 0 { FRAME_ERROR } else { y }, Ordering::SeqCst); } drop(f); @@ -1385,9 +1395,9 @@ pub fn rav1d_worker_task(task_thread: Arc) { ((sby + 1) as c_uint).wrapping_mul(sbsz as c_uint) }; // Note that `progress.is_some() == c.fc.len() > 1`. - if let Some(progress) = &f.sr_cur.progress { + if let Some(progress) = &f.content.sr_cur.progress { // upon flush, this can be free'ed already - if f.sr_cur.p.data.is_some() { + if f.content.sr_cur.p.data.is_some() { progress[1].store( if error_0 != 0 { FRAME_ERROR } else { y_0 }, Ordering::SeqCst,