#![allow(dead_code)]
#![allow(clippy::doc_markdown)]
#![allow(clippy::needless_range_loop)]
pub const CDF_PROB_BITS: u8 = 15;
pub const CDF_PROB_TOP: u16 = 1 << CDF_PROB_BITS;
pub const CDF_INIT_COUNT: u16 = 0;
pub const CDF_MAX_COUNT: u16 = 32;
pub const PARTITION_CONTEXTS: usize = 4;
pub const PARTITION_TYPES: usize = 10;
pub const DEFAULT_PARTITION_CDF_0: [u16; 11] = [
15588, 17570, 19323, 21084, 22472, 24311, 25744, 27999, 29223, 32768, 0,
];
pub const DEFAULT_PARTITION_CDF_1: [u16; 11] = [
12064, 14616, 17239, 19824, 21631, 24068, 25919, 28400, 29760, 32768, 0,
];
pub const DEFAULT_PARTITION_CDF_2: [u16; 11] = [
9216, 12096, 15424, 18432, 20672, 23424, 25664, 28544, 30080, 32768, 0,
];
pub const DEFAULT_PARTITION_CDF_3: [u16; 11] = [
6144, 9472, 13312, 16896, 19584, 22912, 25600, 28800, 30464, 32768, 0,
];
pub const DEFAULT_PARTITION_CDFS: [[u16; 11]; PARTITION_CONTEXTS] = [
DEFAULT_PARTITION_CDF_0,
DEFAULT_PARTITION_CDF_1,
DEFAULT_PARTITION_CDF_2,
DEFAULT_PARTITION_CDF_3,
];
pub const INTRA_MODES: usize = 13;
pub const INTRA_Y_MODE_CONTEXTS: usize = 4;
pub const DEFAULT_Y_MODE_CDF_0: [u16; 14] = [
15588, 17570, 18800, 20000, 21500, 23000, 24500, 26000, 27500, 29000, 30500, 31500, 32768, 0,
];
pub const DEFAULT_Y_MODE_CDF_1: [u16; 14] = [
12064, 14616, 16500, 18500, 20500, 22500, 24500, 26500, 28000, 29500, 30750, 31750, 32768, 0,
];
pub const DEFAULT_Y_MODE_CDF_2: [u16; 14] = [
9216, 12096, 14500, 17000, 19500, 22000, 24500, 26500, 28500, 30000, 31000, 32000, 32768, 0,
];
pub const DEFAULT_Y_MODE_CDF_3: [u16; 14] = [
6144, 9472, 12500, 15500, 18500, 21500, 24500, 27000, 29000, 30500, 31250, 32000, 32768, 0,
];
pub const DEFAULT_Y_MODE_CDFS: [[u16; 14]; INTRA_Y_MODE_CONTEXTS] = [
DEFAULT_Y_MODE_CDF_0,
DEFAULT_Y_MODE_CDF_1,
DEFAULT_Y_MODE_CDF_2,
DEFAULT_Y_MODE_CDF_3,
];
pub const INTRA_UV_MODE_CONTEXTS: usize = 13;
pub const DEFAULT_UV_MODE_CDF_NO_CFL: [u16; 14] = [
22528, 24320, 25344, 26368, 27136, 28160, 28928, 29696, 30464, 31104, 31616, 32128, 32768, 0,
];
pub const DEFAULT_UV_MODE_CDF_CFL: [u16; 15] = [
18432, 20480, 22016, 23296, 24576, 25856, 27136, 28160, 29184, 30080, 30848, 31488, 32000,
32768, 0,
];
pub const TX_SIZE_CONTEXTS: usize = 3;
pub const MAX_TX_CATS: usize = 4;
pub const DEFAULT_TX_SIZE_CDF_8X8: [u16; 3] = [16384, 32768, 0];
pub const DEFAULT_TX_SIZE_CDF_16X16: [u16; 4] = [10923, 21845, 32768, 0];
pub const DEFAULT_TX_SIZE_CDF_32X32: [u16; 5] = [8192, 16384, 24576, 32768, 0];
pub const DEFAULT_TX_SIZE_CDF_64X64: [u16; 6] = [6554, 13107, 19661, 26214, 32768, 0];
pub const TX_TYPE_CONTEXTS: usize = 7;
pub const INTRA_TX_TYPES: usize = 7;
pub const INTER_TX_TYPES: usize = 16;
pub const DEFAULT_INTRA_TX_TYPE_4X4: [[u16; 8]; TX_TYPE_CONTEXTS] = [
[5461, 10923, 16384, 21845, 24576, 27307, 30037, 32768],
[4681, 9362, 14043, 18725, 22118, 25512, 28905, 32768],
[4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768],
[3641, 7282, 10923, 14564, 18893, 23222, 27551, 32768],
[3277, 6554, 9830, 13107, 17476, 21845, 26214, 32768],
[2979, 5958, 8937, 11916, 16213, 20511, 25228, 32768],
[2731, 5461, 8192, 10923, 15019, 19114, 24064, 32768],
];
pub const DEFAULT_INTRA_TX_TYPE_8X8: [[u16; 8]; TX_TYPE_CONTEXTS] = [
[6144, 12288, 18432, 24576, 26624, 28672, 30720, 32768],
[5461, 10923, 16384, 21845, 24576, 27307, 30037, 32768],
[4915, 9830, 14745, 19660, 22938, 26214, 29491, 32768],
[4455, 8909, 13364, 17818, 21399, 24980, 28561, 32768],
[4096, 8192, 12288, 16384, 20070, 23756, 27852, 32768],
[3780, 7559, 11339, 15119, 18897, 22675, 27200, 32768],
[3495, 6991, 10486, 13981, 17827, 21673, 26600, 32768],
];
pub const DEFAULT_INTER_TX_TYPE: [[u16; 17]; TX_TYPE_CONTEXTS] = [
[
2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432, 20480, 22528, 24576, 26624,
28672, 30720, 32768, 0,
],
[
2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432, 20480, 22528, 24576, 26624,
28672, 30720, 32768, 0,
],
[
2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432, 20480, 22528, 24576, 26624,
28672, 30720, 32768, 0,
],
[
2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432, 20480, 22528, 24576, 26624,
28672, 30720, 32768, 0,
],
[
2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432, 20480, 22528, 24576, 26624,
28672, 30720, 32768, 0,
],
[
2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432, 20480, 22528, 24576, 26624,
28672, 30720, 32768, 0,
],
[
2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432, 20480, 22528, 24576, 26624,
28672, 30720, 32768, 0,
],
];
pub const EOB_MULTI_CONTEXTS: usize = 7;
pub const DEFAULT_EOB_MULTI_2: [u16; 3] = [16384, 32768, 0];
pub const DEFAULT_EOB_MULTI_4: [u16; 5] = [8192, 16384, 24576, 32768, 0];
pub const DEFAULT_EOB_MULTI_8: [u16; 9] = [4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 0];
pub const DEFAULT_EOB_MULTI_16: [u16; 17] = [
2048, 4096, 6144, 8192, 10240, 12288, 14336, 16384, 18432, 20480, 22528, 24576, 26624, 28672,
30720, 32768, 0,
];
pub const COEFF_BASE_CTX_COUNT: usize = 42;
pub const DEFAULT_COEFF_BASE_CDF: [u16; 5] = [8192, 16384, 24576, 32768, 0];
pub const DEFAULT_COEFF_BASE_EOB_CDF: [u16; 4] = [10923, 21845, 32768, 0];
pub const DC_SIGN_CTX_COUNT: usize = 3;
pub const DEFAULT_DC_SIGN_CDF: [u16; 3] = [16384, 32768, 0];
pub const COEFF_BR_CTX_COUNT: usize = 21;
pub const DEFAULT_COEFF_BR_CDF: [u16; 4] = [10923, 21845, 32768, 0];
pub const MV_JOINTS: usize = 4;
pub const DEFAULT_MV_JOINT_CDF: [u16; 5] = [4096, 11264, 19712, 32768, 0];
pub const MV_CLASSES: usize = 11;
pub const DEFAULT_MV_CLASS_CDF: [u16; 12] = [
28672, 30976, 31744, 32128, 32320, 32448, 32544, 32608, 32672, 32720, 32768, 0,
];
pub const DEFAULT_MV_CLASS0_BIT_CDF: [u16; 3] = [16384, 32768, 0];
pub const MV_CLASS0_FP: usize = 4;
pub const DEFAULT_MV_CLASS0_FP_CDF: [[u16; 5]; 2] = [
[8192, 16384, 24576, 32768, 0],
[8192, 16384, 24576, 32768, 0],
];
pub const MV_FP: usize = 4;
pub const DEFAULT_MV_FP_CDF: [u16; 5] = [8192, 16384, 24576, 32768, 0];
pub const DEFAULT_MV_CLASS0_HP_CDF: [u16; 3] = [16384, 32768, 0];
pub const DEFAULT_MV_HP_CDF: [u16; 3] = [16384, 32768, 0];
pub const DEFAULT_MV_SIGN_CDF: [u16; 3] = [16384, 32768, 0];
pub const MV_OFFSET_BITS: usize = 10;
pub const DEFAULT_MV_BITS_CDF: [[u16; 3]; MV_OFFSET_BITS] = [
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
];
pub const SKIP_CONTEXTS: usize = 3;
pub const DEFAULT_SKIP_CDF: [[u16; 3]; SKIP_CONTEXTS] =
[[24576, 32768, 0], [16384, 32768, 0], [8192, 32768, 0]];
pub const MAX_SEGMENTS: usize = 8;
pub const DEFAULT_SEGMENT_TREE_CDF: [u16; 9] =
[4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 0];
pub const DEFAULT_SEGMENT_PRED_CDF: [[u16; 3]; 3] =
[[16384, 32768, 0], [16384, 32768, 0], [16384, 32768, 0]];
pub const REF_CONTEXTS: usize = 3;
pub const SINGLE_REF_TYPES: usize = 7;
pub const DEFAULT_SINGLE_REF_CDF: [[[u16; 3]; SINGLE_REF_TYPES]; REF_CONTEXTS] = [
[
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
],
[
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
],
[
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
[16384, 32768, 0],
],
];
pub const INTER_MODE_CONTEXTS: usize = 8;
pub const INTER_MODES: usize = 4;
pub const DEFAULT_INTER_MODE_CDF: [[u16; 5]; INTER_MODE_CONTEXTS] = [
[2048, 10240, 17664, 32768, 0],
[4096, 12288, 20480, 32768, 0],
[6144, 14336, 22528, 32768, 0],
[8192, 16384, 24576, 32768, 0],
[10240, 18432, 26624, 32768, 0],
[12288, 20480, 28672, 32768, 0],
[14336, 22528, 29696, 32768, 0],
[16384, 24576, 30720, 32768, 0],
];
pub const COMPOUND_MODE_CONTEXTS: usize = 8;
pub const COMPOUND_MODES: usize = 8;
pub const DEFAULT_COMPOUND_MODE_CDF: [[u16; 9]; COMPOUND_MODE_CONTEXTS] = [
[4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 0],
[4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 0],
[4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 0],
[4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 0],
[4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 0],
[4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 0],
[4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 0],
[4096, 8192, 12288, 16384, 20480, 24576, 28672, 32768, 0],
];
pub const INTERP_FILTERS: usize = 4;
pub const INTERP_FILTER_CONTEXTS: usize = 16;
pub const DEFAULT_INTERP_FILTER_CDF: [[u16; 5]; INTERP_FILTER_CONTEXTS] = [
[6144, 12288, 18432, 32768, 0],
[6144, 12288, 18432, 32768, 0],
[6144, 12288, 18432, 32768, 0],
[6144, 12288, 18432, 32768, 0],
[8192, 16384, 24576, 32768, 0],
[8192, 16384, 24576, 32768, 0],
[8192, 16384, 24576, 32768, 0],
[8192, 16384, 24576, 32768, 0],
[10240, 18432, 26624, 32768, 0],
[10240, 18432, 26624, 32768, 0],
[10240, 18432, 26624, 32768, 0],
[10240, 18432, 26624, 32768, 0],
[12288, 20480, 28672, 32768, 0],
[12288, 20480, 28672, 32768, 0],
[12288, 20480, 28672, 32768, 0],
[12288, 20480, 28672, 32768, 0],
];
#[must_use]
#[allow(clippy::cast_possible_truncation)]
pub fn create_uniform_cdf(n: usize) -> Vec<u16> {
let mut cdf = Vec::with_capacity(n + 1);
for i in 1..=n {
cdf.push(((i * CDF_PROB_TOP as usize) / n) as u16);
}
cdf.push(CDF_INIT_COUNT); cdf
}
#[allow(clippy::cast_possible_truncation)]
pub fn update_cdf(cdf: &mut [u16], symbol: usize) {
let n = cdf.len() - 1; if n == 0 {
return;
}
let count = u32::from(cdf[n]);
let rate = 3 + (count >> 4);
let rate = rate.min(32);
for i in 0..n {
if i < symbol {
let diff = cdf[i] >> rate;
cdf[i] = cdf[i].saturating_sub(diff);
} else {
let diff = CDF_PROB_TOP.saturating_sub(cdf[i]) >> rate;
cdf[i] = cdf[i].saturating_add(diff);
}
}
if count < u32::from(CDF_MAX_COUNT) {
cdf[n] += 1;
}
}
#[allow(clippy::cast_possible_truncation)]
pub fn reset_cdf_uniform(cdf: &mut [u16]) {
let n = cdf.len() - 1;
if n == 0 {
return;
}
for i in 0..n {
cdf[i] = (((i + 1) * CDF_PROB_TOP as usize) / n) as u16;
}
cdf[n] = CDF_INIT_COUNT;
}
pub fn copy_cdf(dst: &mut [u16], src: &[u16]) {
let len = dst.len().min(src.len());
dst[..len].copy_from_slice(&src[..len]);
}
#[must_use]
pub fn is_valid_cdf(cdf: &[u16]) -> bool {
if cdf.len() < 2 {
return false;
}
let n = cdf.len() - 1;
for i in 1..n {
if cdf[i] < cdf[i - 1] {
return false;
}
}
cdf[n - 1] == CDF_PROB_TOP
}
#[derive(Clone, Debug)]
pub struct CdfContext {
pub partition: [[u16; 11]; PARTITION_CONTEXTS],
pub y_mode: [[u16; 14]; INTRA_Y_MODE_CONTEXTS],
pub skip: [[u16; 3]; SKIP_CONTEXTS],
pub mv_joint: [u16; 5],
pub mv_sign: [[u16; 3]; 2],
pub mv_class: [[u16; 12]; 2],
pub dc_sign: [[u16; 3]; DC_SIGN_CTX_COUNT],
pub coeff_base: Vec<[u16; 5]>,
pub coeff_br: Vec<[u16; 4]>,
}
impl CdfContext {
#[must_use]
pub fn new() -> Self {
Self {
partition: DEFAULT_PARTITION_CDFS,
y_mode: DEFAULT_Y_MODE_CDFS,
skip: DEFAULT_SKIP_CDF,
mv_joint: DEFAULT_MV_JOINT_CDF,
mv_sign: [DEFAULT_MV_SIGN_CDF, DEFAULT_MV_SIGN_CDF],
mv_class: [DEFAULT_MV_CLASS_CDF, DEFAULT_MV_CLASS_CDF],
dc_sign: [DEFAULT_DC_SIGN_CDF; DC_SIGN_CTX_COUNT],
coeff_base: vec![DEFAULT_COEFF_BASE_CDF; COEFF_BASE_CTX_COUNT],
coeff_br: vec![DEFAULT_COEFF_BR_CDF; COEFF_BR_CTX_COUNT],
}
}
pub fn reset(&mut self) {
self.partition = DEFAULT_PARTITION_CDFS;
self.y_mode = DEFAULT_Y_MODE_CDFS;
self.skip = DEFAULT_SKIP_CDF;
self.mv_joint = DEFAULT_MV_JOINT_CDF;
self.mv_sign = [DEFAULT_MV_SIGN_CDF, DEFAULT_MV_SIGN_CDF];
self.mv_class = [DEFAULT_MV_CLASS_CDF, DEFAULT_MV_CLASS_CDF];
self.dc_sign = [DEFAULT_DC_SIGN_CDF; DC_SIGN_CTX_COUNT];
for cdf in &mut self.coeff_base {
*cdf = DEFAULT_COEFF_BASE_CDF;
}
for cdf in &mut self.coeff_br {
*cdf = DEFAULT_COEFF_BR_CDF;
}
}
#[must_use]
pub fn get_partition_cdf(&self, ctx: usize) -> &[u16; 11] {
&self.partition[ctx.min(PARTITION_CONTEXTS - 1)]
}
pub fn get_partition_cdf_mut(&mut self, ctx: usize) -> &mut [u16; 11] {
&mut self.partition[ctx.min(PARTITION_CONTEXTS - 1)]
}
#[must_use]
pub fn get_y_mode_cdf(&self, ctx: usize) -> &[u16; 14] {
&self.y_mode[ctx.min(INTRA_Y_MODE_CONTEXTS - 1)]
}
#[must_use]
pub fn get_skip_cdf(&self, ctx: usize) -> &[u16; 3] {
&self.skip[ctx.min(SKIP_CONTEXTS - 1)]
}
#[must_use]
pub fn get_eob_multi_cdf(&self, _ctx: usize) -> &[u16] {
&[8192, 16384, 24576, 32768]
}
#[must_use]
pub fn get_coeff_base_cdf(&self, ctx: usize) -> &[u16] {
if ctx < self.coeff_base.len() {
&self.coeff_base[ctx]
} else {
&DEFAULT_COEFF_BASE_CDF
}
}
#[must_use]
pub fn get_coeff_base_eob_cdf(&self, ctx: usize) -> &[u16] {
self.get_coeff_base_cdf(ctx)
}
#[must_use]
pub fn get_coeff_br_cdf(&self, ctx: usize) -> &[u16] {
if ctx < self.coeff_br.len() {
&self.coeff_br[ctx]
} else {
&DEFAULT_COEFF_BR_CDF
}
}
#[must_use]
pub fn get_dc_sign_cdf(&self, ctx: usize) -> &[u16] {
&self.dc_sign[ctx.min(DC_SIGN_CTX_COUNT - 1)]
}
pub fn get_eob_multi_cdf_mut(&mut self, _ctx: usize) -> &mut [u16] {
if !self.coeff_base.is_empty() {
let len = self.coeff_base[0].len();
let max_len = 4.min(len);
if max_len > 0 {
return &mut self.coeff_base[0][..max_len];
}
}
if !self.dc_sign.is_empty() {
&mut self.dc_sign[0][..0]
} else {
&mut []
}
}
pub fn get_coeff_base_cdf_mut(&mut self, ctx: usize) -> &mut [u16] {
if ctx < self.coeff_base.len() {
&mut self.coeff_base[ctx]
} else if !self.coeff_base.is_empty() {
&mut self.coeff_base[0]
} else {
&mut []
}
}
pub fn get_coeff_base_eob_cdf_mut(&mut self, ctx: usize) -> &mut [u16] {
self.get_coeff_base_cdf_mut(ctx)
}
pub fn get_coeff_br_cdf_mut(&mut self, ctx: usize) -> &mut [u16] {
if ctx < self.coeff_br.len() {
&mut self.coeff_br[ctx]
} else if !self.coeff_br.is_empty() {
&mut self.coeff_br[0]
} else {
&mut []
}
}
pub fn get_dc_sign_cdf_mut(&mut self, ctx: usize) -> &mut [u16] {
let idx = ctx.min(DC_SIGN_CTX_COUNT - 1);
&mut self.dc_sign[idx]
}
}
impl Default for CdfContext {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_uniform_cdf() {
let cdf = create_uniform_cdf(4);
assert_eq!(cdf.len(), 5);
assert_eq!(cdf[0], 8192);
assert_eq!(cdf[1], 16384);
assert_eq!(cdf[2], 24576);
assert_eq!(cdf[3], 32768);
assert_eq!(cdf[4], 0); }
#[test]
fn test_update_cdf() {
let mut cdf = create_uniform_cdf(4);
let orig_0 = cdf[0];
update_cdf(&mut cdf, 0);
assert!(cdf[0] >= orig_0);
}
#[test]
fn test_reset_cdf_uniform() {
let mut cdf = vec![0u16; 5];
reset_cdf_uniform(&mut cdf);
assert_eq!(cdf[0], 8192);
assert_eq!(cdf[3], 32768);
assert_eq!(cdf[4], 0);
}
#[test]
fn test_copy_cdf() {
let src = create_uniform_cdf(4);
let mut dst = vec![0u16; 5];
copy_cdf(&mut dst, &src);
assert_eq!(dst, src);
}
#[test]
fn test_is_valid_cdf() {
let valid_cdf = create_uniform_cdf(4);
assert!(is_valid_cdf(&valid_cdf));
let invalid_cdf = vec![100u16, 50, 200, 32768, 0]; assert!(!is_valid_cdf(&invalid_cdf));
}
#[test]
fn test_cdf_context_new() {
let ctx = CdfContext::new();
assert_eq!(ctx.partition.len(), PARTITION_CONTEXTS);
assert_eq!(ctx.y_mode.len(), INTRA_Y_MODE_CONTEXTS);
}
#[test]
fn test_cdf_context_reset() {
let mut ctx = CdfContext::new();
ctx.partition[0][0] = 12345;
ctx.reset();
assert_eq!(ctx.partition[0], DEFAULT_PARTITION_CDFS[0]);
}
#[test]
fn test_get_partition_cdf() {
let ctx = CdfContext::new();
let cdf = ctx.get_partition_cdf(0);
assert_eq!(cdf, &DEFAULT_PARTITION_CDF_0);
let cdf_clamped = ctx.get_partition_cdf(100);
assert_eq!(cdf_clamped, &DEFAULT_PARTITION_CDF_3);
}
#[test]
fn test_default_cdfs_valid() {
for cdf in &DEFAULT_PARTITION_CDFS {
assert!(is_valid_cdf(cdf));
}
for cdf in &DEFAULT_Y_MODE_CDFS {
assert!(is_valid_cdf(cdf));
}
assert!(is_valid_cdf(&DEFAULT_MV_JOINT_CDF));
assert!(is_valid_cdf(&DEFAULT_MV_CLASS_CDF));
}
#[test]
fn test_cdf_constants() {
assert_eq!(CDF_PROB_BITS, 15);
assert_eq!(CDF_PROB_TOP, 32768);
assert_eq!(CDF_MAX_COUNT, 32);
}
#[test]
fn test_partition_contexts() {
assert_eq!(PARTITION_CONTEXTS, 4);
assert_eq!(PARTITION_TYPES, 10);
}
#[test]
fn test_intra_mode_contexts() {
assert_eq!(INTRA_MODES, 13);
assert_eq!(INTRA_Y_MODE_CONTEXTS, 4);
}
#[test]
fn test_mv_constants() {
assert_eq!(MV_JOINTS, 4);
assert_eq!(MV_CLASSES, 11);
assert_eq!(MV_OFFSET_BITS, 10);
}
}