scuffle_h265/sps/
st_ref_pic_set.rs1use std::fmt::Debug;
2use std::io;
3
4use scuffle_bytes_util::BitReader;
5use scuffle_expgolomb::BitReaderExpGolombExt;
6
7use crate::range_check::range_check;
8
9#[derive(Debug, Clone, PartialEq)]
16pub struct ShortTermRefPicSets {
17 pub num_delta_pocs: Vec<u64>,
19 pub num_positive_pics: Vec<u64>,
21 pub num_negative_pics: Vec<u64>,
23 pub delta_poc_s1: Vec<Vec<i64>>,
25 pub delta_poc_s0: Vec<Vec<i64>>,
27 pub used_by_curr_pic_s0: Vec<Vec<bool>>,
29 pub used_by_curr_pic_s1: Vec<Vec<bool>>,
31}
32
33impl ShortTermRefPicSets {
34 pub(crate) fn parse<R: io::Read>(
35 bit_reader: &mut BitReader<R>,
36 num_short_term_ref_pic_sets: usize,
37 nuh_layer_id: u8,
38 sps_max_dec_pic_buffering_minus1_at_sps_max_sub_layers_minus1: u64,
39 ) -> io::Result<Self> {
40 let mut num_delta_pocs = Vec::with_capacity(num_short_term_ref_pic_sets);
41
42 let mut num_positive_pics = vec![0u64; num_short_term_ref_pic_sets];
44 let mut num_negative_pics = vec![0u64; num_short_term_ref_pic_sets];
45 let mut delta_poc_s1 = Vec::with_capacity(num_short_term_ref_pic_sets);
46 let mut delta_poc_s0 = Vec::with_capacity(num_short_term_ref_pic_sets);
47 let mut used_by_curr_pic_s0 = Vec::with_capacity(num_short_term_ref_pic_sets);
48 let mut used_by_curr_pic_s1 = Vec::with_capacity(num_short_term_ref_pic_sets);
49
50 for st_rps_idx in 0..num_short_term_ref_pic_sets {
51 let mut inter_ref_pic_set_prediction_flag = false;
52 if st_rps_idx != 0 {
53 inter_ref_pic_set_prediction_flag = bit_reader.read_bit()?;
54 }
55
56 if inter_ref_pic_set_prediction_flag {
57 let mut delta_idx_minus1 = 0;
58 if st_rps_idx == num_short_term_ref_pic_sets {
59 delta_idx_minus1 = bit_reader.read_exp_golomb()? as usize;
60 range_check!(delta_idx_minus1, 0, st_rps_idx - 1)?;
61 }
62
63 let ref_rps_idx = st_rps_idx - (delta_idx_minus1 + 1);
65
66 let delta_rps_sign = bit_reader.read_bit()?;
67 let abs_delta_rps_minus1 = bit_reader.read_exp_golomb()?;
68 range_check!(abs_delta_rps_minus1, 0, 2u64.pow(15) - 1)?;
69 let delta_rps = (1 - 2 * delta_rps_sign as i64) * (abs_delta_rps_minus1 + 1) as i64;
71
72 let len = num_delta_pocs[ref_rps_idx] as usize + 1;
74 let mut used_by_curr_pic_flag = vec![false; len];
75 let mut use_delta_flag = vec![true; len];
76 for j in 0..len {
77 used_by_curr_pic_flag[j] = bit_reader.read_bit()?;
78 if !used_by_curr_pic_flag[j] {
79 use_delta_flag[j] = bit_reader.read_bit()?;
80 }
81 }
82
83 delta_poc_s0.push(vec![0; len]);
84 delta_poc_s1.push(vec![0; len]);
85 used_by_curr_pic_s0.push(vec![false; len]);
86 used_by_curr_pic_s1.push(vec![false; len]);
87
88 let mut i = 0;
90 if let Some(start) = num_positive_pics[ref_rps_idx].checked_sub(1).map(|s| s as usize) {
91 for j in (0..=start).rev() {
92 let d_poc = delta_poc_s1[ref_rps_idx][j] + delta_rps;
93 if d_poc < 0 && use_delta_flag[num_negative_pics[ref_rps_idx] as usize + j] {
94 delta_poc_s0[st_rps_idx][i] = d_poc;
95 used_by_curr_pic_s0[st_rps_idx][i] =
96 used_by_curr_pic_flag[num_negative_pics[ref_rps_idx] as usize + j];
97 i += 1;
98 }
99 }
100 }
101
102 if delta_rps < 0 && use_delta_flag[num_delta_pocs[ref_rps_idx] as usize] {
103 delta_poc_s0[st_rps_idx][i] = delta_rps;
104 used_by_curr_pic_s0[st_rps_idx][i] = used_by_curr_pic_flag[num_delta_pocs[ref_rps_idx] as usize];
105 i += 1;
106 }
107
108 for j in 0..num_negative_pics[ref_rps_idx] as usize {
109 let d_poc = delta_poc_s0[ref_rps_idx][j] + delta_rps;
110 if d_poc < 0 && use_delta_flag[j] {
111 delta_poc_s0[st_rps_idx][i] = d_poc;
112 used_by_curr_pic_s0[st_rps_idx][i] = used_by_curr_pic_flag[j];
113 i += 1;
114 }
115 }
116
117 num_negative_pics[st_rps_idx] = i as u64;
118 range_check!(num_negative_pics[st_rps_idx], 0, 16)?;
123
124 i = 0;
125 if let Some(start) = num_negative_pics[ref_rps_idx].checked_sub(1).map(|s| s as usize) {
126 for j in (0..=start).rev() {
127 let d_poc = delta_poc_s0[ref_rps_idx][j] + delta_rps;
128 if d_poc > 0 && use_delta_flag[j] {
129 delta_poc_s1[st_rps_idx][i] = d_poc;
130 used_by_curr_pic_s1[st_rps_idx][i] = used_by_curr_pic_flag[j];
131 i += 1;
132 }
133 }
134 }
135
136 if delta_rps > 0 && use_delta_flag[num_delta_pocs[ref_rps_idx] as usize] {
137 delta_poc_s1[st_rps_idx][i] = delta_rps;
138 used_by_curr_pic_s1[st_rps_idx][i] = used_by_curr_pic_flag[num_delta_pocs[ref_rps_idx] as usize];
139 i += 1;
140 }
141
142 for j in 0..num_positive_pics[ref_rps_idx] as usize {
143 let d_poc = delta_poc_s1[ref_rps_idx][j] + delta_rps;
144 if d_poc > 0 && use_delta_flag[num_negative_pics[ref_rps_idx] as usize + j] {
145 delta_poc_s1[st_rps_idx][i] = d_poc;
146 used_by_curr_pic_s1[st_rps_idx][i] =
147 used_by_curr_pic_flag[num_negative_pics[ref_rps_idx] as usize + j];
148 i += 1;
149 }
150 }
151
152 num_positive_pics[st_rps_idx] = i as u64;
153 range_check!(num_negative_pics[st_rps_idx], 0, 16)?;
158 } else {
159 num_negative_pics[st_rps_idx] = bit_reader.read_exp_golomb()?;
160 num_positive_pics[st_rps_idx] = bit_reader.read_exp_golomb()?;
161
162 let upper_bound = if nuh_layer_id == 0 {
163 sps_max_dec_pic_buffering_minus1_at_sps_max_sub_layers_minus1
165 } else {
166 16
167 };
168 range_check!(num_negative_pics[st_rps_idx], 0, upper_bound)?;
169
170 let upper_bound = if nuh_layer_id == 0 {
171 sps_max_dec_pic_buffering_minus1_at_sps_max_sub_layers_minus1
173 .saturating_sub(num_negative_pics[st_rps_idx])
174 } else {
175 16
176 };
177 range_check!(num_positive_pics[st_rps_idx], 0, upper_bound)?;
178
179 delta_poc_s0.push(vec![0; num_negative_pics[st_rps_idx] as usize]);
180 used_by_curr_pic_s0.push(vec![false; num_negative_pics[st_rps_idx] as usize]);
181
182 for i in 0..num_negative_pics[st_rps_idx] as usize {
183 let delta_poc_s0_minus1 = bit_reader.read_exp_golomb()?;
184 range_check!(delta_poc_s0_minus1, 0, 2u64.pow(15) - 1)?;
185 if i == 0 {
186 delta_poc_s0[st_rps_idx][i] = -(delta_poc_s0_minus1 as i64 + 1);
188 } else {
189 delta_poc_s0[st_rps_idx][i] = delta_poc_s0[st_rps_idx][i - 1] - (delta_poc_s0_minus1 as i64 + 1);
191 }
192
193 let used_by_curr_pic_s0_flag = bit_reader.read_bit()?;
194 used_by_curr_pic_s0[st_rps_idx][i] = used_by_curr_pic_s0_flag;
195 }
196
197 delta_poc_s1.push(vec![0; num_positive_pics[st_rps_idx] as usize]);
198 used_by_curr_pic_s1.push(vec![false; num_positive_pics[st_rps_idx] as usize]);
199
200 for i in 0..num_positive_pics[st_rps_idx] as usize {
201 let delta_poc_s1_minus1 = bit_reader.read_exp_golomb()?;
202 range_check!(delta_poc_s1_minus1, 0, 2u64.pow(15) - 1)?;
203 if i == 0 {
204 delta_poc_s1[st_rps_idx][i] = delta_poc_s1_minus1 as i64 + 1;
206 } else {
207 delta_poc_s1[st_rps_idx][i] = delta_poc_s1[st_rps_idx][i - 1] + delta_poc_s1_minus1 as i64 + 1;
209 }
210
211 let used_by_curr_pic_s1_flag = bit_reader.read_bit()?;
212 used_by_curr_pic_s1[st_rps_idx][i] = used_by_curr_pic_s1_flag;
213 }
214 }
215
216 num_delta_pocs.push(num_negative_pics[st_rps_idx] + num_positive_pics[st_rps_idx]);
218 }
221
222 Ok(Self {
223 num_delta_pocs,
224 num_positive_pics,
225 num_negative_pics,
226 delta_poc_s1,
227 delta_poc_s0,
228 used_by_curr_pic_s0,
229 used_by_curr_pic_s1,
230 })
231 }
232}