Skip to content

Commit

Permalink
codec/vp9/parser: use enum for segment features
Browse files Browse the repository at this point in the history
This restricts the possible values to a limited range that is known to
never access the related arrays out-of-bounds.
  • Loading branch information
Gnurou committed Jun 24, 2024
1 parent c7621df commit 69e2e84
Showing 1 changed file with 23 additions and 14 deletions.
37 changes: 23 additions & 14 deletions src/codec/vp9/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@ pub const MAX_SEGMENTS: usize = 8;
pub const SEG_TREE_PROBS: usize = MAX_SEGMENTS - 1;
pub const PREDICTION_PROBS: usize = 3;

pub const SEG_LVL_ALT_L: usize = 1;
pub const SEG_LVL_REF_FRAME: usize = 2;
pub const SEG_LVL_SKIP: usize = 3;
/// Valid segment features values.
#[repr(u8)]
pub enum SegLvl {
AltQ = 0,
AltL = 1,
RefFrame = 2,
LvlSkip = 3,
}
pub const SEG_LVL_MAX: usize = 4;

pub const MAX_LOOP_FILTER: u32 = 63;
Expand Down Expand Up @@ -239,13 +244,15 @@ impl Segmentation {
let mut lvl_seg = i32::from(lf.level);

// 8.8.1 Loop filter frame init process
if hdr.seg_feature_active(segment_id, SEG_LVL_ALT_L as u8) {
if hdr.seg_feature_active(segment_id, SegLvl::AltL) {
if seg.abs_or_delta_update {
lvl_seg =
i32::from(seg.feature_data[usize::from(segment_id)][SEG_LVL_ALT_L]);
lvl_seg = i32::from(
seg.feature_data[usize::from(segment_id)][SegLvl::AltL as usize],
);
} else {
lvl_seg +=
i32::from(seg.feature_data[usize::from(segment_id)][SEG_LVL_ALT_L]);
lvl_seg += i32::from(
seg.feature_data[usize::from(segment_id)][SegLvl::AltL as usize],
);
}
}

Expand Down Expand Up @@ -284,10 +291,12 @@ impl Segmentation {
luma_dc_quant_scale,
chroma_ac_quant_scale,
chroma_dc_quant_scale,
reference_frame_enabled: seg.feature_enabled[usize::from(segment_id)]
[SEG_LVL_REF_FRAME],
reference_frame: seg.feature_data[usize::from(segment_id)][SEG_LVL_REF_FRAME],
reference_skip_enabled: seg.feature_enabled[usize::from(segment_id)][SEG_LVL_SKIP],
reference_frame_enabled: seg.feature_enabled[segment_id as usize]
[SegLvl::RefFrame as usize],
reference_frame: seg.feature_data[usize::from(segment_id)]
[SegLvl::RefFrame as usize],
reference_skip_enabled: seg.feature_enabled[segment_id as usize]
[SegLvl::LvlSkip as usize],
}
}
}
Expand Down Expand Up @@ -426,15 +435,15 @@ pub struct Header {

impl Header {
/// An implementation of seg_feature_active as per "6.4.9 Segmentation feature active syntax"
fn seg_feature_active(&self, segment_id: u8, feature: u8) -> bool {
fn seg_feature_active(&self, segment_id: u8, feature: SegLvl) -> bool {
self.seg.enabled && self.seg.feature_enabled[segment_id as usize][feature as usize]
}

/// An implementation of get_qindex as per "8.6.1 Dequantization functions"
fn get_qindex(&self, segment_id: u8) -> u8 {
let base_q_idx = self.quant.base_q_idx;

if self.seg_feature_active(segment_id, 0) {
if self.seg_feature_active(segment_id, SegLvl::AltQ) {
let mut data = self.seg.feature_data[segment_id as usize][0] as i32;

if !self.seg.abs_or_delta_update {
Expand Down

0 comments on commit 69e2e84

Please sign in to comment.