use std::num::NonZeroU8;
use anyhow::{Result, bail};
use bitflags::bitflags;
pub const MV_DEFAULT_SCD1: u64 = 400;
pub const MV_DEFAULT_SCD2: u64 = 130;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Subpel {
Full = 1,
Half = 2,
Quarter = 4,
}
impl Subpel {
#[must_use]
#[inline]
pub fn log(self) -> usize {
u8::from(self) as usize >> 1
}
}
impl TryFrom<i64> for Subpel {
type Error = anyhow::Error;
#[inline]
fn try_from(val: i64) -> Result<Self> {
Ok(match val {
1 => Self::Full,
2 => Self::Half,
4 => Self::Quarter,
_ => bail!("Invalid value for 'pel', must be 1, 2, or 4, got {val}."),
})
}
}
impl From<Subpel> for u8 {
#[inline]
fn from(value: Subpel) -> Self {
match value {
Subpel::Full => 1,
Subpel::Half => 2,
Subpel::Quarter => 4,
}
}
}
impl From<Subpel> for NonZeroU8 {
#[inline]
fn from(value: Subpel) -> Self {
unsafe { NonZeroU8::new_unchecked(u8::from(value)) }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SubpelMethod {
Bilinear = 0,
Bicubic = 1,
Wiener = 2,
}
impl TryFrom<i64> for SubpelMethod {
type Error = anyhow::Error;
#[inline]
fn try_from(val: i64) -> Result<Self> {
Ok(match val {
0 => Self::Bilinear,
1 => Self::Bicubic,
2 => Self::Wiener,
_ => bail!("Invalid value for 'sharp', must be 0-2, got {val}."),
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReduceFilter {
Average = 0,
Triangle = 1,
Bilinear = 2,
Quadratic = 3,
Cubic = 4,
}
impl TryFrom<i64> for ReduceFilter {
type Error = anyhow::Error;
#[inline]
fn try_from(val: i64) -> Result<Self> {
Ok(match val {
0 => Self::Average,
1 => Self::Triangle,
2 => Self::Bilinear,
3 => Self::Quadratic,
4 => Self::Cubic,
_ => bail!("Invalid value for 'rfilter', must be 0-4, got {val}."),
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SearchType {
Onetime = 0,
Nstep = 1,
Logarithmic = 2,
Exhaustive = 3,
Hex2 = 4,
UnevenMultiHexagon = 5,
Horizontal = 6,
Vertical = 7,
}
impl TryFrom<i64> for SearchType {
type Error = anyhow::Error;
#[inline]
fn try_from(val: i64) -> Result<Self> {
Ok(match val {
0 => Self::Onetime,
1 => Self::Nstep,
2 => Self::Logarithmic,
3 => Self::Exhaustive,
4 => Self::Hex2,
5 => Self::UnevenMultiHexagon,
6 => Self::Horizontal,
7 => Self::Vertical,
_ => bail!("Invalid value for 'search', must be 0-7, got {val}."),
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DctMode {
Spatial = 0,
Dct = 1,
MixedSpatialDct = 2,
AdaptiveSpatialMixed = 3,
AdaptiveSpatialDct = 4,
Satd = 5,
MixedSatdDct = 6,
AdaptiveSatdMixed = 7,
AdaptiveSatdDct = 8,
MixedSadEqSatdDct = 9,
AdaptiveSatdLuma = 10,
}
impl TryFrom<i64> for DctMode {
type Error = anyhow::Error;
#[inline]
fn try_from(val: i64) -> Result<Self> {
Ok(match val {
0 => Self::Spatial,
1 => Self::Dct,
2 => Self::MixedSpatialDct,
3 => Self::AdaptiveSpatialMixed,
4 => Self::AdaptiveSpatialDct,
5 => Self::Satd,
6 => Self::MixedSatdDct,
7 => Self::AdaptiveSatdMixed,
8 => Self::AdaptiveSatdDct,
9 => Self::MixedSadEqSatdDct,
10 => Self::AdaptiveSatdLuma,
_ => bail!("Invalid value for 'dct', must be 0-10, got {val}."),
})
}
}
impl From<DctMode> for u8 {
#[inline]
fn from(value: DctMode) -> Self {
match value {
DctMode::Spatial => 0,
DctMode::Dct => 1,
DctMode::MixedSpatialDct => 2,
DctMode::AdaptiveSpatialMixed => 3,
DctMode::AdaptiveSpatialDct => 4,
DctMode::Satd => 5,
DctMode::MixedSatdDct => 6,
DctMode::AdaptiveSatdMixed => 7,
DctMode::AdaptiveSatdDct => 8,
DctMode::MixedSadEqSatdDct => 9,
DctMode::AdaptiveSatdLuma => 10,
}
}
}
impl DctMode {
#[must_use]
#[inline]
pub const fn uses_satd(self) -> bool {
matches!(
self,
DctMode::Satd
| DctMode::MixedSatdDct
| DctMode::AdaptiveSatdMixed
| DctMode::AdaptiveSatdDct
| DctMode::MixedSadEqSatdDct
| DctMode::AdaptiveSatdLuma
)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PenaltyScaling {
None = 0,
Linear = 1,
Quadratic = 2,
}
impl TryFrom<i64> for PenaltyScaling {
type Error = anyhow::Error;
#[inline]
fn try_from(val: i64) -> Result<Self> {
Ok(match val {
0 => Self::None,
1 => Self::Linear,
2 => Self::Quadratic,
_ => bail!("Invalid value for 'plevel', must be 0-2, got {val}."),
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DivideMode {
None = 0,
Original = 1,
Median = 2,
}
impl TryFrom<i64> for DivideMode {
type Error = anyhow::Error;
#[inline]
fn try_from(val: i64) -> Result<Self> {
Ok(match val {
0 => Self::None,
1 => Self::Original,
2 => Self::Median,
_ => bail!("Invalid value for 'divide', must be 0-2, got {val}."),
})
}
}
bitflags! {
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MotionFlags: u8 {
const IS_BACKWARD = 0x00000002;
const SMALLEST_PLANE = 0x00000004;
const USE_CHROMA_MOTION = 0x00000008;
const USE_SSD = 0x00000010;
const USE_SATD = 0x00000020;
}
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MVPlaneSet: u8 {
const YPLANE = (1 << 0);
const UPLANE = (1 << 1);
const VPLANE = (1 << 2);
const YUPLANES = Self::YPLANE.bits() | Self::UPLANE.bits();
const YVPLANES = Self::YPLANE.bits() | Self::VPLANE.bits();
const UVPLANES = Self::UPLANE.bits() | Self::VPLANE.bits();
const YUVPLANES = Self::YPLANE.bits() | Self::UPLANE.bits() | Self::VPLANE.bits();
}
}
impl From<PlaneSelection> for MVPlaneSet {
#[inline]
fn from(value: PlaneSelection) -> Self {
match value {
PlaneSelection::Luma => Self::YPLANE,
PlaneSelection::ChromaU => Self::UPLANE,
PlaneSelection::ChromaV => Self::VPLANE,
PlaneSelection::ChromaBoth => Self::UVPLANES,
PlaneSelection::All => Self::YUVPLANES,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum SceneChangeBehavior {
ReferenceFrame = 0,
#[default]
CurrentFrame = 1,
}
impl TryFrom<i64> for SceneChangeBehavior {
type Error = anyhow::Error;
#[inline]
fn try_from(val: i64) -> Result<Self> {
Ok(match val {
0 => Self::ReferenceFrame,
1 => Self::CurrentFrame,
_ => bail!("Invalid value for 'scbehavior', must be 0 or 1, got {val}."),
})
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq)]
pub enum PlaneSelection {
Luma = 0,
ChromaU = 1,
ChromaV = 2,
ChromaBoth = 3,
#[default]
All = 4,
}
impl TryFrom<i64> for PlaneSelection {
type Error = anyhow::Error;
#[inline]
fn try_from(val: i64) -> Result<Self> {
Ok(match val {
0 => Self::Luma,
1 => Self::ChromaU,
2 => Self::ChromaV,
3 => Self::ChromaBoth,
4 => Self::All,
_ => bail!("Invalid value for 'plane', must be 0-4, got {val}."),
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum MaskKind {
#[default]
VectorLength = 0,
SadMask = 1,
OcclusionMask = 2,
HorizontalMotion = 3,
VerticalMotion = 4,
MotionColormap = 5,
}
impl TryFrom<i64> for MaskKind {
type Error = anyhow::Error;
#[inline]
fn try_from(val: i64) -> Result<Self> {
Ok(match val {
0 => Self::VectorLength,
1 => Self::SadMask,
2 => Self::OcclusionMask,
3 => Self::HorizontalMotion,
4 => Self::VerticalMotion,
5 => Self::MotionColormap,
_ => bail!("Invalid value for 'kind', must be 0-5, got {val}."),
})
}
}