Skip to content

Commit

Permalink
enum Rav1dFrameType: Make a real enum and make `fn is_{inter_or_s…
Browse files Browse the repository at this point in the history
…witch,key_or_intra}` methods instead (#625)

The `fn is_{inter_or_switch,key_or_intra}`s took whole
`&Rav1dFrameHeader`s as arguments, but this doesn't work in `fn
parse_frame_hdr` if the `Rav1dFrameHeader` isn't constructed, so now
these `fn`s are methods on `enum Rav1dFrameType`. The implementation is
also simpler, not using `& 1`, but it should still be optimized to the
same since Rust knows `enum`s can only be certain values.

I also adjusted `enum {D,R}av1dPixelLayout` to use the same approach as
`enum Rav1dPixelLayout` for conversions.
  • Loading branch information
kkysen authored Dec 20, 2023
2 parents 69b72fc + fd0bddf commit a89336a
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 114 deletions.
14 changes: 0 additions & 14 deletions include/common/frame.rs

This file was deleted.

122 changes: 74 additions & 48 deletions include/dav1d/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::ffi::c_int;
use std::ffi::c_uint;
use std::ops::BitAnd;
use strum::EnumCount;
use strum::FromRepr;

/// This is so we can store both `*mut D` and `*mut R`
/// for maintaining `dav1d` ABI compatibility,
Expand Down Expand Up @@ -222,60 +223,53 @@ impl From<Rav1dWarpedMotionParams> for Dav1dWarpedMotionParams {
}
}

pub type Dav1dPixelLayout = c_uint;
pub const DAV1D_PIXEL_LAYOUT_I444: Dav1dPixelLayout = 3;
pub const DAV1D_PIXEL_LAYOUT_I422: Dav1dPixelLayout = 2;
pub const DAV1D_PIXEL_LAYOUT_I420: Dav1dPixelLayout = 1;
pub const DAV1D_PIXEL_LAYOUT_I400: Dav1dPixelLayout = 0;

#[derive(Clone, Copy, PartialEq, Eq, EnumCount)]
#[derive(Clone, Copy, PartialEq, Eq, EnumCount, FromRepr)]
pub(crate) enum Rav1dPixelLayout {
I400,
I420,
I422,
I444,
I400 = 0,
I420 = 1,
I422 = 2,
I444 = 3,
}

impl EnumKey<{ Self::COUNT }> for Rav1dPixelLayout {
const VALUES: [Self; Self::COUNT] = [Self::I400, Self::I420, Self::I422, Self::I444];

fn as_usize(self) -> usize {
self as usize
impl Rav1dPixelLayout {
pub const fn into_rav1d(self) -> Dav1dPixelLayout {
self as Dav1dPixelLayout
}
}

impl BitAnd for Rav1dPixelLayout {
type Output = bool;
pub type Dav1dPixelLayout = c_uint;
pub const DAV1D_PIXEL_LAYOUT_I400: Dav1dPixelLayout = Rav1dPixelLayout::I400.into_rav1d();
pub const DAV1D_PIXEL_LAYOUT_I420: Dav1dPixelLayout = Rav1dPixelLayout::I420.into_rav1d();
pub const DAV1D_PIXEL_LAYOUT_I422: Dav1dPixelLayout = Rav1dPixelLayout::I422.into_rav1d();
pub const DAV1D_PIXEL_LAYOUT_I444: Dav1dPixelLayout = Rav1dPixelLayout::I444.into_rav1d();

fn bitand(self, rhs: Self) -> Self::Output {
(self as usize & rhs as usize) != 0
impl From<Rav1dPixelLayout> for Dav1dPixelLayout {
fn from(value: Rav1dPixelLayout) -> Self {
value.into_rav1d()
}
}

impl TryFrom<Dav1dPixelLayout> for Rav1dPixelLayout {
type Error = ();

fn try_from(value: Dav1dPixelLayout) -> Result<Self, Self::Error> {
use Rav1dPixelLayout::*;
Ok(match value {
DAV1D_PIXEL_LAYOUT_I400 => I400,
DAV1D_PIXEL_LAYOUT_I420 => I420,
DAV1D_PIXEL_LAYOUT_I422 => I422,
DAV1D_PIXEL_LAYOUT_I444 => I444,
_ => return Err(()),
})
Self::from_repr(value as usize).ok_or(())
}
}

impl From<Rav1dPixelLayout> for Dav1dPixelLayout {
fn from(value: Rav1dPixelLayout) -> Self {
use Rav1dPixelLayout::*;
match value {
I400 => DAV1D_PIXEL_LAYOUT_I400,
I420 => DAV1D_PIXEL_LAYOUT_I420,
I422 => DAV1D_PIXEL_LAYOUT_I422,
I444 => DAV1D_PIXEL_LAYOUT_I444,
}
impl EnumKey<{ Self::COUNT }> for Rav1dPixelLayout {
const VALUES: [Self; Self::COUNT] = [Self::I400, Self::I420, Self::I422, Self::I444];

fn as_usize(self) -> usize {
self as usize
}
}

impl BitAnd for Rav1dPixelLayout {
type Output = bool;

fn bitand(self, rhs: Self) -> Self::Output {
(self as usize & rhs as usize) != 0
}
}

Expand Down Expand Up @@ -319,17 +313,49 @@ impl From<Rav1dPixelLayoutSubSampled> for Rav1dPixelLayout {
}
}

#[derive(Clone, Copy, PartialEq, Eq, FromRepr)]
pub(crate) enum Rav1dFrameType {
Key = 0,
Inter = 1,
Intra = 2,
Switch = 3,
}

impl Rav1dFrameType {
pub const fn into_rav1d(self) -> Dav1dFrameType {
self as Dav1dFrameType
}
}

pub type Dav1dFrameType = c_uint;
pub const DAV1D_FRAME_TYPE_SWITCH: Dav1dFrameType = 3;
pub const DAV1D_FRAME_TYPE_INTRA: Dav1dFrameType = 2;
pub const DAV1D_FRAME_TYPE_INTER: Dav1dFrameType = 1;
pub const DAV1D_FRAME_TYPE_KEY: Dav1dFrameType = 0;
pub const DAV1D_FRAME_TYPE_KEY: Dav1dFrameType = Rav1dFrameType::Key.into_rav1d();
pub const DAV1D_FRAME_TYPE_INTER: Dav1dFrameType = Rav1dFrameType::Inter.into_rav1d();
pub const DAV1D_FRAME_TYPE_INTRA: Dav1dFrameType = Rav1dFrameType::Intra.into_rav1d();
pub const DAV1D_FRAME_TYPE_SWITCH: Dav1dFrameType = Rav1dFrameType::Switch.into_rav1d();

impl From<Rav1dFrameType> for Dav1dFrameType {
fn from(value: Rav1dFrameType) -> Self {
value.into_rav1d()
}
}

impl TryFrom<Dav1dFrameType> for Rav1dFrameType {
type Error = ();

fn try_from(value: Dav1dFrameType) -> Result<Self, Self::Error> {
Self::from_repr(value as usize).ok_or(())
}
}

pub(crate) type Rav1dFrameType = c_uint;
pub(crate) const RAV1D_FRAME_TYPE_SWITCH: Rav1dFrameType = DAV1D_FRAME_TYPE_SWITCH;
pub(crate) const RAV1D_FRAME_TYPE_INTRA: Rav1dFrameType = DAV1D_FRAME_TYPE_INTRA;
pub(crate) const RAV1D_FRAME_TYPE_INTER: Rav1dFrameType = DAV1D_FRAME_TYPE_INTER;
pub(crate) const RAV1D_FRAME_TYPE_KEY: Rav1dFrameType = DAV1D_FRAME_TYPE_KEY;
impl Rav1dFrameType {
pub const fn is_inter_or_switch(&self) -> bool {
matches!(self, Self::Inter | Self::Switch)
}

pub const fn is_key_or_intra(&self) -> bool {
matches!(self, Self::Key | Self::Intra)
}
}

pub type Dav1dColorPrimaries = c_uint;
pub const DAV1D_COLOR_PRI_RESERVED: Dav1dColorPrimaries = 255;
Expand Down Expand Up @@ -2247,7 +2273,7 @@ impl From<Dav1dFrameHeader> for Rav1dFrameHeader {
have_render_size,
},
film_grain: film_grain.into(),
frame_type,
frame_type: frame_type.try_into().unwrap(),
frame_offset,
temporal_id,
spatial_id,
Expand Down Expand Up @@ -2353,7 +2379,7 @@ impl From<Rav1dFrameHeader> for Dav1dFrameHeader {
} = value;
Self {
film_grain: film_grain.into(),
frame_type,
frame_type: frame_type.into(),
width,
height,
frame_offset,
Expand Down
1 change: 0 additions & 1 deletion lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ pub mod include {
pub(crate) mod attributes;
pub(crate) mod bitdepth;
pub(crate) mod dump;
pub mod frame;
pub(crate) mod intops;
pub(crate) mod validate;
} // mod common
Expand Down
43 changes: 22 additions & 21 deletions src/decode.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::include::common::attributes::ctz;
use crate::include::common::bitdepth::DynCoef;
use crate::include::common::bitdepth::DynPixel;
use crate::include::common::frame::is_inter_or_switch;
use crate::include::common::frame::is_key_or_intra;
use crate::include::common::intops::apply_sign64;
use crate::include::common::intops::iclip;
use crate::include::common::intops::iclip_u8;
Expand Down Expand Up @@ -1513,7 +1511,7 @@ unsafe fn decode_b(
case.set(&mut dir.intra.0, 1);
},
);
if is_inter_or_switch(frame_hdr) {
if frame_hdr.frame_type.is_inter_or_switch() {
let r = t.rt.r[((t.by & 31) + 5 + bh4 - 1) as usize].offset(t.bx as isize);
for x in 0..bw4 {
let block = &mut *r.offset(x as isize);
Expand All @@ -1539,7 +1537,7 @@ unsafe fn decode_b(
);
}
} else {
if is_inter_or_switch(frame_hdr) /* not intrabc */
if frame_hdr.frame_type.is_inter_or_switch() /* not intrabc */
&& b.comp_type() == COMP_INTER_NONE
&& b.motion_mode() as MotionMode == MM_WARP
{
Expand Down Expand Up @@ -1587,7 +1585,7 @@ unsafe fn decode_b(
},
);

if is_inter_or_switch(frame_hdr) {
if frame_hdr.frame_type.is_inter_or_switch() {
let r = t.rt.r[((t.by & 31) + 5 + bh4 - 1) as usize].offset(t.bx as isize);
let r = std::slice::from_raw_parts_mut(r, bw4 as usize);
for r in r {
Expand Down Expand Up @@ -1902,7 +1900,7 @@ unsafe fn decode_b(

if b.skip_mode != 0 {
b.intra = 0;
} else if is_inter_or_switch(frame_hdr) {
} else if frame_hdr.frame_type.is_inter_or_switch() {
if let Some(seg) = seg.filter(|seg| seg.r#ref >= 0 || seg.globalmv != 0) {
b.intra = (seg.r#ref == 0) as u8;
} else {
Expand All @@ -1925,7 +1923,7 @@ unsafe fn decode_b(

// intra/inter-specific stuff
if b.intra != 0 {
let ymode_cdf = if frame_hdr.frame_type & 1 != 0 {
let ymode_cdf = if frame_hdr.frame_type.is_inter_or_switch() {
&mut ts.cdf.m.y_mode[dav1d_ymode_size_context[bs as usize] as usize]
} else {
&mut ts.cdf.kfym
Expand Down Expand Up @@ -2220,7 +2218,7 @@ unsafe fn decode_b(
&mut t.pal_sz_uv[dir_index],
if has_chroma { b.pal_sz()[1] } else { 0 },
);
if is_inter_or_switch(frame_hdr) {
if frame_hdr.frame_type.is_inter_or_switch() {
case.set(&mut dir.comp_type.0, COMP_INTER_NONE);
case.set(&mut dir.r#ref[0], -1);
case.set(&mut dir.r#ref[1], -1);
Expand Down Expand Up @@ -2272,10 +2270,10 @@ unsafe fn decode_b(
}
}
}
if is_inter_or_switch(frame_hdr) || frame_hdr.allow_intrabc != 0 {
if frame_hdr.frame_type.is_inter_or_switch() || frame_hdr.allow_intrabc != 0 {
splat_intraref(&*f.c, t, bs, bw4 as usize, bh4 as usize);
}
} else if is_key_or_intra(frame_hdr) {
} else if frame_hdr.frame_type.is_key_or_intra() {
// intra block copy
let mut mvstack = [Default::default(); 8];
let mut n_mvs = 0;
Expand Down Expand Up @@ -3262,7 +3260,7 @@ unsafe fn decode_b(
}
}

if t.frame_thread.pass == 1 && b.intra == 0 && frame_hdr.frame_type & 1 != 0 {
if t.frame_thread.pass == 1 && b.intra == 0 && frame_hdr.frame_type.is_inter_or_switch() {
let sby = t.by - ts.tiling.row_start >> f.sb_shift;
let lowest_px = &mut *ts.lowest_pixel.offset(sby as isize);
// keep track of motion vectors for each reference
Expand Down Expand Up @@ -4045,7 +4043,7 @@ pub(crate) unsafe fn rav1d_decode_tile_sbrow(t: &mut Rav1dTaskContext) -> Result
let col_sb_start = (*f.frame_hdr).tiling.col_start_sb[tile_col as usize] as c_int;
let col_sb128_start = col_sb_start >> ((*f.seq_hdr).sb128 == 0) as c_int;

if is_inter_or_switch(&*f.frame_hdr) || (*f.frame_hdr).allow_intrabc != 0 {
if (*f.frame_hdr).frame_type.is_inter_or_switch() || (*f.frame_hdr).allow_intrabc != 0 {
rav1d_refmvs_tile_sbrow_init(
&mut t.rt,
&f.rf,
Expand All @@ -4059,14 +4057,14 @@ pub(crate) unsafe fn rav1d_decode_tile_sbrow(t: &mut Rav1dTaskContext) -> Result
);
}

if is_inter_or_switch(&*f.frame_hdr) && c.n_fc > 1 {
if (*f.frame_hdr).frame_type.is_inter_or_switch() && c.n_fc > 1 {
let sby = t.by - ts.tiling.row_start >> f.sb_shift;
*ts.lowest_pixel.offset(sby as isize) = [[i32::MIN; 2]; 7];
}

reset_context(
&mut t.l,
is_key_or_intra(&*f.frame_hdr),
(*f.frame_hdr).frame_type.is_key_or_intra(),
t.frame_thread.pass,
);
if t.frame_thread.pass == 2 {
Expand Down Expand Up @@ -4199,7 +4197,10 @@ pub(crate) unsafe fn rav1d_decode_tile_sbrow(t: &mut Rav1dTaskContext) -> Result
}
}

if (*f.seq_hdr).ref_frame_mvs != 0 && (*f.c).n_tc > 1 && (*f.frame_hdr).frame_type & 1 != 0 {
if (*f.seq_hdr).ref_frame_mvs != 0
&& (*f.c).n_tc > 1
&& (*f.frame_hdr).frame_type.is_inter_or_switch()
{
rav1d_refmvs_save_tmvs(
&(*f.c).refmvs_dsp,
&mut t.rt,
Expand Down Expand Up @@ -4602,7 +4603,7 @@ pub(crate) unsafe fn rav1d_decode_frame_init(f: &mut Rav1dFrameContext) -> Rav1d
}

// init ref mvs
if is_inter_or_switch(&*f.frame_hdr) || (*f.frame_hdr).allow_intrabc != 0 {
if (*f.frame_hdr).frame_type.is_inter_or_switch() || (*f.frame_hdr).allow_intrabc != 0 {
let ret = rav1d_refmvs_init_frame(
&mut f.rf,
f.seq_hdr,
Expand Down Expand Up @@ -4768,7 +4769,7 @@ pub(crate) unsafe fn rav1d_decode_frame_init_cdf(f: &mut Rav1dFrameContext) -> R
{
reset_context(
ctx,
is_key_or_intra(&*f.frame_hdr),
(*f.frame_hdr).frame_type.is_key_or_intra(),
if uses_2pass {
1 + (n >= sb128w * rows) as c_int
} else {
Expand All @@ -4794,7 +4795,7 @@ unsafe fn rav1d_decode_frame_main(f: &mut Rav1dFrameContext) -> Rav1dResult {
f.a,
(f.sb128w * (*f.frame_hdr).tiling.rows).try_into().unwrap(),
) {
reset_context(ctx, is_key_or_intra(&*f.frame_hdr), 0);
reset_context(ctx, (*f.frame_hdr).frame_type.is_key_or_intra(), 0);
}

// no threading - we explicitly interleave tile/sbrow decoding
Expand Down Expand Up @@ -4829,7 +4830,7 @@ unsafe fn rav1d_decode_frame_main(f: &mut Rav1dFrameContext) -> Rav1dResult {
t.ts = tile;
rav1d_decode_tile_sbrow(t).map_err(|()| EINVAL)?;
}
if is_inter_or_switch(&*f.frame_hdr) {
if (*f.frame_hdr).frame_type.is_inter_or_switch() {
rav1d_refmvs_save_tmvs(
&(*f.c).refmvs_dsp,
&mut t.rt,
Expand Down Expand Up @@ -5097,7 +5098,7 @@ pub unsafe fn rav1d_submit_frame(c: &mut Rav1dContext) -> Rav1dResult {
}

let mut ref_coded_width = <[i32; 7]>::default();
if is_inter_or_switch(&*f.frame_hdr) {
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 c.refs[pri_ref].p.p.data[0].is_null() {
Expand Down Expand Up @@ -5218,7 +5219,7 @@ pub unsafe fn rav1d_submit_frame(c: &mut Rav1dContext) -> Rav1dResult {
);

// ref_mvs
if is_inter_or_switch(&*f.frame_hdr) || (*f.frame_hdr).allow_intrabc != 0 {
if (*f.frame_hdr).frame_type.is_inter_or_switch() || (*f.frame_hdr).allow_intrabc != 0 {
f.mvs_ref = rav1d_ref_create_using_pool(
c.refmvs_pool,
::core::mem::size_of::<refmvs_temporal_block>()
Expand Down
Loading

0 comments on commit a89336a

Please sign in to comment.