Files
deckcraft/crates/av1/src/cdf.rs
T
Brandon ThomasandClaude Opus 5.5 4375fe7b89 Media playback: slidecraft-media (probe, audio decode, H.264/HEVC/VP9/AV1 video, mixer and clock), cpal output, editor control bar, slide show playback, media.* commands
- crates/media: probe (duration, rate/channels, size/fps; WMA/WMV recognised), audio decode to
  f32 PCM (MP3, AAC M4A/ADTS, ALAC, WAV, AIFF, CAF, FLAC, Vorbis via symphonia; Opus with our
  decoder in Ogg/WebM/MKV), video decode (MP4/MOV/WebM/MKV) with YUV->RGBA, poster frames,
  trim/fade/volume, Player mixer + per-voice clock (device-clocked or wall-clocked), VideoFeed.
- Codec crates ported from FilmCraft: bitstream, h264, hevc, vp9, av1, isobmff, matroska, ogg, opus.
- insert.audio/insert.video probe and store duration/size and a poster frame; unplayable media
  is embedded with a warning. New media.play/pause/toggle/stop/seek/info/posterFrame.
- UI: MediaHost (cpal output injected by the desktop app), control bar under media, video frames
  on canvas and in the show; autoplay, click to play, loop, rewind, across slides, hide, full screen.
- Tests with in-code WAV/AIFF and CC0 self-generated fixtures (make.sh, ATTRIBUTION.md rows).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 01:35:09 -04:00

360 lines
14 KiB
Rust

//! The adaptive CDF arrays (spec 6.8.2 init_non_coeff_cdfs / init_coeff_cdfs, load_cdfs).
use crate::spec_tables::*;
/// Every CDF array listed by init_non_coeff_cdfs and init_coeff_cdfs. Each innermost array holds
/// N cumulative values (the last is 32768) plus the adaptation counter.
#[derive(Clone)]
pub(crate) struct Cdfs {
pub y_mode: [[u16; 14]; 4],
pub uv_mode_cfl_not_allowed: [[u16; 14]; 13],
pub uv_mode_cfl_allowed: [[u16; 15]; 13],
pub angle_delta: [[u16; 8]; 8],
pub intrabc: [u16; 3],
pub partition_w8: [[u16; 5]; 4],
pub partition_w16: [[u16; 11]; 4],
pub partition_w32: [[u16; 11]; 4],
pub partition_w64: [[u16; 11]; 4],
pub partition_w128: [[u16; 9]; 4],
pub segment_id: [[u16; 9]; 3],
pub segment_id_predicted: [[u16; 3]; 3],
pub tx_8x8: [[u16; 3]; 3],
pub tx_16x16: [[u16; 4]; 3],
pub tx_32x32: [[u16; 4]; 3],
pub tx_64x64: [[u16; 4]; 3],
pub txfm_split: [[u16; 3]; 21],
pub filter_intra_mode: [u16; 6],
pub filter_intra: [[u16; 3]; 22],
pub interp_filter: [[u16; 4]; 16],
pub motion_mode: [[u16; 4]; 22],
pub new_mv: [[u16; 3]; 6],
pub zero_mv: [[u16; 3]; 2],
pub ref_mv: [[u16; 3]; 6],
pub compound_mode: [[u16; 9]; 8],
pub drl_mode: [[u16; 3]; 3],
pub is_inter: [[u16; 3]; 4],
pub comp_mode: [[u16; 3]; 5],
pub skip_mode: [[u16; 3]; 3],
pub skip: [[u16; 3]; 3],
pub comp_ref: [[[u16; 3]; 3]; 3],
pub comp_bwd_ref: [[[u16; 3]; 2]; 3],
pub single_ref: [[[u16; 3]; 6]; 3],
pub mv_joint: [[u16; 5]; MV_CONTEXTS],
pub mv_class: [[[u16; 12]; 2]; MV_CONTEXTS],
pub mv_class0_bit: [[[u16; 3]; 2]; MV_CONTEXTS],
pub mv_fr: [[[u16; 5]; 2]; MV_CONTEXTS],
pub mv_class0_fr: [[[[u16; 5]; 2]; 2]; MV_CONTEXTS],
pub mv_class0_hp: [[[u16; 3]; 2]; MV_CONTEXTS],
pub mv_sign: [[[u16; 3]; 2]; MV_CONTEXTS],
pub mv_bit: [[[[u16; 3]; 10]; 2]; MV_CONTEXTS],
pub mv_hp: [[[u16; 3]; 2]; MV_CONTEXTS],
pub palette_y_mode: [[[u16; 3]; 3]; 7],
pub palette_uv_mode: [[u16; 3]; 2],
pub palette_y_size: [[u16; 8]; 7],
pub palette_uv_size: [[u16; 8]; 7],
pub palette_2_y_color: [[u16; 3]; 5],
pub palette_2_uv_color: [[u16; 3]; 5],
pub palette_3_y_color: [[u16; 4]; 5],
pub palette_3_uv_color: [[u16; 4]; 5],
pub palette_4_y_color: [[u16; 5]; 5],
pub palette_4_uv_color: [[u16; 5]; 5],
pub palette_5_y_color: [[u16; 6]; 5],
pub palette_5_uv_color: [[u16; 6]; 5],
pub palette_6_y_color: [[u16; 7]; 5],
pub palette_6_uv_color: [[u16; 7]; 5],
pub palette_7_y_color: [[u16; 8]; 5],
pub palette_7_uv_color: [[u16; 8]; 5],
pub palette_8_y_color: [[u16; 9]; 5],
pub palette_8_uv_color: [[u16; 9]; 5],
pub delta_q: [u16; 5],
pub delta_lf: [u16; 5],
pub delta_lf_multi: [[u16; 5]; FRAME_LF_COUNT],
pub intra_tx_type_set1: [[[u16; 8]; 13]; 2],
pub intra_tx_type_set2: [[[u16; 6]; 13]; 3],
pub inter_tx_type_set1: [[u16; 17]; 2],
pub inter_tx_type_set2: [u16; 13],
pub inter_tx_type_set3: [[u16; 3]; 4],
pub use_obmc: [[u16; 3]; 22],
pub inter_intra: [[u16; 3]; 3],
pub comp_ref_type: [[u16; 3]; 5],
pub cfl_sign: [u16; 9],
pub uni_comp_ref: [[[u16; 3]; 3]; 3],
pub wedge_inter_intra: [[u16; 3]; 22],
pub comp_group_idx: [[u16; 3]; 6],
pub compound_idx: [[u16; 3]; 6],
pub compound_type: [[u16; 3]; 22],
pub inter_intra_mode: [[u16; 5]; 3],
pub wedge_index: [[u16; 17]; 22],
pub cfl_alpha: [[u16; 17]; 6],
pub use_wiener: [u16; 3],
pub use_sgrproj: [u16; 3],
pub restoration_type: [u16; 4],
// coefficient CDFs
pub txb_skip: [[[u16; 3]; 13]; 5],
pub eob_pt_16: [[[u16; 6]; 2]; 2],
pub eob_pt_32: [[[u16; 7]; 2]; 2],
pub eob_pt_64: [[[u16; 8]; 2]; 2],
pub eob_pt_128: [[[u16; 9]; 2]; 2],
pub eob_pt_256: [[[u16; 10]; 2]; 2],
pub eob_pt_512: [[u16; 11]; 2],
pub eob_pt_1024: [[u16; 12]; 2],
pub eob_extra: [[[[u16; 3]; 9]; 2]; 5],
pub dc_sign: [[[u16; 3]; 3]; 2],
pub coeff_base_eob: [[[[u16; 4]; 4]; 2]; 5],
pub coeff_base: [[[[u16; 5]; 42]; 2]; 5],
pub coeff_br: [[[[u16; 5]; 21]; 2]; 5],
}
impl Cdfs {
/// init_non_coeff_cdfs( ) followed by init_coeff_cdfs( ) for `base_q_idx`.
pub fn new(base_q_idx: u32) -> Box<Cdfs> {
let mut c = Box::new(Cdfs {
y_mode: DEFAULT_Y_MODE_CDF,
uv_mode_cfl_not_allowed: DEFAULT_UV_MODE_CFL_NOT_ALLOWED_CDF,
uv_mode_cfl_allowed: DEFAULT_UV_MODE_CFL_ALLOWED_CDF,
angle_delta: DEFAULT_ANGLE_DELTA_CDF,
intrabc: DEFAULT_INTRABC_CDF,
partition_w8: DEFAULT_PARTITION_W8_CDF,
partition_w16: DEFAULT_PARTITION_W16_CDF,
partition_w32: DEFAULT_PARTITION_W32_CDF,
partition_w64: DEFAULT_PARTITION_W64_CDF,
partition_w128: DEFAULT_PARTITION_W128_CDF,
segment_id: DEFAULT_SEGMENT_ID_CDF,
segment_id_predicted: DEFAULT_SEGMENT_ID_PREDICTED_CDF,
tx_8x8: DEFAULT_TX_8X8_CDF,
tx_16x16: DEFAULT_TX_16X16_CDF,
tx_32x32: DEFAULT_TX_32X32_CDF,
tx_64x64: DEFAULT_TX_64X64_CDF,
txfm_split: DEFAULT_TXFM_SPLIT_CDF,
filter_intra_mode: DEFAULT_FILTER_INTRA_MODE_CDF,
filter_intra: DEFAULT_FILTER_INTRA_CDF,
interp_filter: DEFAULT_INTERP_FILTER_CDF,
motion_mode: DEFAULT_MOTION_MODE_CDF,
new_mv: DEFAULT_NEW_MV_CDF,
zero_mv: DEFAULT_ZERO_MV_CDF,
ref_mv: DEFAULT_REF_MV_CDF,
compound_mode: DEFAULT_COMPOUND_MODE_CDF,
drl_mode: DEFAULT_DRL_MODE_CDF,
is_inter: DEFAULT_IS_INTER_CDF,
comp_mode: DEFAULT_COMP_MODE_CDF,
skip_mode: DEFAULT_SKIP_MODE_CDF,
skip: DEFAULT_SKIP_CDF,
comp_ref: DEFAULT_COMP_REF_CDF,
comp_bwd_ref: DEFAULT_COMP_BWD_REF_CDF,
single_ref: DEFAULT_SINGLE_REF_CDF,
mv_joint: [DEFAULT_MV_JOINT_CDF; MV_CONTEXTS],
mv_class: [DEFAULT_MV_CLASS_CDF; MV_CONTEXTS],
mv_class0_bit: [[DEFAULT_MV_CLASS0_BIT_CDF; 2]; MV_CONTEXTS],
mv_fr: [DEFAULT_MV_FR_CDF; MV_CONTEXTS],
mv_class0_fr: [DEFAULT_MV_CLASS0_FR_CDF; MV_CONTEXTS],
mv_class0_hp: [[DEFAULT_MV_CLASS0_HP_CDF; 2]; MV_CONTEXTS],
mv_sign: [[DEFAULT_MV_SIGN_CDF; 2]; MV_CONTEXTS],
mv_bit: [[DEFAULT_MV_BIT_CDF; 2]; MV_CONTEXTS],
mv_hp: [[DEFAULT_MV_HP_CDF; 2]; MV_CONTEXTS],
palette_y_mode: DEFAULT_PALETTE_Y_MODE_CDF,
palette_uv_mode: DEFAULT_PALETTE_UV_MODE_CDF,
palette_y_size: DEFAULT_PALETTE_Y_SIZE_CDF,
palette_uv_size: DEFAULT_PALETTE_UV_SIZE_CDF,
palette_2_y_color: DEFAULT_PALETTE_SIZE_2_Y_COLOR_CDF,
palette_2_uv_color: DEFAULT_PALETTE_SIZE_2_UV_COLOR_CDF,
palette_3_y_color: DEFAULT_PALETTE_SIZE_3_Y_COLOR_CDF,
palette_3_uv_color: DEFAULT_PALETTE_SIZE_3_UV_COLOR_CDF,
palette_4_y_color: DEFAULT_PALETTE_SIZE_4_Y_COLOR_CDF,
palette_4_uv_color: DEFAULT_PALETTE_SIZE_4_UV_COLOR_CDF,
palette_5_y_color: DEFAULT_PALETTE_SIZE_5_Y_COLOR_CDF,
palette_5_uv_color: DEFAULT_PALETTE_SIZE_5_UV_COLOR_CDF,
palette_6_y_color: DEFAULT_PALETTE_SIZE_6_Y_COLOR_CDF,
palette_6_uv_color: DEFAULT_PALETTE_SIZE_6_UV_COLOR_CDF,
palette_7_y_color: DEFAULT_PALETTE_SIZE_7_Y_COLOR_CDF,
palette_7_uv_color: DEFAULT_PALETTE_SIZE_7_UV_COLOR_CDF,
palette_8_y_color: DEFAULT_PALETTE_SIZE_8_Y_COLOR_CDF,
palette_8_uv_color: DEFAULT_PALETTE_SIZE_8_UV_COLOR_CDF,
delta_q: DEFAULT_DELTA_Q_CDF,
delta_lf: DEFAULT_DELTA_LF_CDF,
delta_lf_multi: [DEFAULT_DELTA_LF_CDF; FRAME_LF_COUNT],
intra_tx_type_set1: DEFAULT_INTRA_TX_TYPE_SET1_CDF,
intra_tx_type_set2: DEFAULT_INTRA_TX_TYPE_SET2_CDF,
inter_tx_type_set1: DEFAULT_INTER_TX_TYPE_SET1_CDF,
inter_tx_type_set2: DEFAULT_INTER_TX_TYPE_SET2_CDF,
inter_tx_type_set3: DEFAULT_INTER_TX_TYPE_SET3_CDF,
use_obmc: DEFAULT_USE_OBMC_CDF,
inter_intra: DEFAULT_INTER_INTRA_CDF,
comp_ref_type: DEFAULT_COMP_REF_TYPE_CDF,
cfl_sign: DEFAULT_CFL_SIGN_CDF,
uni_comp_ref: DEFAULT_UNI_COMP_REF_CDF,
wedge_inter_intra: DEFAULT_WEDGE_INTER_INTRA_CDF,
comp_group_idx: DEFAULT_COMP_GROUP_IDX_CDF,
compound_idx: DEFAULT_COMPOUND_IDX_CDF,
compound_type: DEFAULT_COMPOUND_TYPE_CDF,
inter_intra_mode: DEFAULT_INTER_INTRA_MODE_CDF,
wedge_index: DEFAULT_WEDGE_INDEX_CDF,
cfl_alpha: DEFAULT_CFL_ALPHA_CDF,
use_wiener: DEFAULT_USE_WIENER_CDF,
use_sgrproj: DEFAULT_USE_SGRPROJ_CDF,
restoration_type: DEFAULT_RESTORATION_TYPE_CDF,
txb_skip: DEFAULT_TXB_SKIP_CDF[0],
eob_pt_16: DEFAULT_EOB_PT_16_CDF[0],
eob_pt_32: DEFAULT_EOB_PT_32_CDF[0],
eob_pt_64: DEFAULT_EOB_PT_64_CDF[0],
eob_pt_128: DEFAULT_EOB_PT_128_CDF[0],
eob_pt_256: DEFAULT_EOB_PT_256_CDF[0],
eob_pt_512: DEFAULT_EOB_PT_512_CDF[0],
eob_pt_1024: DEFAULT_EOB_PT_1024_CDF[0],
eob_extra: DEFAULT_EOB_EXTRA_CDF[0],
dc_sign: DEFAULT_DC_SIGN_CDF[0],
coeff_base_eob: DEFAULT_COEFF_BASE_EOB_CDF[0],
coeff_base: DEFAULT_COEFF_BASE_CDF[0],
coeff_br: DEFAULT_COEFF_BR_CDF[0],
});
c.init_coeff(base_q_idx);
c
}
/// init_coeff_cdfs( )
pub fn init_coeff(&mut self, base_q_idx: u32) {
let idx = match base_q_idx {
0..=20 => 0,
21..=60 => 1,
61..=120 => 2,
_ => 3,
};
self.txb_skip = DEFAULT_TXB_SKIP_CDF[idx];
self.eob_pt_16 = DEFAULT_EOB_PT_16_CDF[idx];
self.eob_pt_32 = DEFAULT_EOB_PT_32_CDF[idx];
self.eob_pt_64 = DEFAULT_EOB_PT_64_CDF[idx];
self.eob_pt_128 = DEFAULT_EOB_PT_128_CDF[idx];
self.eob_pt_256 = DEFAULT_EOB_PT_256_CDF[idx];
self.eob_pt_512 = DEFAULT_EOB_PT_512_CDF[idx];
self.eob_pt_1024 = DEFAULT_EOB_PT_1024_CDF[idx];
self.eob_extra = DEFAULT_EOB_EXTRA_CDF[idx];
self.dc_sign = DEFAULT_DC_SIGN_CDF[idx];
self.coeff_base_eob = DEFAULT_COEFF_BASE_EOB_CDF[idx];
self.coeff_base = DEFAULT_COEFF_BASE_CDF[idx];
self.coeff_br = DEFAULT_COEFF_BR_CDF[idx];
}
/// The counter reset of load_cdfs( ): the last entry of every CDF array is set to 0.
pub fn clear_counts(&mut self) {
macro_rules! clr {
($($f:ident),*) => { $( self.$f.clear_count(); )* };
}
clr!(
y_mode,
uv_mode_cfl_not_allowed,
uv_mode_cfl_allowed,
angle_delta,
intrabc,
partition_w8,
partition_w16,
partition_w32,
partition_w64,
partition_w128,
segment_id,
segment_id_predicted,
tx_8x8,
tx_16x16,
tx_32x32,
tx_64x64,
txfm_split,
filter_intra_mode,
filter_intra,
interp_filter,
motion_mode,
new_mv,
zero_mv,
ref_mv,
compound_mode,
drl_mode,
is_inter,
comp_mode,
skip_mode,
skip,
comp_ref,
comp_bwd_ref,
single_ref,
mv_joint,
mv_class,
mv_class0_bit,
mv_fr,
mv_class0_fr,
mv_class0_hp,
mv_sign,
mv_bit,
mv_hp,
palette_y_mode,
palette_uv_mode,
palette_y_size,
palette_uv_size,
palette_2_y_color,
palette_2_uv_color,
palette_3_y_color,
palette_3_uv_color,
palette_4_y_color,
palette_4_uv_color,
palette_5_y_color,
palette_5_uv_color,
palette_6_y_color,
palette_6_uv_color,
palette_7_y_color,
palette_7_uv_color,
palette_8_y_color,
palette_8_uv_color,
delta_q,
delta_lf,
delta_lf_multi,
intra_tx_type_set1,
intra_tx_type_set2,
inter_tx_type_set1,
inter_tx_type_set2,
inter_tx_type_set3,
use_obmc,
inter_intra,
comp_ref_type,
cfl_sign,
uni_comp_ref,
wedge_inter_intra,
comp_group_idx,
compound_idx,
compound_type,
inter_intra_mode,
wedge_index,
cfl_alpha,
use_wiener,
use_sgrproj,
restoration_type,
txb_skip,
eob_pt_16,
eob_pt_32,
eob_pt_64,
eob_pt_128,
eob_pt_256,
eob_pt_512,
eob_pt_1024,
eob_extra,
dc_sign,
coeff_base_eob,
coeff_base,
coeff_br
);
}
}
/// Zeroes the adaptation counter (last element) of every innermost CDF array.
trait ClearCount {
fn clear_count(&mut self);
}
impl<const N: usize> ClearCount for [u16; N] {
fn clear_count(&mut self) {
self[N - 1] = 0;
}
}
impl<T: ClearCount, const M: usize> ClearCount for [T; M] {
fn clear_count(&mut self) {
for e in self.iter_mut() {
e.clear_count();
}
}
}