Skip to content

Commit

Permalink
Parse scaling lists properly.
Browse files Browse the repository at this point in the history
  • Loading branch information
jerzywilczek committed Dec 12, 2024
1 parent 7ca37a5 commit 54d98a7
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 35 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
* BREAKING CHANGE: The `ParamSetId` type has been removed and replaced with separate `PicParamSetId` and
`SeqParamSetId` types, since the allowed range of values needs to be different in these two usages.

### Added

* Parsing of scaling lists

## 0.7.0 - 2023-05-30

### Changed
Expand Down
32 changes: 19 additions & 13 deletions src/nal/pps.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::sps;
use super::sps::{self, ScalingList};
use crate::nal::sps::{SeqParamSetId, SeqParamSetIdError};
use crate::rbsp::BitRead;
use crate::{rbsp, Context};
Expand Down Expand Up @@ -142,7 +142,8 @@ impl SliceGroup {

#[derive(Debug, Clone)]
pub struct PicScalingMatrix {
// TODO
pub scaling_list4x4: Vec<ScalingList<16>>,
pub scaling_list8x8: Vec<ScalingList<64>>,
}
impl PicScalingMatrix {
fn read<R: BitRead>(
Expand All @@ -166,17 +167,22 @@ impl PicScalingMatrix {
};
for i in 0..6 + count {
let seq_scaling_list_present_flag = r.read_bool("seq_scaling_list_present_flag")?;
if seq_scaling_list_present_flag {
if i < 6 {
scaling_list4x4
.push(sps::ScalingList::read(r, 16).map_err(PpsError::ScalingMatrix)?);
} else {
scaling_list8x8
.push(sps::ScalingList::read(r, 64).map_err(PpsError::ScalingMatrix)?);
}
if i < 6 {
scaling_list4x4.push(
sps::ScalingList::<16>::read(r, seq_scaling_list_present_flag)
.map_err(PpsError::ScalingMatrix)?,
);
} else {
scaling_list8x8.push(
sps::ScalingList::<64>::read(r, seq_scaling_list_present_flag)
.map_err(PpsError::ScalingMatrix)?,
);
}
}
Some(PicScalingMatrix {})
Some(PicScalingMatrix {
scaling_list4x4,
scaling_list8x8,
})
} else {
None
})
Expand Down Expand Up @@ -360,9 +366,9 @@ mod test {
pps.extension,
Some(PicParameterSetExtra {
transform_8x8_mode_flag: true,
pic_scaling_matrix: Some(_),
pic_scaling_matrix: Some(PicScalingMatrix { scaling_list4x4, scaling_list8x8 }),
..
})
}) if scaling_list4x4.len() == 6 && scaling_list8x8.len() == 2
));
}

Expand Down
77 changes: 55 additions & 22 deletions src/nal/sps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,33 +278,48 @@ impl From<ProfileIdc> for u8 {
}
}

pub struct ScalingList {
// TODO
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ScalingList<const S: usize> {
NotPresent,
UseDefault,
List(Box<[i32; S]>),
}
impl ScalingList {
pub fn read<R: BitRead>(r: &mut R, size: u8) -> Result<ScalingList, ScalingMatrixError> {
let mut scaling_list = vec![];

impl<const S: usize> ScalingList<S> {
pub fn read<R: BitRead>(
r: &mut R,
present: bool,
) -> Result<ScalingList<S>, ScalingMatrixError> {
if !present {
return Ok(ScalingList::NotPresent);
}
let mut scaling_list = Box::new([0; S]);
let mut last_scale = 8;
let mut next_scale = 8;
let mut _use_default_scaling_matrix_flag = false;
for j in 0..size {
let mut use_default_scaling_matrix_flag = false;
for j in 0..S {
if next_scale != 0 {
let delta_scale = r.read_se("delta_scale")?;
if delta_scale < -128 || delta_scale > 127 {
return Err(ScalingMatrixError::DeltaScaleOutOfRange(delta_scale));
}
next_scale = (last_scale + delta_scale + 256) % 256;
_use_default_scaling_matrix_flag = j == 0 && next_scale == 0;
use_default_scaling_matrix_flag = j == 0 && next_scale == 0;
}
let new_value = if next_scale == 0 {
last_scale
} else {
next_scale
};
scaling_list.push(new_value);
scaling_list[j] = new_value;
last_scale = new_value;
}
Ok(ScalingList {})

if use_default_scaling_matrix_flag {
Ok(ScalingList::UseDefault)
} else {
Ok(ScalingList::List(scaling_list))
}
}
}

Expand All @@ -323,7 +338,8 @@ impl From<BitReaderError> for ScalingMatrixError {

#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct SeqScalingMatrix {
// TODO
pub scaling_list4x4: Vec<ScalingList<16>>,
pub scaling_list8x8: Vec<ScalingList<64>>,
}

impl SeqScalingMatrix {
Expand All @@ -337,15 +353,16 @@ impl SeqScalingMatrix {
let count = if chroma_format_idc == 3 { 12 } else { 8 };
for i in 0..count {
let seq_scaling_list_present_flag = r.read_bool("seq_scaling_list_present_flag")?;
if seq_scaling_list_present_flag {
if i < 6 {
scaling_list4x4.push(ScalingList::read(r, 16)?);
} else {
scaling_list8x8.push(ScalingList::read(r, 64)?);
}
if i < 6 {
scaling_list4x4.push(ScalingList::<16>::read(r, seq_scaling_list_present_flag)?);
} else {
scaling_list8x8.push(ScalingList::<64>::read(r, seq_scaling_list_present_flag)?);
}
}
Ok(SeqScalingMatrix {})
Ok(SeqScalingMatrix {
scaling_list4x4,
scaling_list8x8,
})
}
}

Expand All @@ -356,7 +373,7 @@ pub struct ChromaInfo {
pub bit_depth_luma_minus8: u8,
pub bit_depth_chroma_minus8: u8,
pub qpprime_y_zero_transform_bypass_flag: bool,
pub scaling_matrix: SeqScalingMatrix,
pub scaling_matrix: Option<SeqScalingMatrix>,
}
impl ChromaInfo {
pub fn read<R: BitRead>(r: &mut R, profile_idc: ProfileIdc) -> Result<ChromaInfo, SpsError> {
Expand Down Expand Up @@ -390,12 +407,14 @@ impl ChromaInfo {
fn read_scaling_matrix<R: BitRead>(
r: &mut R,
chroma_format_idc: u32,
) -> Result<SeqScalingMatrix, SpsError> {
) -> Result<Option<SeqScalingMatrix>, SpsError> {
let scaling_matrix_present_flag = r.read_bool("scaling_matrix_present_flag")?;
if scaling_matrix_present_flag {
SeqScalingMatrix::read(r, chroma_format_idc).map_err(SpsError::ScalingMatrix)
Ok(Some(
SeqScalingMatrix::read(r, chroma_format_idc).map_err(SpsError::ScalingMatrix)?,
))
} else {
Ok(SeqScalingMatrix::default())
Ok(None)
}
}
}
Expand Down Expand Up @@ -1414,6 +1433,20 @@ mod test {
seq_parameter_set_id: SeqParamSetId::from_u32(0).unwrap(),
chroma_info: ChromaInfo{
chroma_format: ChromaFormat::YUV420,
scaling_matrix: Some(SeqScalingMatrix {
scaling_list4x4: vec![
ScalingList::List(Box::new([16; 16])),
ScalingList::List(Box::new([16; 16])),
ScalingList::List(Box::new([16; 16])),
ScalingList::List(Box::new([16; 16])),
ScalingList::List(Box::new([16; 16])),
ScalingList::List(Box::new([16; 16])),
],
scaling_list8x8: vec![
ScalingList::NotPresent,
ScalingList::NotPresent,
]
}),
..ChromaInfo::default()
},
/*seq_scaling_list: Some(SeqScalingList{
Expand Down

0 comments on commit 54d98a7

Please sign in to comment.