zoomvtools 1.1.1

Video motion vector analysis utilities in pure Rust
Documentation
use std::mem::size_of;

use bitflags::bitflags;

pub(crate) const MV_SIZE: usize = size_of::<MotionVector>();

#[repr(C)]
#[derive(Debug, Clone, Copy)]
/// One motion vector and its matching cost.
pub struct MotionVector {
    /// Horizontal displacement in subpixel units of the owning analysis level.
    pub x: i32,
    /// Vertical displacement in subpixel units of the owning analysis level.
    pub y: i32,
    /// Matching cost associated with this vector.
    pub sad: i64,
}

impl MotionVector {
    /// computes square distance between two vectors
    #[must_use]
    #[inline]
    pub(crate) const fn square_difference_norm(v1: MotionVector, v2: MotionVector) -> u64 {
        ((v1.x - v2.x).pow(2) + (v1.y - v2.y).pow(2)) as u64
    }
}

impl MotionVector {
    #[must_use]
    pub(crate) const fn bytes(&self) -> &[u8] {
        // SAFETY: We've added `repr(c)` to ensure a predictable size of the struct
        unsafe {
            std::slice::from_raw_parts(
                self as *const Self as *const u8,
                std::mem::size_of::<Self>(),
            )
        }
    }
}

bitflags! {
    /// Bitflags for motion vector checking options.
    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
    pub(crate) struct CheckMVFlags: u32 {
        /// Penalty for new motion vectors.
        const PENALTY_NEW = 1 << 1;
        /// Update direction during motion vector checking.
        const UPDATE_DIR = 1 << 2;
        /// Update best motion vector during checking.
        const UPDATE_BEST_MV = 1 << 3;
    }
}

impl MotionVector {
    #[must_use]
    #[inline]
    pub(crate) const fn zero() -> Self {
        MotionVector {
            x: 0,
            y: 0,
            sad: -1,
        }
    }
}

impl Default for MotionVector {
    #[inline]
    fn default() -> Self {
        Self::zero()
    }
}