Skip to content

Commit

Permalink
struct Lossless: Make Rav1dFrameHeader_segmentation::lossless a b…
Browse files Browse the repository at this point in the history
…it array.
  • Loading branch information
kkysen committed Jun 21, 2024
1 parent 1449ec4 commit b30e31c
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 11 deletions.
49 changes: 45 additions & 4 deletions include/dav1d/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2096,6 +2096,48 @@ pub struct Dav1dFrameHeader_segmentation {
pub qidx: [u8; DAV1D_MAX_SEGMENTS as usize],
}

/// Like a `[bool; RAV1D_MAX_SEGMENTS as usize]`,
/// but the [`bool`]s are compressed into the bits of the [`u8`].
#[derive(Clone, Copy, Default)]
pub struct Lossless {
bits: u8,
}

impl Lossless {
pub const fn empty() -> Self {
Self { bits: 0 }
}

pub const fn get(&self, index: u8) -> bool {
const { assert!(u8::BITS >= RAV1D_MAX_SEGMENTS as _) };
self.bits & (1 << index) != 0
}

pub const fn all(&self) -> bool {
self.bits == ((1u64 << RAV1D_MAX_SEGMENTS) - 1) as u8
}

pub const fn to_array(&self) -> [bool; RAV1D_MAX_SEGMENTS as usize] {
let mut a = [false; RAV1D_MAX_SEGMENTS as usize];
let mut i = 0;
while i < RAV1D_MAX_SEGMENTS {
a[i as usize] = self.get(i);
i += 1;
}
a
}

pub fn from_array(a: [bool; RAV1D_MAX_SEGMENTS as usize]) -> Self {
let mut this = Self::empty();
let mut i = 0;
while i < RAV1D_MAX_SEGMENTS {
this.bits |= (a[i as usize] as u8) << i;
i += 1;
}
this
}
}

#[derive(Clone, Default)]
#[repr(C)]
pub struct Rav1dFrameHeader_segmentation {
Expand All @@ -2104,8 +2146,7 @@ pub struct Rav1dFrameHeader_segmentation {
pub temporal: u8,
pub update_data: u8,
pub seg_data: Rav1dSegmentationDataSet,
/// TODO compress `[bool; 8]` into `u8`.
pub lossless: [bool; RAV1D_MAX_SEGMENTS as usize],
pub lossless: Lossless,
pub qidx: [u8; RAV1D_MAX_SEGMENTS as usize],
}

Expand All @@ -2126,7 +2167,7 @@ impl From<Dav1dFrameHeader_segmentation> for Rav1dFrameHeader_segmentation {
temporal,
update_data,
seg_data: seg_data.into(),
lossless: lossless.map(|e| e != 0),
lossless: Lossless::from_array(lossless.map(|e| e != 0)),
qidx,
}
}
Expand All @@ -2149,7 +2190,7 @@ impl From<Rav1dFrameHeader_segmentation> for Dav1dFrameHeader_segmentation {
temporal,
update_data,
seg_data: seg_data.into(),
lossless: lossless.map(|e| e as u8),
lossless: lossless.to_array().map(|e| e as u8),
qidx,
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,7 @@ fn read_vartx_tree(
let frame_hdr = &***f.frame_hdr.as_ref().unwrap();
let txfm_mode = frame_hdr.txfm_mode;
let uvtx;
if b.skip == 0 && (frame_hdr.segmentation.lossless[b.seg_id as usize] || max_ytx == TX_4X4) {
if b.skip == 0 && (frame_hdr.segmentation.lossless.get(b.seg_id) || max_ytx == TX_4X4) {
uvtx = TX_4X4;
max_ytx = uvtx;
if txfm_mode == Rav1dTxfmMode::Switchable {
Expand Down Expand Up @@ -1683,7 +1683,7 @@ fn decode_b(
let uv_angle;
let cfl_alpha;
if has_chroma {
let cfl_allowed = if frame_hdr.segmentation.lossless[b.seg_id as usize] {
let cfl_allowed = if frame_hdr.segmentation.lossless.get(b.seg_id) {
cbw4 == 1 && cbh4 == 1
} else {
(cfl_allowed_mask & (1 << bs as u8)) != 0
Expand Down Expand Up @@ -1882,7 +1882,7 @@ fn decode_b(

let frame_hdr = f.frame_hdr();

let tx = if frame_hdr.segmentation.lossless[b.seg_id as usize] {
let tx = if frame_hdr.segmentation.lossless.get(b.seg_id) {
b.uvtx = TX_4X4;
b.uvtx
} else {
Expand Down Expand Up @@ -3075,7 +3075,7 @@ fn decode_b(
let tx_split = [tx_split0 as u16, tx_split1];
let mut ytx = max_ytx;
let mut uvtx = b.uvtx;
if frame_hdr.segmentation.lossless[b.seg_id as usize] {
if frame_hdr.segmentation.lossless.get(b.seg_id) {
ytx = TX_4X4;
uvtx = TX_4X4;
}
Expand Down
5 changes: 3 additions & 2 deletions src/obu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::include::dav1d::data::Rav1dData;
use crate::include::dav1d::dav1d::Rav1dDecodeFrameType;
use crate::include::dav1d::headers::DRav1d;
use crate::include::dav1d::headers::Dav1dSequenceHeader;
use crate::include::dav1d::headers::Lossless;
use crate::include::dav1d::headers::Rav1dAdaptiveBoolean;
use crate::include::dav1d::headers::Rav1dChromaSamplePosition;
use crate::include::dav1d::headers::Rav1dColorPrimaries;
Expand Down Expand Up @@ -1195,7 +1196,7 @@ fn parse_segmentation(
quant.yac
}
});
let lossless = array::from_fn(|i| qidx[i] == 0 && delta_lossless);
let lossless = Lossless::from_array(array::from_fn(|i| qidx[i] == 0 && delta_lossless));
Ok(Rav1dFrameHeader_segmentation {
enabled,
update_map,
Expand Down Expand Up @@ -2001,7 +2002,7 @@ fn parse_frame_hdr(
let tiling = parse_tiling(seqhdr, &size, &debug, gb)?;
let quant = parse_quant(seqhdr, &debug, gb);
let segmentation = parse_segmentation(state, primary_ref_frame, &refidx, &quant, &debug, gb)?;
let all_lossless = segmentation.lossless.iter().all(|&it| it);
let all_lossless = segmentation.lossless.all();
let delta = parse_delta(&quant, allow_intrabc, &debug, gb);
let loopfilter = parse_loopfilter(
state,
Expand Down
2 changes: 1 addition & 1 deletion src/recon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ fn decode_coefs<BD: BitDepth>(
let ts = &f.ts[ts];
let chroma = plane != 0;
let frame_hdr = &***f.frame_hdr.as_ref().unwrap();
let lossless = frame_hdr.segmentation.lossless[b.seg_id as usize];
let lossless = frame_hdr.segmentation.lossless.get(b.seg_id);
let t_dim = &dav1d_txfm_dimensions[tx as usize];
let dbg = dbg_block_info && plane != 0 && false;

Expand Down

0 comments on commit b30e31c

Please sign in to comment.