hevc_parser 0.6.0

HEVC format parser, incomplete
Documentation
use anyhow::Result;

use super::sps::SPSNAL;
use super::BsIoVecReader;

#[derive(Default, Debug, PartialEq, Clone, Eq)]
pub struct ShortTermRPS {
    inter_ref_pic_set_prediction_flag: bool,
    delta_idx: u64,
    delta_rps_sign: bool,
    abs_delta_rps: u64,
    used_by_curr_pic_flags: Vec<bool>,
    use_delta_flags: Vec<bool>,
    num_delta_pocs: u64,
    num_negative_pics: u64,
    num_positive_pics: u64,

    delta_poc_s0: Vec<u64>,
    used_by_curr_pic_s0_flags: Vec<bool>,
    delta_poc_s1: Vec<u64>,
    used_by_curr_pic_s1_flags: Vec<bool>,
}

impl ShortTermRPS {
    pub fn parse(
        bs: &mut BsIoVecReader,
        sps: &SPSNAL,
        st_rps_idx: usize,
        nb_st_rps: u64,
        is_slice_header: bool,
    ) -> Result<ShortTermRPS> {
        let mut rps = ShortTermRPS::default();

        if st_rps_idx > 0 && nb_st_rps > 0 {
            rps.inter_ref_pic_set_prediction_flag = bs.get()?;
        }

        if rps.inter_ref_pic_set_prediction_flag {
            let ref_pic_sets = &sps.short_term_ref_pic_sets;

            if st_rps_idx == nb_st_rps as usize || is_slice_header {
                rps.delta_idx = bs.get_ue()?;
            }

            rps.delta_rps_sign = bs.get()?;
            rps.abs_delta_rps = bs.get_ue()? + 1;

            let ref_rps_idx = st_rps_idx - (rps.delta_idx as usize + 1);
            let mut num_delta_pocs: usize = 0;
            let ref_rps = &ref_pic_sets[ref_rps_idx];

            if ref_rps.inter_ref_pic_set_prediction_flag {
                for i in 0..ref_rps.used_by_curr_pic_flags.len() {
                    if ref_rps.used_by_curr_pic_flags[i] || ref_rps.use_delta_flags[i] {
                        num_delta_pocs += 1;
                    }
                }
            } else {
                num_delta_pocs = (ref_rps.num_negative_pics + ref_rps.num_positive_pics) as usize;
            }

            rps.used_by_curr_pic_flags.resize(num_delta_pocs + 1, false);
            rps.use_delta_flags.resize(num_delta_pocs + 1, true);

            for i in 0..=num_delta_pocs {
                rps.used_by_curr_pic_flags[i] = bs.get()?;

                if !rps.used_by_curr_pic_flags[i] {
                    rps.use_delta_flags[i] = bs.get()?;
                }
            }
        } else {
            rps.num_negative_pics = bs.get_ue()?;
            rps.num_positive_pics = bs.get_ue()?;

            for _ in 0..rps.num_negative_pics {
                rps.delta_poc_s0.push(bs.get_ue()? + 1);
                rps.used_by_curr_pic_s0_flags.push(bs.get()?);
            }

            for _ in 0..rps.num_positive_pics {
                rps.delta_poc_s1.push(bs.get_ue()? + 1);
                rps.used_by_curr_pic_s1_flags.push(bs.get()?);
            }
        }

        Ok(rps)
    }
}