Ok(())
}
- fn pred_mv(sstate: &mut SliceState, frame_refs: &FrameRefs, mb_info: &mut CurrentMBInfo, cur_id: u16, temporal_mv: bool, direct_8x8: bool) {
+ fn pred_mv(sstate: &mut SliceState, frame_refs: &SliceRefs, mb_info: &mut CurrentMBInfo, cur_id: u16, temporal_mv: bool, direct_8x8: bool) {
let mb_type = mb_info.mb_type;
if !mb_type.is_4x4() {
let (pw, ph) = mb_type.size();
self.sstate.reset_mb_mv();
}
if !mb_info.mb_type.is_intra() {
- Self::pred_mv(&mut self.sstate, &self.frame_refs, mb_info, self.cur_id, self.temporal_mv, self.sps[self.cur_sps].direct_8x8_inference);
+ Self::pred_mv(&mut self.sstate, &self.frame_refs.cur_refs, mb_info, self.cur_id, self.temporal_mv, self.sps[self.cur_sps].direct_8x8_inference);
}
if !pps.constrained_intra_pred && mb_info.mb_type != MBType::Intra4x4 && mb_info.mb_type != MBType::Intra8x8 {
self.sstate.fill_ipred(IntraPredMode::DC);
} else {
0
};
- recon_mb(&mut frm, slice_hdr, mb_info, &mut self.sstate, &self.frame_refs, &mut self.mc_dsp, weight_mode);
+ recon_mb(&mut frm, slice_hdr, mb_info, &mut self.sstate, &self.frame_refs.cur_refs, &mut self.mc_dsp, weight_mode);
} else {
for (dline, src) in frm.data[frm.offset[0] + xpos + ypos * frm.stride[0]..].chunks_mut(frm.stride[0]).take(16).zip(self.ipcm_buf.chunks(16)) {
dline[..16].copy_from_slice(src);
mb.mv[blk4] = self.sstate.get_cur_blk4(blk4).mv;
}
for blk8 in 0..4 {
- mb.ref_poc[blk8] = self.frame_refs.map_refs(self.sstate.get_cur_blk8(blk8).ref_idx);
+ mb.ref_poc[blk8] = self.frame_refs.cur_refs.map_refs(self.sstate.get_cur_blk8(blk8).ref_idx);
mb.ref_idx[blk8] = self.sstate.get_cur_blk8(blk8).ref_idx;
}
mv_info.mbs[mb_pos] = mb;
}
if !self.deblock_skip && self.deblock_mode != 1 {
- self.sstate.fill_deblock(&self.frame_refs, self.deblock_mode, self.is_s);
+ self.sstate.fill_deblock(&self.frame_refs.cur_refs, self.deblock_mode, self.is_s);
if let Some(ref mut pic) = self.cur_pic {
let mut frm = NASimpleVideoFrame::from_video_buf(&mut pic.buf).unwrap();
loop_filter_mb(&mut frm, &self.sstate, self.lf_alpha, self.lf_beta);
}
}
-pub struct FrameRefs {
- pub ref_pics: Vec<PictureInfo>,
+#[derive(Clone)]
+pub struct SliceRefs {
pub ref_list0: Vec<Option<PictureInfo>>,
pub ref_list1: Vec<Option<PictureInfo>>,
+ pub cur_id: u32,
+}
+
+impl SliceRefs {
+ pub fn select_ref_pic(&self, list_id: u8, ref_id: usize) -> Option<NAVideoBufferRef<u8>> {
+ let ref_list = if list_id == 0 { &self.ref_list0 } else { &self.ref_list1 };
+ if ref_list.len() > ref_id {
+ ref_list[ref_id].as_ref().map(|pic| pic.buf.clone())
+ } else {
+ None
+ }
+ }
+ pub fn get_colocated_info(&self, mb_x: usize, mb_y: usize) -> (FrameMBInfo, u16, bool) {
+ if let Some(ref ref_pic) = &self.ref_list1[0] {
+ let mv_info = &ref_pic.mv_info;
+ let mb = mv_info.mbs[mb_x + mb_y * mv_info.mb_stride];
+ (mb, ref_pic.full_id as u16, ref_pic.long_term.is_some())
+ } else {
+ (FrameMBInfo::default(), 0, false)
+ }
+ }
+ pub fn map_ref0(&self, ref0_id: u16) -> (PicRef, bool) {
+ let mut r0_idx = 0;
+ let mut long = false;
+ for (i, rpic0) in self.ref_list0.iter().enumerate() {
+ if let Some(ref pic) = rpic0 {
+ if (pic.full_id as u16) == ref0_id {
+ r0_idx = i as u8;
+ long = pic.long_term.is_some();
+ break;
+ }
+ }
+ }
+ (PicRef::new(r0_idx), long)
+ }
+ pub fn map_refs(&self, ref_idx: [PicRef; 2]) -> [u16; 2] {
+ let r0 = ref_idx[0].index();
+ let r1 = ref_idx[1].index();
+ let ref0 = if r0 < self.ref_list0.len() {
+ if let Some(ref pic) = self.ref_list0[r0] {
+ pic.full_id as u16
+ } else {
+ MISSING_POC
+ }
+ } else {
+ MISSING_POC
+ };
+ let ref1 = if r1 < self.ref_list1.len() {
+ if let Some(ref pic) = self.ref_list1[r1] {
+ pic.full_id as u16
+ } else {
+ MISSING_POC
+ }
+ } else {
+ MISSING_POC
+ };
+ [ref0, ref1]
+ }
+ pub fn cmp_refs(&self, ref1: [PicRef; 2], ref2: [PicRef; 2]) -> bool {
+ if ref1 != ref2 {
+ self.cmp_ref(ref1[0], ref2[0], 0) && self.cmp_ref(ref1[1], ref2[1], 1)
+ } else {
+ true
+ }
+ }
+ fn cmp_ref(&self, ref1: PicRef, ref2: PicRef, list: u8) -> bool {
+ if ref1 == ref2 {
+ true
+ } else {
+ let idx0 = ref1.index();
+ let idx1 = ref2.index();
+ if idx0 == idx1 {
+ return true;
+ }
+ let src = if list == 0 { &self.ref_list0 } else { &self.ref_list1 };
+ if idx0 >= src.len() || idx1 >= src.len() {
+//panic!("wrong refs");
+ return false;
+ }
+ if let (Some(ref pic0), Some(ref pic1)) = (&src[idx0], &src[idx1]) {
+ pic0.full_id == pic1.full_id
+ } else {
+//panic!("missing pics");
+ false
+ }
+ }
+ }
+}
+
+pub struct FrameRefs {
+ pub ref_pics: Vec<PictureInfo>,
+ pub cur_refs: SliceRefs,
pub long_term: Vec<Option<PictureInfo>>,
- pub cur_id: u32,
prev_poc_msb: u32,
prev_poc_lsb: u16,
pub fn new() -> Self {
Self {
ref_pics: Vec::with_capacity(16),
- ref_list0: Vec::with_capacity(3),
- ref_list1: Vec::with_capacity(3),
+ cur_refs: SliceRefs {
+ ref_list0: Vec::with_capacity(3),
+ ref_list1: Vec::with_capacity(3),
+ cur_id: 0,
+ },
long_term: Vec::new(),
- cur_id: 0,
prev_poc_msb: 0,
prev_poc_lsb: 0,
}
#[allow(clippy::cognitive_complexity)]
pub fn select_refs(&mut self, sps: &SeqParameterSet, slice_hdr: &SliceHeader, cur_id: u32) {
- self.cur_id = cur_id;
- self.ref_list0.clear();
- self.ref_list1.clear();
+ self.cur_refs.cur_id = cur_id;
+ self.cur_refs.ref_list0.clear();
+ self.cur_refs.ref_list1.clear();
let pic_num_mask = if sps.log2_max_frame_num == 16 {
0xFFFF
} else {
(1 << sps.log2_max_frame_num) - 1
};
+
if !slice_hdr.slice_type.is_intra() {
let has_reordering = slice_hdr.ref_pic_list_reordering_l0;
if !has_reordering {
if slice_hdr.slice_type.is_p() {
if !self.ref_pics.is_empty() {
for pic in self.ref_pics.iter().rev().take(num_ref) {
- self.ref_list0.push(Some(pic.clone()));
+ self.cur_refs.ref_list0.push(Some(pic.clone()));
}
}
} else {
}
}
for pic in self.ref_pics[..pivot].iter().rev() {
- if self.ref_list0.len() >= num_ref {
+ if self.cur_refs.ref_list0.len() >= num_ref {
break;
}
- self.ref_list0.push(Some(pic.clone()));
+ self.cur_refs.ref_list0.push(Some(pic.clone()));
}
for pic in self.ref_pics.iter().skip(pivot) {
- if self.ref_list0.len() >= num_ref {
+ if self.cur_refs.ref_list0.len() >= num_ref {
break;
}
- self.ref_list0.push(Some(pic.clone()));
+ self.cur_refs.ref_list0.push(Some(pic.clone()));
}
}
- if !self.long_term.is_empty() && self.ref_list0.len() < num_ref {
- let copy_size = num_ref - self.ref_list0.len();
+ if !self.long_term.is_empty() && self.cur_refs.ref_list0.len() < num_ref {
+ let copy_size = num_ref - self.cur_refs.ref_list0.len();
for ltpic in self.long_term.iter().take(copy_size) {
- self.ref_list0.push(ltpic.clone());
+ self.cur_refs.ref_list0.push(ltpic.clone());
}
}
} else {
- form_ref_list(&mut self.ref_list0,
+ form_ref_list(&mut self.cur_refs.ref_list0,
&self.ref_pics, &self.long_term,
&slice_hdr.reordering_list_l0,
slice_hdr.frame_num, pic_num_mask);
}
}
for pic in self.ref_pics.iter().skip(pivot) {
- if self.ref_list1.len() >= num_ref {
+ if self.cur_refs.ref_list1.len() >= num_ref {
break;
}
- self.ref_list1.push(Some(pic.clone()));
+ self.cur_refs.ref_list1.push(Some(pic.clone()));
}
for pic in self.ref_pics[..pivot].iter().rev() {
- if self.ref_list1.len() >= num_ref {
+ if self.cur_refs.ref_list1.len() >= num_ref {
break;
}
- self.ref_list1.push(Some(pic.clone()));
+ self.cur_refs.ref_list1.push(Some(pic.clone()));
}
- if !self.long_term.is_empty() && self.ref_list1.len() < num_ref {
- let copy_size = num_ref - self.ref_list1.len();
+ if !self.long_term.is_empty() && self.cur_refs.ref_list1.len() < num_ref {
+ let copy_size = num_ref - self.cur_refs.ref_list1.len();
for ltpic in self.long_term.iter().take(copy_size) {
- self.ref_list1.push(ltpic.clone());
+ self.cur_refs.ref_list1.push(ltpic.clone());
}
}
- if self.ref_list1.len() > 1 && self.ref_list0.len() == self.ref_list1.len() {
+ if self.cur_refs.ref_list1.len() > 1 && self.cur_refs.ref_list0.len() == self.cur_refs.ref_list1.len() {
let mut equal = true;
- for (pic1, pic2) in self.ref_list0.iter().zip(self.ref_list1.iter()) {
+ for (pic1, pic2) in self.cur_refs.ref_list0.iter().zip(self.cur_refs.ref_list1.iter()) {
match (pic1, pic2) {
(Some(p1), Some(p2)) => {
if p1.full_id != p2.full_id {
};
}
if equal {
- self.ref_list1.swap(0, 1);
+ self.cur_refs.ref_list1.swap(0, 1);
}
}
} else {
- form_ref_list(&mut self.ref_list1,
+ form_ref_list(&mut self.cur_refs.ref_list1,
&self.ref_pics, &self.long_term,
&slice_hdr.reordering_list_l1,
slice_hdr.frame_num, pic_num_mask);
self.long_term[lt_idx] = Some(cpic);
}
}
- pub fn select_ref_pic(&self, list_id: u8, ref_id: usize) -> Option<NAVideoBufferRef<u8>> {
- let ref_list = if list_id == 0 { &self.ref_list0 } else { &self.ref_list1 };
- if ref_list.len() > ref_id {
- ref_list[ref_id].as_ref().map(|pic| pic.buf.clone())
- } else {
- None
- }
- }
- pub fn get_colocated_info(&self, mb_x: usize, mb_y: usize) -> (FrameMBInfo, u16, bool) {
- if let Some(ref ref_pic) = &self.ref_list1[0] {
- let mv_info = &ref_pic.mv_info;
- let mb = mv_info.mbs[mb_x + mb_y * mv_info.mb_stride];
- (mb, ref_pic.full_id as u16, ref_pic.long_term.is_some())
- } else {
- (FrameMBInfo::default(), 0, false)
- }
- }
- pub fn map_ref0(&self, ref0_id: u16) -> (PicRef, bool) {
- let mut r0_idx = 0;
- let mut long = false;
- for (i, rpic0) in self.ref_list0.iter().enumerate() {
- if let Some(ref pic) = rpic0 {
- if (pic.full_id as u16) == ref0_id {
- r0_idx = i as u8;
- long = pic.long_term.is_some();
- break;
- }
- }
- }
- (PicRef::new(r0_idx), long)
- }
- pub fn map_refs(&self, ref_idx: [PicRef; 2]) -> [u16; 2] {
- let r0 = ref_idx[0].index();
- let r1 = ref_idx[1].index();
- let ref0 = if r0 < self.ref_list0.len() {
- if let Some(ref pic) = self.ref_list0[r0] {
- pic.full_id as u16
- } else {
- MISSING_POC
- }
- } else {
- MISSING_POC
- };
- let ref1 = if r1 < self.ref_list1.len() {
- if let Some(ref pic) = self.ref_list1[r1] {
- pic.full_id as u16
- } else {
- MISSING_POC
- }
- } else {
- MISSING_POC
- };
- [ref0, ref1]
- }
- pub fn cmp_refs(&self, ref1: [PicRef; 2], ref2: [PicRef; 2]) -> bool {
- if ref1 != ref2 {
- self.cmp_ref(ref1[0], ref2[0], 0) && self.cmp_ref(ref1[1], ref2[1], 1)
- } else {
- true
- }
- }
- fn cmp_ref(&self, ref1: PicRef, ref2: PicRef, list: u8) -> bool {
- if ref1 == ref2 {
- true
- } else {
- let idx0 = ref1.index();
- let idx1 = ref2.index();
- if idx0 == idx1 {
- return true;
- }
- let src = if list == 0 { &self.ref_list0 } else { &self.ref_list1 };
- if idx0 >= src.len() || idx1 >= src.len() {
-//panic!("wrong refs");
- return false;
- }
- if let (Some(ref pic0), Some(ref pic1)) = (&src[idx0], &src[idx1]) {
- pic0.full_id == pic1.full_id
- } else {
-//panic!("missing pics");
- false
- }
- }
- }
}
fn 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) {
use nihav_core::frame::NASimpleVideoFrame;
use nihav_codec_support::codecs::{MV, ZERO_MV};
use nihav_codec_support::data::GenericCache;
-use super::FrameRefs;
+use super::SliceRefs;
use super::pic_ref::FrameMBInfo;
#[repr(u8)]
}
}
}
- pub fn fill_deblock(&mut self, frefs: &FrameRefs, deblock_mode: u8, is_s: bool) {
+ pub fn fill_deblock(&mut self, frefs: &SliceRefs, deblock_mode: u8, is_s: bool) {
if deblock_mode == 1 {
return;
}
self.fill_mv (0, 0, 16, 16, 0, mv);
self.fill_ref(0, 0, 16, 16, 0, ref_idx);
}
- pub fn predict_direct_mb(&mut self, frame_refs: &FrameRefs, temporal_mv: bool, direct_8x8: bool, cur_id: u16) {
+ pub fn predict_direct_mb(&mut self, frame_refs: &SliceRefs, temporal_mv: bool, direct_8x8: bool, cur_id: u16) {
let (col_mb, r1_poc, r1_long) = frame_refs.get_colocated_info(self.mb_x, self.mb_y);
if direct_8x8 {
for blk4 in 0..16 {
}
}
}
- pub fn predict_direct_sub(&mut self, frame_refs: &FrameRefs, temporal_mv: bool, direct8x8: bool, cur_id: u16, blk4: usize) {
+ pub fn predict_direct_sub(&mut self, frame_refs: &SliceRefs, temporal_mv: bool, direct8x8: bool, cur_id: u16, blk4: usize) {
let src_blk = if !direct8x8 { blk4 } else { BLK4_TO_D8[blk4] };
let (mbi, r1_poc, r1_long) = frame_refs.get_colocated_info(self.mb_x, self.mb_y);
let (mv0, ref0, mv1, ref1) = self.get_direct_mv(frame_refs, &mbi, r1_poc, r1_long, temporal_mv, cur_id, src_blk);
self.get_cur_blk8(blk4_to_blk8(blk4)).ref_idx = [ref0, ref1];
}
#[allow(clippy::nonminimal_bool)]
- pub fn get_direct_mv(&self, frame_refs: &FrameRefs, mbi: &FrameMBInfo, r1_poc: u16, r1_long: bool, temporal_mv: bool, cur_id: u16, blk4: usize) -> (MV, PicRef, MV, PicRef) {
+ pub fn get_direct_mv(&self, frame_refs: &SliceRefs, mbi: &FrameMBInfo, r1_poc: u16, r1_long: bool, temporal_mv: bool, cur_id: u16, blk4: usize) -> (MV, PicRef, MV, PicRef) {
let blk8 = blk4_to_blk8(blk4);
let (col_mv, r0_poc, col_idx) = if mbi.ref_poc[blk8] == [MISSING_POC; 2] {
(ZERO_MV, MISSING_POC, MISSING_REF)