X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-realmedia%2Fsrc%2Fcodecs%2Frv3040.rs;h=762d05459b3b11172f9f89b3c2aa321d8ac1086a;hp=adde67840a340a2d74f0c2f1fcea6b70631b85ee;hb=379524159c95f1c3639976ccf35f9d47cd9732ac;hpb=3fc28ece6664a34af9b7f6a52dbf8a8809fa9204 diff --git a/nihav-realmedia/src/codecs/rv3040.rs b/nihav-realmedia/src/codecs/rv3040.rs index adde678..762d054 100644 --- a/nihav-realmedia/src/codecs/rv3040.rs +++ b/nihav-realmedia/src/codecs/rv3040.rs @@ -1,51 +1,15 @@ use nihav_core::formats::YUV420_FORMAT; use nihav_core::frame::{NABufferType, NAVideoInfo, NAVideoBuffer, NAVideoBufferRef, FrameType, alloc_video_buffer}; -use nihav_core::codecs::{MV, ZERO_MV, DecoderError, DecoderResult, IPBShuffler}; +use nihav_core::codecs::{NADecoderSupport, DecoderError, DecoderResult}; +use nihav_codec_support::codecs::{MV, ZERO_MV, IPBShuffler}; use nihav_core::io::bitreader::{BitReader,BitReaderMode}; use nihav_core::io::intcode::*; +use nihav_codec_support::data::GenericCache; use std::mem; use super::rv34codes::*; use super::rv34dsp::*; -pub struct GenericCache { - pub height: usize, - pub stride: usize, - pub xpos: usize, - pub data: Vec, - pub default: T, -} - -impl GenericCache { - pub fn new(height: usize, stride: usize, default: T) -> Self { - let mut ret = Self { - stride: stride, - height: height, - xpos: 0, - data: Vec::with_capacity((height + 1) * stride), - default: default, - }; - ret.reset(); - ret - } - fn full_size(&self) -> usize { self.stride * (self.height + 1) } - pub fn reset(&mut self) { - self.data.truncate(0); - let size = self.full_size(); - self.data.resize(size, self.default); - self.xpos = self.stride + 1; - } - pub fn update_row(&mut self) { - for i in 0..self.stride { - self.data[i] = self.data[self.height * self.stride + i]; - } - self.data.truncate(self.stride); - let size = self.full_size(); - self.data.resize(size, self.default); - self.xpos = self.stride + 1; - } -} - trait RV34MVScale { fn scale(&self, trd: u16, trb: u16) -> (MV, MV); } @@ -106,17 +70,17 @@ pub enum MBType { } impl MBType { - pub fn is_intra(&self) -> bool { - (*self == MBType::MBIntra) || (*self == MBType::MBIntra16) + pub fn is_intra(self) -> bool { + (self == MBType::MBIntra) || (self == MBType::MBIntra16) } - pub fn is_16(&self) -> bool { - (*self == MBType::MBIntra16) || (*self == MBType::MBP16x16Mix) + pub fn is_16(self) -> bool { + (self == MBType::MBIntra16) || (self == MBType::MBP16x16Mix) } - pub fn is_intra_or_16(&self) -> bool { + pub fn is_intra_or_16(self) -> bool { self.is_intra() || self.is_16() } - pub fn get_num_mvs(&self) -> usize { - match *self { + pub fn get_num_mvs(self) -> usize { + match self { MBType::MBIntra | MBType::MBIntra16 | MBType::MBSkip | MBType::MBDirect => 0, MBType::MBP16x16 | MBType::MBP16x16Mix | @@ -126,42 +90,42 @@ impl MBType { MBType::Invalid => unreachable!(), } } - pub fn is_fwd(&self) -> bool { - match *self { + pub fn is_fwd(self) -> bool { + match self { MBType::MBP16x16 | MBType::MBP16x16Mix | MBType::MBP16x8 | MBType::MBP8x16 | MBType::MBP8x8 | MBType::MBForward => true, _ => false, } } - pub fn is_bwd(&self) -> bool { - match *self { + pub fn is_bwd(self) -> bool { + match self { MBType::MBBidir | MBType::MBBackward => true, _ => false, } } - pub fn has_mv_dir(&self, fwd: bool) -> bool { - match *self { + pub fn has_mv_dir(self, fwd: bool) -> bool { + match self { MBType::MBBidir => true, MBType::MBForward if fwd => true, MBType::MBBackward if !fwd => true, _ => false, } } - pub fn is_nomv(&self) -> bool { - match *self { + pub fn is_nomv(self) -> bool { + match self { MBType::MBIntra | MBType::MBIntra16 | MBType::MBSkip | MBType::MBDirect => true, _ => false, } } - /*pub fn is_16x16(&self) -> bool { - match *self { + /*pub fn is_16x16(self) -> bool { + match self { MBType::MBP16x8 | MBType::MBP8x16 | MBType::MBP8x8 => false, _ => true, } }*/ - fn get_weight(&self) -> usize { - match *self { + fn get_weight(self) -> usize { + match self { MBType::MBIntra => 0, MBType::MBIntra16 => 1, MBType::MBSkip => unreachable!(), @@ -362,13 +326,13 @@ impl MVInfo { } fn reset(&mut self) { let size = self.w * self.h; - self.mv_f.truncate(0); + self.mv_f.clear(); self.mv_f.resize(size, ZERO_MV); - self.mv_b.truncate(0); + self.mv_b.clear(); self.mv_b.resize(size, ZERO_MV); - self.has_f.truncate(0); + self.has_f.clear(); self.has_f.resize(size >> 2, false); - self.has_b.truncate(0); + self.has_b.clear(); self.has_b.resize(size >> 2, false); } fn fill(&mut self, mb_x: usize, mb_y: usize, fwd: bool, mv: MV) { @@ -535,11 +499,11 @@ pub trait RV34BitstreamDecoder { fn decode_intra_pred(&mut self, br: &mut BitReader, types: &mut [i8], pos: usize, tstride: usize, has_top: bool) -> DecoderResult<()>; fn quant_dc(&self, is_intra: bool, q: u8) -> u8; fn decode_inter_mb_hdr(&mut self, br: &mut BitReader, ftype: FrameType, mbtype: MBType) -> DecoderResult; - fn predict_b_mv(&self, sstate: &SState, mvi: &MVInfo, mbtype: MBType, mvs: &[MV], mbinfo: &Vec) -> (MV, MV); + fn predict_b_mv(&self, sstate: &SState, mvi: &MVInfo, mbtype: MBType, mvs: &[MV], mbinfo: &[RV34MBInfo]) -> (MV, MV); } pub trait RV34DSP { - fn loop_filter(&self, frame: &mut NAVideoBuffer, ftype: FrameType, mbinfo: &[RV34MBInfo], mb_w: usize, row: usize); + fn loop_filter(&self, frame: &mut NAVideoBuffer, ftype: FrameType, mbinfo: &[RV34MBInfo], mb_w: usize, mb_h: usize, row: usize); fn do_luma_mc(&self, frame: &mut NAVideoBuffer, prev_frame: &NAVideoBuffer, x: usize, y: usize, mv: MV, use16: bool, avg: bool); fn do_chroma_mc(&self, frame: &mut NAVideoBuffer, prev_frame: &NAVideoBuffer, x: usize, y: usize, comp: usize, mv: MV, use8: bool, avg: bool); } @@ -547,11 +511,11 @@ pub trait RV34DSP { fn parse_slice_offsets(src: &[u8], offsets: &mut Vec) -> DecoderResult<()> { let num_slices = (src[0] as usize) + 1; let ini_off = num_slices * 8 + 1; - offsets.truncate(0); + offsets.clear(); if ini_off >= src.len() { return Err(DecoderError::ShortData); } - let mut br = BitReader::new(&src[1..], ini_off - 1, BitReaderMode::BE); + let mut br = BitReader::new(&src[1..ini_off], BitReaderMode::BE); for i in 0..num_slices { br.skip(32)?; @@ -568,17 +532,33 @@ fn parse_slice_offsets(src: &[u8], offsets: &mut Vec) -> DecoderResult<() Ok(()) } -fn decode_slice_header(br: &mut BitReader, bd: &mut RV34BitstreamDecoder, slice_no: usize, slice_offs: &Vec, old_width: usize, old_height: usize) -> DecoderResult { +fn decode_slice_header(br: &mut BitReader, bd: &mut dyn RV34BitstreamDecoder, slice_no: usize, slice_offs: &[usize], old_width: usize, old_height: usize) -> DecoderResult { validate!(slice_no < slice_offs.len()); br.seek((slice_offs[slice_no] * 8) as u32)?; let mut shdr = bd.decode_slice_header(br, old_width, old_height)?; + if ((shdr.width == 0) || (shdr.height == 0)) && (shdr.ftype != FrameType::I) { + return Err(DecoderError::MissingReference); + } if slice_no < slice_offs.len() - 1 { let cur_pos = br.tell() as u32; br.seek((slice_offs[slice_no + 1] * 8) as u32)?; - let nhdr = bd.decode_slice_header(br, shdr.width, shdr.height)?; + if let Ok(nhdr) = bd.decode_slice_header(br, shdr.width, shdr.height) { + validate!(nhdr.start > shdr.start); + shdr.end = nhdr.start; + } else { + if slice_no + 2 < slice_offs.len() { + br.seek((slice_offs[slice_no + 2] * 8) as u32)?; + if let Ok(nhdr) = bd.decode_slice_header(br, shdr.width, shdr.height) { + validate!(nhdr.start > shdr.start); + shdr.end = nhdr.start; + } else { + shdr.end = ((shdr.width + 15) >> 4) * ((shdr.height + 15) >> 4); + } + } else { + shdr.end = ((shdr.width + 15) >> 4) * ((shdr.height + 15) >> 4); + } + } br.seek(cur_pos)?; - validate!(nhdr.start > shdr.start); - shdr.end = nhdr.start; } else { shdr.end = ((shdr.width + 15) >> 4) * ((shdr.height + 15) >> 4); } @@ -589,6 +569,9 @@ const RV34_MB_MAX_SIZES: [usize; 6] = [ 0x2F, 0x62, 0x18B, 0x62F, 0x18BF, 0x23FF const RV34_SLICE_START_BITS: [u8; 6] = [ 6, 7, 9, 11, 13, 14 ]; pub fn get_slice_start_offset_bits(w: usize, h: usize) -> u8 { + if (w == 0) || (h == 0) { + return 0; + } let mb_size = ((w + 15) >> 4) * ((h + 15) >> 4) - 1; let mut idx: usize = 0; while (idx < 5) && (RV34_MB_MAX_SIZES[idx] < mb_size) { idx += 1; } @@ -713,16 +696,16 @@ impl MBHist { fn decode_mv(br: &mut BitReader) -> DecoderResult { let x = br.read_code_signed(IntCodeType::Gamma)? as i16; let y = br.read_code_signed(IntCodeType::Gamma)? as i16; - Ok(MV{ x: x, y: y }) + Ok(MV{ x, y }) } -fn do_mc_16x16(dsp: &Box, buf: &mut NAVideoBuffer, prevbuf: &NAVideoBuffer, mb_x: usize, mb_y: usize, mv: MV, avg: bool) { +fn do_mc_16x16(dsp: &mut dyn RV34DSP, buf: &mut NAVideoBuffer, prevbuf: &NAVideoBuffer, mb_x: usize, mb_y: usize, mv: MV, avg: bool) { dsp.do_luma_mc (buf, prevbuf, mb_x * 16, mb_y * 16, mv, true, avg); dsp.do_chroma_mc(buf, prevbuf, mb_x * 8, mb_y * 8, 1, mv, true, avg); dsp.do_chroma_mc(buf, prevbuf, mb_x * 8, mb_y * 8, 2, mv, true, avg); } -fn do_mc_8x8(dsp: &Box, buf: &mut NAVideoBuffer, prevbuf: &NAVideoBuffer, mb_x: usize, xoff: usize, mb_y: usize, yoff: usize, mv: MV, avg: bool) { +fn do_mc_8x8(dsp: &mut dyn RV34DSP, buf: &mut NAVideoBuffer, prevbuf: &NAVideoBuffer, mb_x: usize, xoff: usize, mb_y: usize, yoff: usize, mv: MV, avg: bool) { dsp.do_luma_mc (buf, prevbuf, mb_x * 16 + xoff * 8, mb_y * 16 + yoff * 8, mv, false, avg); dsp.do_chroma_mc(buf, prevbuf, mb_x * 8 + xoff * 4, mb_y * 8 + yoff * 4, 1, mv, false, avg); dsp.do_chroma_mc(buf, prevbuf, mb_x * 8 + xoff * 4, mb_y * 8 + yoff * 4, 2, mv, false, avg); @@ -754,7 +737,7 @@ fn do_avg(cdsp: &RV34CommonDSP, buf: &mut NAVideoBuffer, avg_buf: &NAVideoBu pub struct RV34Decoder { is_rv30: bool, coderead: RV34Codes, - dsp: Box, + dsp: Box, cdsp: RV34CommonDSP, width: usize, height: usize, @@ -772,15 +755,15 @@ pub struct RV34Decoder { } impl RV34Decoder { - pub fn new(is_rv30: bool, dsp: Box) -> Self { + pub fn new(is_rv30: bool, dsp: Box) -> Self { let tmp_vinfo = NAVideoInfo::new(16, 16, false, YUV420_FORMAT); let vt = alloc_video_buffer(tmp_vinfo, 4).unwrap(); let vb = vt.get_vbuf(); let avg_buf = vb.unwrap(); RV34Decoder { - is_rv30: is_rv30, + is_rv30, coderead: RV34Codes::new(), - dsp: dsp, + dsp, cdsp: RV34CommonDSP::new(), ipbs: IPBShuffler::new(), mvi: MVInfo::new(), @@ -790,15 +773,15 @@ impl RV34Decoder { last_ts: 0, next_ts: 0, ratio1: 0, ratio2: 0, is_b: false, - avg_buf: avg_buf, + avg_buf, base_ts: 0, } } - fn decode_mb_header_intra(&mut self, bd: &mut RV34BitstreamDecoder, br: &mut BitReader, is_i16: bool, im: &mut IntraModeState, q: u8, has_top: bool, has_dq: bool) -> DecoderResult { + fn decode_mb_header_intra(&mut self, bd: &mut dyn RV34BitstreamDecoder, br: &mut BitReader, is_i16: bool, im: &mut IntraModeState, q: u8, has_top: bool, has_dq: bool) -> DecoderResult { if is_i16 { let imode = br.read(2)? as i8; im.fill_block(imode); - return Ok(MBInfo { mbtype: MBType::MBIntra16, skip_run: 0, dquant: false }); + Ok(MBInfo { mbtype: MBType::MBIntra16, skip_run: 0, dquant: false }) } else { let dq = if !has_dq { if !self.is_rv30 { !br.read_bool()? } else { false } @@ -807,10 +790,10 @@ impl RV34Decoder { decode_dquant(br, q)?; } bd.decode_intra_pred(br, im.cache.data.as_mut_slice(), im.cache.xpos, im.cache.stride, has_top)?; - return Ok(MBInfo { mbtype: MBType::MBIntra, skip_run: 0, dquant: dq }); + Ok(MBInfo { mbtype: MBType::MBIntra, skip_run: 0, dquant: dq }) } } - fn decode_mb_header_inter(&mut self, bd: &mut RV34BitstreamDecoder, br: &mut BitReader, ftype: FrameType, mbtype: MBType, im: &mut IntraModeState, q: u8, has_top: bool) -> DecoderResult { + fn decode_mb_header_inter(&mut self, bd: &mut dyn RV34BitstreamDecoder, br: &mut BitReader, ftype: FrameType, mbtype: MBType, im: &mut IntraModeState, q: u8, has_top: bool) -> DecoderResult { let hdr = bd.decode_inter_mb_hdr(br, ftype, mbtype)?; validate!(hdr.mbtype != MBType::Invalid); if hdr.dquant { @@ -819,7 +802,7 @@ impl RV34Decoder { if hdr.mbtype.is_intra() { return self.decode_mb_header_intra(bd, br, hdr.mbtype.is_16(), im, q, has_top, true); } - return Ok(hdr); + Ok(hdr) } fn decode_mb_intra(&mut self, sstate: &SState, imode: &IntraModeState, buf: &mut NAVideoBuffer, br: &mut BitReader, is_16: bool) -> DecoderResult<()> { @@ -941,19 +924,19 @@ impl RV34Decoder { MBType::MBP16x16 | MBType::MBP16x16Mix => { if let Some(ref prevbuf) = self.ipbs.get_lastref() { let mv = self.mvi.get_mv(mb_x, mb_y, 0, 0, true); - do_mc_16x16(&self.dsp, buf, prevbuf, mb_x, mb_y, mv, false); + do_mc_16x16(self.dsp.as_mut(), buf, prevbuf, mb_x, mb_y, mv, false); } }, MBType::MBForward => { if let Some(ref fwdbuf) = self.ipbs.get_b_fwdref() { let mv = self.mvi.get_mv(mb_x, mb_y, 0, 0, true); - do_mc_16x16(&self.dsp, buf, fwdbuf, mb_x, mb_y, mv, false); + do_mc_16x16(self.dsp.as_mut(), buf, fwdbuf, mb_x, mb_y, mv, false); } }, MBType::MBBackward => { if let Some(ref bwdbuf) = self.ipbs.get_b_bwdref() { let mv = self.mvi.get_mv(mb_x, mb_y, 0, 0, false); - do_mc_16x16(&self.dsp, buf, bwdbuf, mb_x, mb_y, mv, false); + do_mc_16x16(self.dsp.as_mut(), buf, bwdbuf, mb_x, mb_y, mv, false); } }, MBType::MBP8x8 | MBType::MBP8x16 | MBType::MBP16x8 => { @@ -961,14 +944,14 @@ impl RV34Decoder { for y in 0..2 { for x in 0..2 { let mv = self.mvi.get_mv(mb_x, mb_y, x, y, true); - do_mc_8x8(&self.dsp, buf, prevbuf, mb_x, x, mb_y, y, mv, false); + do_mc_8x8(self.dsp.as_mut(), buf, prevbuf, mb_x, x, mb_y, y, mv, false); } } } }, MBType::MBSkip if !self.is_b => { if let Some(ref prevbuf) = self.ipbs.get_lastref() { - do_mc_16x16(&self.dsp, buf, prevbuf, mb_x, mb_y, ZERO_MV, false); + do_mc_16x16(self.dsp.as_mut(), buf, prevbuf, mb_x, mb_y, ZERO_MV, false); } }, MBType::MBSkip | MBType::MBDirect => { @@ -976,8 +959,8 @@ impl RV34Decoder { for y in 0..2 { for x in 0..2 { let (mv_f, mv_b) = self.ref_mvi.get_mv(mb_x, mb_y, x, y, true).scale(sstate.trd, sstate.trb); - do_mc_8x8(&self.dsp, buf, fwdbuf, mb_x, x, mb_y, y, mv_f, false); - do_mc_8x8(&self.dsp, &mut self.avg_buf, bwdbuf, mb_x, x, mb_y, y, mv_b, true); + do_mc_8x8(self.dsp.as_mut(), buf, fwdbuf, mb_x, x, mb_y, y, mv_f, false); + do_mc_8x8(self.dsp.as_mut(), &mut self.avg_buf, bwdbuf, mb_x, x, mb_y, y, mv_b, true); do_avg(&self.cdsp, buf, &self.avg_buf, mb_x, x, mb_y, y, 8, self.ratio1, self.ratio2); } } @@ -987,8 +970,8 @@ impl RV34Decoder { if let (Some(ref fwdbuf), Some(ref bwdbuf)) = (self.ipbs.get_b_fwdref(), self.ipbs.get_b_bwdref()) { let mv_f = self.mvi.get_mv(mb_x, mb_y, 0, 0, true); let mv_b = self.mvi.get_mv(mb_x, mb_y, 0, 0, false); - do_mc_16x16(&self.dsp, buf, fwdbuf, mb_x, mb_y, mv_f, false); - do_mc_16x16(&self.dsp, &mut self.avg_buf, bwdbuf, mb_x, mb_y, mv_b, true); + do_mc_16x16(self.dsp.as_mut(), buf, fwdbuf, mb_x, mb_y, mv_f, false); + do_mc_16x16(self.dsp.as_mut(), &mut self.avg_buf, bwdbuf, mb_x, mb_y, mv_b, true); do_avg(&self.cdsp, buf, &self.avg_buf, mb_x, 0, mb_y, 0, 16, self.ratio1, self.ratio2); } }, @@ -1112,13 +1095,14 @@ impl RV34Decoder { } } - pub fn parse_frame(&mut self, src: &[u8], bd: &mut RV34BitstreamDecoder) -> DecoderResult<(NABufferType, FrameType, u64)> { + #[allow(clippy::cognitive_complexity)] + pub fn parse_frame(&mut self, supp: &mut NADecoderSupport, src: &[u8], bd: &mut dyn RV34BitstreamDecoder) -> DecoderResult<(NABufferType, FrameType, u64)> { let mut slice_offs: Vec = Vec::new(); parse_slice_offsets(src, &mut slice_offs)?; let ini_off = slice_offs.len() * 8 + 1; - let mut br = BitReader::new(&src[ini_off..], src.len() - ini_off, BitReaderMode::BE); - let hdr0 = decode_slice_header(&mut br, bd, 0, &slice_offs, self.width, self.height)?; + let mut br = BitReader::new(&src[ini_off..], BitReaderMode::BE); + let hdr0 = decode_slice_header(&mut br, bd, 0, slice_offs.as_slice(), self.width, self.height)?; validate!((hdr0.width != 0) && (hdr0.height != 0)); self.width = hdr0.width; self.height = hdr0.height; @@ -1143,6 +1127,22 @@ impl RV34Decoder { self.base_ts += 1 << 13; } } + match hdr0.ftype { + FrameType::P => { + if self.ipbs.get_lastref().is_none() { + return Err(DecoderError::MissingReference); + } + }, + FrameType::B => { + if self.ipbs.get_lastref().is_none() { + return Err(DecoderError::MissingReference); + } + if self.ipbs.get_nextref().is_none() { + return Err(DecoderError::MissingReference); + } + }, + _ => {}, + }; let ts_diff = (self.next_ts << 3).wrapping_sub(hdr0.pts << 3) >> 3; let ts = self.base_ts + (self.next_ts as u64) - (ts_diff as u64); sstate.trd = (self.next_ts << 3).wrapping_sub(self.last_ts << 3) >> 3; @@ -1157,10 +1157,21 @@ impl RV34Decoder { //todo validate against ref frame let vinfo = NAVideoInfo::new(hdr0.width, hdr0.height, false, YUV420_FORMAT); - let bufret = alloc_video_buffer(vinfo, 4); - if let Err(_) = bufret { return Err(DecoderError::InvalidData); } - let bufinfo = bufret.unwrap(); - let mut buf = bufinfo.get_vbuf().unwrap(); + let ret = supp.pool_u8.get_free(); + if ret.is_none() { + return Err(DecoderError::AllocError); + } + let mut buf = ret.unwrap(); + if buf.get_info() != vinfo { + self.ipbs.clear(); + supp.pool_u8.reset(); + supp.pool_u8.prealloc_video(vinfo, 4)?; + let ret = supp.pool_u8.get_free(); + if ret.is_none() { + return Err(DecoderError::AllocError); + } + buf = ret.unwrap(); + } sstate.q = q; sstate.has_top = false; @@ -1221,7 +1232,7 @@ impl RV34Decoder { if !self.is_b { self.mvi.set_mb(mb_x, mb_y, mbh.mbtype, &self.ref_mvi, &mvs, &sstate); } else { - let (mv_f, mv_b) = bd.predict_b_mv(&sstate, &self.mvi, mbh.mbtype, &mvs, &mbinfo); + let (mv_f, mv_b) = bd.predict_b_mv(&sstate, &self.mvi, mbh.mbtype, &mvs, mbinfo.as_slice()); self.mvi.fill(mb_x, mb_y, true, mv_f); self.mvi.fill(mb_x, mb_y, false, mv_b); } @@ -1245,11 +1256,12 @@ impl RV34Decoder { sstate.q_dc = bd.quant_dc(true, q); self.decode_mb_intra(&sstate, &imode, &mut buf, &mut br, is_16)?; } else { + sstate.q_dc = bd.quant_dc(false, q); imode.fill_block(0); self.decode_mb_inter(&sstate, &mbh, &mut buf, &mut br, is_16)?; } - let mi = RV34MBInfo { cbp: cbp, q: q, mbtype: mbh.mbtype, deblock: 0, cbp_c: 0 }; + let mi = RV34MBInfo { cbp, q, mbtype: mbh.mbtype, deblock: 0, cbp_c: 0 }; mbinfo.push(mi); if is_intra { mbinfo[mb_pos].deblock = 0xFFFF; @@ -1261,19 +1273,22 @@ impl RV34Decoder { mb_pos += 1; } if hdr0.deblock && (mb_y >= 1) { - self.dsp.loop_filter(&mut buf, hdr0.ftype, &mbinfo, mb_w, mb_y - 1); + self.dsp.loop_filter(&mut buf, hdr0.ftype, &mbinfo, mb_w, mb_h, mb_y - 1); } imode.update(); } if hdr0.deblock { - self.dsp.loop_filter(&mut buf, hdr0.ftype, &mbinfo, mb_w, mb_h - 1); + self.dsp.loop_filter(&mut buf, hdr0.ftype, &mbinfo, mb_w, mb_h, mb_h - 1); } if !self.is_b { - self.ipbs.add_frame(buf); + self.ipbs.add_frame(buf.clone()); mem::swap(&mut self.mvi, &mut self.ref_mvi); mem::swap(&mut self.mbinfo, &mut mbinfo); } - Ok((bufinfo, hdr0.ftype, ts)) + Ok((NABufferType::Video(buf), hdr0.ftype, ts)) + } + pub fn flush(&mut self) { + self.ipbs.clear(); } }