h264: prepare data references before decoding
[nihav.git] / nihav-itu / src / codecs / h264 / pic_ref.rs
CommitLineData
696e4e20 1use nihav_core::codecs::DecoderResult;
11d7aef2 2use nihav_core::frame::{FrameType, NAVideoBufferRef, NATimeInfo};
93839abd 3use nihav_core::refs::*;
696e4e20
KS
4use nihav_codec_support::codecs::MV;
5use super::sets::SeqParameterSet;
6use super::slice::*;
7use super::types::*;
8
9#[derive(Clone)]
10pub struct PictureInfo {
11 pub id: u16,
12 pub full_id: u32,
11d7aef2
KS
13 pub time: NATimeInfo,
14 pub user_id: u32,
696e4e20
KS
15 pub pic_type: FrameType,
16 pub buf: NAVideoBufferRef<u8>,
17 pub cur_mb: usize,
18 pub is_ref: bool,
11d7aef2 19 pub is_idr: bool,
696e4e20
KS
20 pub long_term: Option<usize>,
21
93839abd 22 pub mv_info: NABufferRef<FrameMV>,
696e4e20
KS
23}
24
25#[derive(Clone,Copy,Default, Debug)]
26pub struct FrameMBInfo {
27 pub mb_type: CompactMBType,
28 pub ref_poc: [[u16; 2]; 4],
29 pub ref_idx: [[PicRef; 2]; 4],
30 pub mv: [[MV; 2]; 16],
31}
32
33impl FrameMBInfo {
34 pub fn new() -> Self { Self::default() }
35}
36
37#[derive(Clone)]
38pub struct FrameMV {
39 pub mbs: Vec<FrameMBInfo>,
40 pub mb_stride: usize,
41}
42
43impl FrameMV {
44 pub fn new(mb_w: usize, mb_h: usize) -> Self {
45 Self {
46 mbs: vec![FrameMBInfo::default(); mb_w * mb_h],
47 mb_stride: mb_w,
48 }
49 }
50}
51
56a17e69
KS
52#[derive(Clone)]
53pub struct SliceRefs {
696e4e20
KS
54 pub ref_list0: Vec<Option<PictureInfo>>,
55 pub ref_list1: Vec<Option<PictureInfo>>,
56a17e69
KS
56 pub cur_id: u32,
57}
58
5f223cdb 59#[allow(dead_code)]
56a17e69 60impl SliceRefs {
11d7aef2
KS
61 pub fn get_ref_id(&self, list_id: u8, ref_id: usize) -> Option<u32> {
62 let ref_list = if list_id == 0 { &self.ref_list0 } else { &self.ref_list1 };
63 if ref_list.len() > ref_id {
64 ref_list[ref_id].as_ref().map(|pic| pic.full_id)
65 } else {
66 None
67 }
68 }
56a17e69
KS
69 pub fn select_ref_pic(&self, list_id: u8, ref_id: usize) -> Option<NAVideoBufferRef<u8>> {
70 let ref_list = if list_id == 0 { &self.ref_list0 } else { &self.ref_list1 };
71 if ref_list.len() > ref_id {
72 ref_list[ref_id].as_ref().map(|pic| pic.buf.clone())
73 } else {
74 None
75 }
76 }
77 pub fn get_colocated_info(&self, mb_x: usize, mb_y: usize) -> (FrameMBInfo, u16, bool) {
78 if let Some(ref ref_pic) = &self.ref_list1[0] {
79 let mv_info = &ref_pic.mv_info;
80 let mb = mv_info.mbs[mb_x + mb_y * mv_info.mb_stride];
81 (mb, ref_pic.full_id as u16, ref_pic.long_term.is_some())
82 } else {
83 (FrameMBInfo::default(), 0, false)
84 }
85 }
86 pub fn map_ref0(&self, ref0_id: u16) -> (PicRef, bool) {
87 let mut r0_idx = 0;
88 let mut long = false;
89 for (i, rpic0) in self.ref_list0.iter().enumerate() {
90 if let Some(ref pic) = rpic0 {
91 if (pic.full_id as u16) == ref0_id {
92 r0_idx = i as u8;
93 long = pic.long_term.is_some();
94 break;
95 }
96 }
97 }
98 (PicRef::new(r0_idx), long)
99 }
100 pub fn map_refs(&self, ref_idx: [PicRef; 2]) -> [u16; 2] {
101 let r0 = ref_idx[0].index();
102 let r1 = ref_idx[1].index();
103 let ref0 = if r0 < self.ref_list0.len() {
104 if let Some(ref pic) = self.ref_list0[r0] {
105 pic.full_id as u16
106 } else {
107 MISSING_POC
108 }
109 } else {
110 MISSING_POC
111 };
112 let ref1 = if r1 < self.ref_list1.len() {
113 if let Some(ref pic) = self.ref_list1[r1] {
114 pic.full_id as u16
115 } else {
116 MISSING_POC
117 }
118 } else {
119 MISSING_POC
120 };
121 [ref0, ref1]
122 }
123 pub fn cmp_refs(&self, ref1: [PicRef; 2], ref2: [PicRef; 2]) -> bool {
5f223cdb
KS
124 if ref1 != ref2 {
125 self.cmp_ref(ref1[0], ref2[0], 0) && self.cmp_ref(ref1[1], ref2[1], 1)
126 } else {
127 true
128 }
129 }
130 fn cmp_ref(&self, ref1: PicRef, ref2: PicRef, list: u8) -> bool {
131 if ref1 == ref2 {
132 true
133 } else {
134 let idx0 = ref1.index();
135 let idx1 = ref2.index();
136 if idx0 == idx1 {
137 return true;
138 }
139 let src = if list == 0 { &self.ref_list0 } else { &self.ref_list1 };
140 if idx0 >= src.len() || idx1 >= src.len() {
141//panic!("wrong refs");
142 return false;
143 }
144 if let (Some(ref pic0), Some(ref pic1)) = (&src[idx0], &src[idx1]) {
145 pic0.full_id == pic1.full_id
146 } else {
147//panic!("missing pics");
148 false
149 }
150 }
151 }
152}
153
154#[derive(Clone)]
155pub struct SimplePictureInfo<'a> {
156 pub full_id: u32,
157 pub buf: SimpleFrame<'a>,
158 pub long_term: bool,
159 pub mv_info: &'a FrameMV,
160}
161
162#[derive(Clone)]
163pub struct SimplifiedSliceRefs<'a> {
164 pub ref_list0: Vec<Option<SimplePictureInfo<'a>>>,
165 pub ref_list1: Vec<Option<SimplePictureInfo<'a>>>,
166 pub cur_id: u32,
167}
168
169impl<'a> SimplifiedSliceRefs<'a> {
170 pub fn new(srefs: &'a SliceRefs) -> Self {
171 let mut ref_list0 = Vec::with_capacity(srefs.ref_list0.len());
172 let mut ref_list1 = Vec::with_capacity(srefs.ref_list1.len());
173 for entry in srefs.ref_list0.iter() {
174 ref_list0.push(entry.as_ref().map(|pic| SimplePictureInfo {
175 full_id: pic.full_id,
176 buf: SimpleFrame::new(&pic.buf),
177 long_term: pic.long_term.is_some(),
178 mv_info: &pic.mv_info,
179 }));
180 }
181 for entry in srefs.ref_list1.iter() {
182 ref_list1.push(entry.as_ref().map(|pic| SimplePictureInfo {
183 full_id: pic.full_id,
184 buf: SimpleFrame::new(&pic.buf),
185 long_term: pic.long_term.is_some(),
186 mv_info: &pic.mv_info,
187 }));
188 }
189 Self {
190 cur_id: srefs.cur_id,
191 ref_list0, ref_list1
192 }
193 }
194 pub fn get_ref_id(&self, list_id: u8, ref_id: usize) -> Option<u32> {
195 let ref_list = if list_id == 0 { &self.ref_list0 } else { &self.ref_list1 };
196 if ref_list.len() > ref_id {
197 ref_list[ref_id].as_ref().map(|pic| pic.full_id)
198 } else {
199 None
200 }
201 }
202 pub fn select_ref_pic(&self, list_id: u8, ref_id: usize) -> Option<&SimpleFrame> {
203 let ref_list = if list_id == 0 { &self.ref_list0 } else { &self.ref_list1 };
204 if ref_list.len() > ref_id {
205 ref_list[ref_id].as_ref().map(|pic| &pic.buf)
206 } else {
207 None
208 }
209 }
210 pub fn get_colocated_info(&self, mb_x: usize, mb_y: usize) -> (FrameMBInfo, u16, bool) {
211 if let Some(ref ref_pic) = &self.ref_list1[0] {
212 let mv_info = ref_pic.mv_info;
213 let mb = mv_info.mbs[mb_x + mb_y * mv_info.mb_stride];
214 (mb, ref_pic.full_id as u16, ref_pic.long_term)
215 } else {
216 (FrameMBInfo::default(), 0, false)
217 }
218 }
219 pub fn map_ref0(&self, ref0_id: u16) -> (PicRef, bool) {
220 let mut r0_idx = 0;
221 let mut long = false;
222 for (i, rpic0) in self.ref_list0.iter().enumerate() {
223 if let Some(ref pic) = rpic0 {
224 if (pic.full_id as u16) == ref0_id {
225 r0_idx = i as u8;
226 long = pic.long_term;
227 break;
228 }
229 }
230 }
231 (PicRef::new(r0_idx), long)
232 }
233 pub fn map_refs(&self, ref_idx: [PicRef; 2]) -> [u16; 2] {
234 let r0 = ref_idx[0].index();
235 let r1 = ref_idx[1].index();
236 let ref0 = if r0 < self.ref_list0.len() {
237 if let Some(ref pic) = self.ref_list0[r0] {
238 pic.full_id as u16
239 } else {
240 MISSING_POC
241 }
242 } else {
243 MISSING_POC
244 };
245 let ref1 = if r1 < self.ref_list1.len() {
246 if let Some(ref pic) = self.ref_list1[r1] {
247 pic.full_id as u16
248 } else {
249 MISSING_POC
250 }
251 } else {
252 MISSING_POC
253 };
254 [ref0, ref1]
255 }
256 pub fn cmp_refs(&self, ref1: [PicRef; 2], ref2: [PicRef; 2]) -> bool {
56a17e69
KS
257 if ref1 != ref2 {
258 self.cmp_ref(ref1[0], ref2[0], 0) && self.cmp_ref(ref1[1], ref2[1], 1)
259 } else {
260 true
261 }
262 }
263 fn cmp_ref(&self, ref1: PicRef, ref2: PicRef, list: u8) -> bool {
264 if ref1 == ref2 {
265 true
266 } else {
267 let idx0 = ref1.index();
268 let idx1 = ref2.index();
269 if idx0 == idx1 {
270 return true;
271 }
272 let src = if list == 0 { &self.ref_list0 } else { &self.ref_list1 };
273 if idx0 >= src.len() || idx1 >= src.len() {
274//panic!("wrong refs");
275 return false;
276 }
277 if let (Some(ref pic0), Some(ref pic1)) = (&src[idx0], &src[idx1]) {
278 pic0.full_id == pic1.full_id
279 } else {
280//panic!("missing pics");
281 false
282 }
283 }
284 }
285}
286
287pub struct FrameRefs {
288 pub ref_pics: Vec<PictureInfo>,
289 pub cur_refs: SliceRefs,
696e4e20
KS
290 pub long_term: Vec<Option<PictureInfo>>,
291
292 prev_poc_msb: u32,
293 prev_poc_lsb: u16,
294 prev_ref_poc_lsb: u16,
295 prev_frame_num: u16,
296 frame_num_offset: u32,
02cfd8de 297 max_frame_num: i32,
696e4e20
KS
298}
299
300impl FrameRefs {
301 pub fn new() -> Self {
302 Self {
303 ref_pics: Vec::with_capacity(16),
56a17e69
KS
304 cur_refs: SliceRefs {
305 ref_list0: Vec::with_capacity(3),
306 ref_list1: Vec::with_capacity(3),
307 cur_id: 0,
308 },
696e4e20
KS
309 long_term: Vec::new(),
310
311 prev_poc_msb: 0,
312 prev_poc_lsb: 0,
313 prev_ref_poc_lsb: 0,
314 prev_frame_num: 0,
315 frame_num_offset: 0,
02cfd8de 316 max_frame_num: 0,
696e4e20
KS
317 }
318 }
11d7aef2
KS
319 pub fn fill_ref_nums(&self, dst: &mut Vec<u32>) {
320 for pic in self.ref_pics.iter() {
321 if !dst.contains(&pic.full_id) {
322 dst.push(pic.full_id);
323 }
324 }
e6aaad5c
KS
325 for pic in self.long_term.iter().flatten() {
326 if !dst.contains(&pic.full_id) {
327 dst.push(pic.full_id);
11d7aef2
KS
328 }
329 }
330 }
696e4e20 331 pub fn calc_picture_num(&mut self, slice_hdr: &SliceHeader, is_idr: bool, ref_id: u8, sps: &SeqParameterSet) -> u32 {
02cfd8de 332 self.max_frame_num = 1 << sps.log2_max_frame_num;
696e4e20
KS
333 match sps.pic_order_cnt_type {
334 0 => {
335 if is_idr {
336 //self.prev_poc_msb = 0;
337 self.prev_poc_lsb = 0;
338 } else {
339 self.prev_poc_lsb = self.prev_ref_poc_lsb;
340 }
341 let max_poc_lsb = 1 << sps.log2_max_pic_order_cnt_lsb;
342 let half_max_poc_lsb = 1 << (sps.log2_max_pic_order_cnt_lsb - 1);
343 let cur_lsb = slice_hdr.pic_order_cnt_lsb;
344 let poc_msb = if cur_lsb < self.prev_poc_lsb && (self.prev_poc_lsb - cur_lsb >= half_max_poc_lsb) {
345 self.prev_poc_msb + max_poc_lsb
346 } else if cur_lsb > self.prev_poc_lsb && (cur_lsb - self.prev_poc_lsb > half_max_poc_lsb) {
347 self.prev_poc_msb.wrapping_sub(max_poc_lsb)
348 } else {
349 self.prev_poc_msb
350 };
351 let poc = poc_msb + u32::from(cur_lsb);
352 if ref_id != 0 {
353 self.prev_ref_poc_lsb = slice_hdr.pic_order_cnt_lsb;
354 self.prev_poc_msb = poc_msb;
355 }
356 poc
357 },
358 1 => {
359 let off = if self.prev_frame_num > slice_hdr.frame_num {
360 self.frame_num_offset + (1 << sps.log2_max_frame_num)
361 } else {
362 self.frame_num_offset
363 };
364 let mut anum = if sps.num_ref_frames_in_pic_order_cnt_cycle != 0 {
365 (off as i32) + i32::from(slice_hdr.frame_num)
366 } else {
367 0
368 };
369 if ref_id == 0 && anum > 0 {
370 anum -= 1;
371 }
372 let (poc_cycle_cnt, fno_in_poc_cycle) = if anum > 0 {
373 let nrf = sps.num_ref_frames_in_pic_order_cnt_cycle as i32;
374 ((anum - 1) / nrf, (anum - 1) % nrf)
375 } else {
376 (0, 0)
377 };
378 let mut expected_delta = 0;
379 for &offset in sps.offset_for_ref_frame[..sps.num_ref_frames_in_pic_order_cnt_cycle].iter() {
380 expected_delta += offset;
381 }
382 let mut expected_poc = if anum > 0 {
383 let mut sum = poc_cycle_cnt * expected_delta;
384 for &offset in sps.offset_for_ref_frame[..=fno_in_poc_cycle as usize].iter() {
385 sum += offset;
386 }
387 sum
388 } else {
389 0
390 };
391 if ref_id == 0 {
392 expected_poc += sps.offset_for_non_ref_pic;
393 }
394 let (top_id, _bottom_id) = if !slice_hdr.field_pic {
395 let top_id = expected_poc + slice_hdr.delta_pic_order_cnt[0];
396 let bot_id = top_id + sps.offset_for_top_to_bottom_field + slice_hdr.delta_pic_order_cnt[1];
397 (top_id, bot_id)
398 } else if !slice_hdr.bottom_field {
399 (expected_poc + slice_hdr.delta_pic_order_cnt[0], 0)
400 } else {
401 (0, sps.offset_for_top_to_bottom_field + slice_hdr.delta_pic_order_cnt[1])
402 };
403 self.prev_frame_num = slice_hdr.frame_num;
404 self.frame_num_offset = off;
405 top_id as u32
406 },
407 _ => {
408 if slice_hdr.frame_num < self.prev_frame_num {
409 self.frame_num_offset += 1 << sps.log2_max_frame_num;
410 }
411 self.prev_frame_num = slice_hdr.frame_num;
412 self.frame_num_offset + u32::from(slice_hdr.frame_num)
413 },
414 }
415 }
416 pub fn apply_adaptive_marking(&mut self, marking: &AdaptiveMarking, cur_id: u16, max_id: u16) -> DecoderResult<()> {
417 let all_ref_pics = self.ref_pics.clone();
418
419 for (&op, (&arg1, &arg2)) in marking.memory_management_control_op.iter().zip(marking.operation_arg.iter().zip(marking.operation_arg2.iter())).take(marking.num_ops) {
420 match op {
421 1 => {
422 let src_id = cur_id.wrapping_sub(arg1) & (max_id - 1);
423 let mut found = false;
424 let mut idx = 0;
425 for (i, pic) in self.ref_pics.iter().enumerate() {
426 if pic.id == src_id {
427 found = true;
428 idx = i;
429 break;
430 }
431 }
432 if found {
433 self.ref_pics.remove(idx);
434 }
435 },
436 2 => { // mark long term picture as unused
437 let idx = arg1 as usize;
438 if idx < self.long_term.len() {
439 self.long_term[idx] = None;
440 }
441 },
442 3 => {
443 let src_id = cur_id.wrapping_sub(arg1) & (max_id - 1);
444
445 let didx = arg2 as usize;
446 for pic in all_ref_pics.iter() {
447 if pic.id == src_id {
448 if didx < self.long_term.len() {
449 self.long_term[didx] = Some(pic.clone());
450 }
451 break;
452 }
453 }
454 },
455 4 => {
456 self.long_term.resize(arg1 as usize, None);
457 },
458 5 => {
37952415
KS
459 self.ref_pics.clear();
460 self.long_term.clear();
696e4e20
KS
461 },
462 6 => {
463 // assign an long term index to current pic - done elsewhere
464 },
465 _ => {},
466 };
467 }
468 Ok(())
469 }
470 pub fn clear_refs(&mut self) {
37952415
KS
471 self.ref_pics.clear();
472 self.long_term.clear();
696e4e20 473 }
b7c882c1 474 #[allow(clippy::cognitive_complexity)]
696e4e20 475 pub fn select_refs(&mut self, sps: &SeqParameterSet, slice_hdr: &SliceHeader, cur_id: u32) {
56a17e69
KS
476 self.cur_refs.cur_id = cur_id;
477 self.cur_refs.ref_list0.clear();
478 self.cur_refs.ref_list1.clear();
696e4e20
KS
479 let pic_num_mask = if sps.log2_max_frame_num == 16 {
480 0xFFFF
481 } else {
482 (1 << sps.log2_max_frame_num) - 1
483 };
56a17e69 484
696e4e20
KS
485 if !slice_hdr.slice_type.is_intra() {
486 let has_reordering = slice_hdr.ref_pic_list_reordering_l0;
487 if !has_reordering {
488 let num_ref = slice_hdr.num_ref_idx_l0_active;
489 if slice_hdr.slice_type.is_p() {
490 if !self.ref_pics.is_empty() {
491 for pic in self.ref_pics.iter().rev().take(num_ref) {
56a17e69 492 self.cur_refs.ref_list0.push(Some(pic.clone()));
696e4e20
KS
493 }
494 }
495 } else {
496 let mut pivot = 0;
497 for (i, pic) in self.ref_pics.iter().enumerate() {
498 pivot = i;
499 if pic.full_id > cur_id {
500 break;
501 }
502 }
503 for pic in self.ref_pics[..pivot].iter().rev() {
56a17e69 504 if self.cur_refs.ref_list0.len() >= num_ref {
696e4e20
KS
505 break;
506 }
56a17e69 507 self.cur_refs.ref_list0.push(Some(pic.clone()));
696e4e20
KS
508 }
509 for pic in self.ref_pics.iter().skip(pivot) {
56a17e69 510 if self.cur_refs.ref_list0.len() >= num_ref {
696e4e20
KS
511 break;
512 }
56a17e69 513 self.cur_refs.ref_list0.push(Some(pic.clone()));
696e4e20
KS
514 }
515 }
56a17e69
KS
516 if !self.long_term.is_empty() && self.cur_refs.ref_list0.len() < num_ref {
517 let copy_size = num_ref - self.cur_refs.ref_list0.len();
696e4e20 518 for ltpic in self.long_term.iter().take(copy_size) {
56a17e69 519 self.cur_refs.ref_list0.push(ltpic.clone());
696e4e20
KS
520 }
521 }
522 } else {
56a17e69 523 form_ref_list(&mut self.cur_refs.ref_list0,
696e4e20
KS
524 &self.ref_pics, &self.long_term,
525 &slice_hdr.reordering_list_l0,
526 slice_hdr.frame_num, pic_num_mask);
527 }
528 if slice_hdr.slice_type.is_b() {
529 let has_reordering = slice_hdr.ref_pic_list_reordering_l1;
530 if !has_reordering {
531 let num_ref = slice_hdr.num_ref_idx_l1_active;
532 let mut pivot = 0;
533 for (i, pic) in self.ref_pics.iter().enumerate() {
534 pivot = i;
535 if pic.full_id > cur_id {
536 break;
537 }
538 }
539 for pic in self.ref_pics.iter().skip(pivot) {
56a17e69 540 if self.cur_refs.ref_list1.len() >= num_ref {
696e4e20
KS
541 break;
542 }
56a17e69 543 self.cur_refs.ref_list1.push(Some(pic.clone()));
696e4e20
KS
544 }
545 for pic in self.ref_pics[..pivot].iter().rev() {
56a17e69 546 if self.cur_refs.ref_list1.len() >= num_ref {
696e4e20
KS
547 break;
548 }
56a17e69 549 self.cur_refs.ref_list1.push(Some(pic.clone()));
696e4e20 550 }
56a17e69
KS
551 if !self.long_term.is_empty() && self.cur_refs.ref_list1.len() < num_ref {
552 let copy_size = num_ref - self.cur_refs.ref_list1.len();
696e4e20 553 for ltpic in self.long_term.iter().take(copy_size) {
56a17e69 554 self.cur_refs.ref_list1.push(ltpic.clone());
696e4e20
KS
555 }
556 }
56a17e69 557 if self.cur_refs.ref_list1.len() > 1 && self.cur_refs.ref_list0.len() == self.cur_refs.ref_list1.len() {
696e4e20 558 let mut equal = true;
56a17e69 559 for (pic1, pic2) in self.cur_refs.ref_list0.iter().zip(self.cur_refs.ref_list1.iter()) {
696e4e20
KS
560 match (pic1, pic2) {
561 (Some(p1), Some(p2)) => {
562 if p1.full_id != p2.full_id {
563 equal = false;
564 break;
565 }
566 },
567 (None, None) => {},
568 _ => {
569 equal = false;
570 break;
571 },
572 };
573 }
574 if equal {
56a17e69 575 self.cur_refs.ref_list1.swap(0, 1);
696e4e20
KS
576 }
577 }
578 } else {
56a17e69 579 form_ref_list(&mut self.cur_refs.ref_list1,
696e4e20
KS
580 &self.ref_pics, &self.long_term,
581 &slice_hdr.reordering_list_l1,
582 slice_hdr.frame_num, pic_num_mask);
583 }
584 }
585 }
586 }
587 pub fn add_short_term(&mut self, cpic: PictureInfo, num_ref_frames: usize) {
588 if !self.ref_pics.is_empty() && self.ref_pics.len() >= num_ref_frames {
02cfd8de
KS
589 let base_id = i32::from(cpic.id);
590 let mut min_id = base_id;
591 let mut min_idx = 0;
592 for (i, pic) in self.ref_pics.iter().enumerate() {
593 let mut pic_id = i32::from(pic.id);
594 if pic_id > base_id {
595 pic_id -= self.max_frame_num;
596 }
597 if pic_id < min_id {
598 min_id = pic_id;
599 min_idx = i;
600 }
601 }
602 self.ref_pics.remove(min_idx);
696e4e20
KS
603 }
604 if self.ref_pics.is_empty() || self.ref_pics.last().unwrap().full_id < cpic.full_id {
605 self.ref_pics.push(cpic);
606 } else {
607 let mut idx = 0;
608 for (i, pic) in self.ref_pics.iter().enumerate() {
609 if pic.full_id < cpic.full_id {
610 idx = i;
611 } else {
612 break;
613 }
614 }
615 self.ref_pics.insert(idx + 1, cpic);
616 }
617 }
618 pub fn add_long_term(&mut self, lt_idx: usize, cpic: PictureInfo) {
619 if lt_idx < self.long_term.len() {
620 self.long_term[lt_idx] = Some(cpic);
621 }
622 }
696e4e20
KS
623}
624
4a1ca15c 625fn form_ref_list(ref_list: &mut Vec<Option<PictureInfo>>, ref_pics: &[PictureInfo], long_term: &[Option<PictureInfo>], reord_info: &ReorderingInfo, cur_id: u16, pic_num_mask: u16) {
696e4e20
KS
626 let mut ref_pic_id = cur_id;
627 for (&op, &num) in reord_info.reordering_of_pic_nums_idc.iter().zip(reord_info.abs_diff_or_num.iter()).take(reord_info.num_ops) {
628 if op < 2 {
629 if op == 0 {
630 ref_pic_id = ref_pic_id.wrapping_sub(num) & pic_num_mask;
631 } else {
632 ref_pic_id = ref_pic_id.wrapping_add(num) & pic_num_mask;
633 }
634 let mut found = false;
635 for pic in ref_pics.iter() {
636 if pic.id == ref_pic_id {
637 ref_list.push(Some(pic.clone()));
638 found = true;
639 break;
640 }
641 }
642 if !found {
643 ref_list.push(None);
644 }
645 } else {
646 let idx = num as usize;
647 if idx < long_term.len() {
648 ref_list.push(long_term[idx].clone());
649 } else {
650 ref_list.push(None);
651 }
652 }
653 }
654}