X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-realmedia%2Fsrc%2Fcodecs%2Frv60.rs;h=1d13efdd9e073cce2976b335363da40b7bc87014;hb=61d3e29467a4a634bbca56b8acfadcc346122a50;hp=cf09845ef9b2f1851a0aa6ea3adea3d0c7b9c5ad;hpb=b70cc0062fd4d791ee20f23439a3b08a04921835;p=nihav.git diff --git a/nihav-realmedia/src/codecs/rv60.rs b/nihav-realmedia/src/codecs/rv60.rs index cf09845..1d13efd 100644 --- a/nihav-realmedia/src/codecs/rv60.rs +++ b/nihav-realmedia/src/codecs/rv60.rs @@ -1,8 +1,6 @@ -use std::rc::Rc; -use std::cell::RefCell; use nihav_core::formats::YUV420_FORMAT; use nihav_core::frame::*; -use nihav_core::codecs::{NADecoder, MV, ZERO_MV, DecoderError, DecoderResult, IPBShuffler}; +use nihav_core::codecs::{NADecoder, NADecoderSupport, MV, ZERO_MV, DecoderError, DecoderResult, IPBShuffler}; use nihav_core::io::byteio::{MemoryReader,ByteReader}; use nihav_core::io::bitreader::{BitReader,BitReaderMode}; use nihav_core::io::intcode::*; @@ -23,7 +21,7 @@ impl UniqueList { fn add(&mut self, cand: A) { if self.fill == self.max_size { return; } let mut unique = true; - for el in self.list.into_iter().take(self.fill) { + for el in self.list.iter().take(self.fill) { if *el == cand { unique = false; break; @@ -610,13 +608,13 @@ impl DeblockInfo { } struct RealVideo60Decoder { - info: Rc, + info: NACodecInfoRef, cbs: RV60Codebooks, ipbs: IPBShuffler, dsp: RV60DSP, ipred: IntraPredContext, - avg_buf: NAVideoBuffer, + avg_buf: NAVideoBufferRef, y_coeffs: [i16; 16 * 16], u_coeffs: [i16; 8 * 8], @@ -647,7 +645,7 @@ impl RealVideo60Decoder { let vb = vt.get_vbuf(); let avg_buf = vb.unwrap(); RealVideo60Decoder{ - info: Rc::new(DUMMY_CODEC_INFO), + info: NACodecInfoRef::default(), cbs: RV60Codebooks::init(), ipbs: IPBShuffler::new(), ipred: IntraPredContext::new(), @@ -671,7 +669,7 @@ impl RealVideo60Decoder { ypos: 0, } } - fn decode_cu_line(&mut self, buf: &mut NAVideoBuffer, hdr: &FrameHeader, src: &[u8], cu_y: usize) -> DecoderResult<()> { + fn decode_cu_line(&mut self, buf: &mut NASimpleVideoFrame, hdr: &FrameHeader, src: &[u8], cu_y: usize) -> DecoderResult<()> { let mut br = BitReader::new(src, src.len(), BitReaderMode::BE); let cu_w = hdr.get_width_cu(); let dqp = hdr.read_line_qp_offset(&mut br)?; @@ -713,7 +711,7 @@ println!(" left {} bits", br.left()); } Ok(()) } - fn decode_cb_tree(&mut self, buf: &mut NAVideoBuffer, hdr: &FrameHeader, br: &mut BitReader, xpos: usize, ypos: usize, log_size: u8) -> DecoderResult<()> { + fn decode_cb_tree(&mut self, buf: &mut NASimpleVideoFrame, hdr: &FrameHeader, br: &mut BitReader, xpos: usize, ypos: usize, log_size: u8) -> DecoderResult<()> { if (xpos >= hdr.width) || (ypos >= hdr.height) { return Ok(()); } let size = 1 << log_size; @@ -738,19 +736,17 @@ println!(" left {} bits", br.left()); CUType::Intra => { let itype = self.blk_info[self.blk_pos].imode; if !split_i4x4 { - let dstride = buf.get_stride(0); + let dstride = buf.stride[0]; let off = xpos + ypos * dstride; - let mut data = buf.get_data_mut(); - let dst = &mut data; + let dst = &mut buf.data; self.populate_ipred(hdr, dst, 0, dstride, 0, 0, size, true); self.ipred.pred_angle(dst, off, dstride, size, itype as usize, true); } for comp in 1..3 { - let dstride = buf.get_stride(comp); - let soff = buf.get_offset(comp); + let dstride = buf.stride[comp]; + let soff = buf.offset[comp]; let off = soff + (xpos >> 1) + (ypos >> 1) * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.populate_ipred(hdr, dst, soff, dstride, 0, 0, size >> 1, false); self.ipred.pred_angle(&mut dst, off, dstride, size >> 1, itype as usize, false); } @@ -793,7 +789,10 @@ println!(" left {} bits", br.left()); validate!(hdr.ftype == FrameType::B); if let (Some(ref prevbuf), Some(ref nextbuf)) = (self.ipbs.get_b_fwdref(), self.ipbs.get_b_bwdref()) { self.dsp.do_mc(buf, prevbuf, bx, by, bw, bh, mv.f_mv, false); - self.dsp.do_mc(&mut self.avg_buf, nextbuf, bx, by, bw, bh, mv.b_mv, true); + { + let mut avg_buf = NASimpleVideoFrame::from_video_buf(&mut self.avg_buf).unwrap(); + self.dsp.do_mc(&mut avg_buf, nextbuf, bx, by, bw, bh, mv.b_mv, true); + } self.dsp.do_avg(buf, &self.avg_buf, bx, by, bw, bh); } }, @@ -846,10 +845,9 @@ println!(" left {} bits", br.left()); let i = x + y * 4; if ((cbp16 >> i) & 1) != 0 { self.dsp.transform4x4(&mut self.y_coeffs[i * 16..][..16]); - let dstride = buf.get_stride(0); + let dstride = buf.stride[0]; let off = xpos + x * 4 + (ypos + y * 4) * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs[i*16..][..16], 4); } } @@ -861,18 +859,16 @@ println!(" left {} bits", br.left()); let yoff = (ypos >> 1) + y * 4; if ((cbp16 >> (16 + i)) & 1) != 0 { self.dsp.transform4x4(&mut self.u_coeffs[i * 16..][..16]); - let dstride = buf.get_stride(1); - let off = buf.get_offset(1) + xoff + yoff * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let dstride = buf.stride[1]; + let off = buf.offset[1] + xoff + yoff * dstride; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs[i * 16..][..16], 4); } if ((cbp16 >> (20 + i)) & 1) != 0 { self.dsp.transform4x4(&mut self.v_coeffs[i * 16..][..16]); - let dstride = buf.get_stride(2); - let off = buf.get_offset(2) + xoff + yoff * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let dstride = buf.stride[2]; + let off = buf.offset[2] + xoff + yoff * dstride; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs[i * 16..][..16], 4); } } @@ -888,10 +884,9 @@ println!(" left {} bits", br.left()); let xoff = (i & 1) * 4; let yoff = (i & 2) * 2; if split_i4x4 { - let dstride = buf.get_stride(0); + let dstride = buf.stride[0]; let off = xpos + xoff + (ypos + yoff) * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.populate_ipred(hdr, dst, 0, dstride, xoff, yoff, 4, true); let itype = self.blk_info[self.blk_pos + (i & 1) + (i >> 1) * self.blk_stride].imode; self.ipred.pred_angle(&mut dst, off, dstride, 4, itype as usize, false); @@ -899,30 +894,27 @@ println!(" left {} bits", br.left()); if ((cbp8 >> i) & 1) != 0 { let blk = &mut self.y_coeffs[i * 16..][..16]; self.dsp.transform4x4(blk); - let dstride = buf.get_stride(0); - let soff = buf.get_offset(0); + let dstride = buf.stride[0]; + let soff = buf.offset[0]; let off = soff + xpos + xoff + (ypos + yoff) * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, blk, 4); } } if ((cbp8 >> 4) & 1) != 0 { self.dsp.transform4x4(&mut self.u_coeffs); - let dstride = buf.get_stride(1); - let soff = buf.get_offset(1); + let dstride = buf.stride[1]; + let soff = buf.offset[1]; let off = soff + (xpos >> 1) + (ypos >> 1) * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 4); } if ((cbp8 >> 5) & 1) != 0 { self.dsp.transform4x4(&mut self.v_coeffs); - let dstride = buf.get_stride(2); - let soff = buf.get_offset(2); + let dstride = buf.stride[2]; + let soff = buf.offset[2]; let off = soff + (xpos >> 1) + (ypos >> 1) * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs, 4); } } @@ -935,28 +927,25 @@ println!(" left {} bits", br.left()); rv6_decode_cu_8x8(br, &self.cbs, is_intra, self.qp, self.sel_qp, &mut self.y_coeffs, &mut self.u_coeffs, &mut self.v_coeffs, cbp8, false)?; if (cbp8 & 0xF) != 0 { self.dsp.transform8x8(&mut self.y_coeffs); - let dstride = buf.get_stride(0); + let dstride = buf.stride[0]; let off = xpos + ypos * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs, 8); } if ((cbp8 >> 4) & 1) != 0 { self.dsp.transform4x4(&mut self.u_coeffs); - let dstride = buf.get_stride(1); - let soff = buf.get_offset(1); + let dstride = buf.stride[1]; + let soff = buf.offset[1]; let off = soff + (xpos >> 1) + (ypos >> 1) * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 4); } if ((cbp8 >> 5) & 1) != 0 { self.dsp.transform4x4(&mut self.v_coeffs); - let dstride = buf.get_stride(2); - let soff = buf.get_offset(2); + let dstride = buf.stride[2]; + let soff = buf.offset[2]; let off = soff + (xpos >> 1) + (ypos >> 1) * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs, 4); } } @@ -980,28 +969,25 @@ println!(" left {} bits", br.left()); rv6_decode_cu_16x16(br, &self.cbs, is_intra, self.qp, self.sel_qp, &mut self.y_coeffs, &mut self.u_coeffs, &mut self.v_coeffs, super_cbp)?; if (super_cbp & 0xFFFF) != 0 { self.dsp.transform16x16(&mut self.y_coeffs); - let dstride = buf.get_stride(0); + let dstride = buf.stride[0]; let off = xpos + x * 16 + (ypos + y * 16) * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, &self.y_coeffs, 16); } if ((super_cbp >> 16) & 0xF) != 0 { self.dsp.transform8x8(&mut self.u_coeffs); - let dstride = buf.get_stride(1); - let soff = buf.get_offset(1); + let dstride = buf.stride[1]; + let soff = buf.offset[1]; let off = soff + (xpos >> 1) + x * 8 + ((ypos >> 1) + y * 8) * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, &self.u_coeffs, 8); } if ((super_cbp >> 20) & 0xF) != 0 { self.dsp.transform8x8(&mut self.v_coeffs); - let dstride = buf.get_stride(2); - let soff = buf.get_offset(2); + let dstride = buf.stride[2]; + let soff = buf.offset[2]; let off = soff + (xpos >> 1) + x * 8 + ((ypos >> 1) + y * 8) * dstride; - let mut data = buf.get_data_mut(); - let mut dst = &mut data; + let mut dst = &mut buf.data; self.dsp.add_block(&mut dst, off, dstride, &self.v_coeffs, 8); } } @@ -1131,7 +1117,7 @@ println!(" left {} bits", br.left()); } } } - for el in RV60_CANDIDATE_INTRA_ANGLES.into_iter() { + for el in RV60_CANDIDATE_INTRA_ANGLES.iter() { ipm_cand.add(*el); } // actually decode prediction mode @@ -1143,7 +1129,7 @@ println!(" left {} bits", br.left()); let mut imode = mode; let mut ipm_cs: [u8; 3] = [ipm_cand.list[0], ipm_cand.list[1], ipm_cand.list[2]]; ipm_cs.sort(); - for ic in ipm_cs.into_iter() { + for ic in ipm_cs.iter() { if imode >= *ic { imode += 1; } @@ -1337,7 +1323,7 @@ println!(" left {} bits", br.left()); skip_cand.list[i] = MVInfo { f_mv: ZERO_MV, b_mv: ZERO_MV, mvref: MVRef::Ref0 }; } } - fn deblock_cb_tree(&mut self, buf: &mut NAVideoBuffer, hdr: &FrameHeader, xpos: usize, ypos: usize, log_size: u8) { + fn deblock_cb_tree(&mut self, buf: &mut NASimpleVideoFrame, hdr: &FrameHeader, xpos: usize, ypos: usize, log_size: u8) { if (xpos >= hdr.width) || (ypos >= hdr.height) { return; } let split = (log_size > 3) && self.cu_splits.pop().unwrap(); if split { @@ -1405,11 +1391,11 @@ println!(" left {} bits", br.left()); } impl NADecoder for RealVideo60Decoder { - fn init(&mut self, info: Rc) -> DecoderResult<()> { - if let NACodecTypeInfo::Video(_vinfo) = info.get_properties() { + fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> { + if let NACodecTypeInfo::Video(vinfo) = info.get_properties() { let fmt = YUV420_FORMAT; let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt)); - self.info = Rc::new(NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata())); + self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref(); let edata = info.get_extradata().unwrap(); let src: &[u8] = &edata; @@ -1426,13 +1412,17 @@ impl NADecoder for RealVideo60Decoder { //self.bd.width = vinfo.get_width(); //self.bd.height = vinfo.get_height(); //self.frmmgr.clear(); + + supp.pool_u8.set_dec_bufs(3); + supp.pool_u8.prealloc_video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, fmt), 6)?; + Ok(()) } else { println!("???"); Err(DecoderError::InvalidData) } } - fn decode(&mut self, pkt: &NAPacket) -> DecoderResult { + fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult { let src = pkt.get_buffer(); validate!(src.len() > 9); @@ -1443,10 +1433,21 @@ println!("???"); hdr.parse_slice_sizes(&mut br, &mut slices)?; let tmp_vinfo = NAVideoInfo::new(hdr.width, hdr.height, false, YUV420_FORMAT); - let res = alloc_video_buffer(tmp_vinfo, 6); - if !res.is_ok() { return Err(DecoderError::InvalidData); } - let bufinfo = res.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() != tmp_vinfo { + self.ipbs.clear(); + supp.pool_u8.reset(); + supp.pool_u8.prealloc_video(tmp_vinfo, 6)?; + let ret = supp.pool_u8.get_free(); + if ret.is_none() { + return Err(DecoderError::AllocError); + } + buf = ret.unwrap(); + } let cu_w = hdr.get_width_cu(); let cu_h = hdr.get_height_cu(); @@ -1459,23 +1460,24 @@ println!("???"); self.dblk.reinit(hdr.width, hdr.height); } let mut off = hsize + ((br.tell() >> 3) as usize); + let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap(); for (cu_y, size) in slices.into_iter().enumerate() { - self.decode_cu_line(&mut buf, &hdr, &src[off..][..size], cu_y)?; + self.decode_cu_line(&mut dframe, &hdr, &src[off..][..size], cu_y)?; off += size; } if (hdr.ftype == FrameType::I) || (hdr.ftype == FrameType::P) { - self.ipbs.add_frame(buf); + self.ipbs.add_frame(buf.clone()); } - let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo); + let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), NABufferType::Video(buf)); frm.set_keyframe(hdr.ftype == FrameType::I); frm.set_pts(Some(hdr.ts as u64)); frm.set_frame_type(hdr.ftype); - Ok(Rc::new(RefCell::new(frm))) + Ok(frm.into_ref()) } } -pub fn get_decoder() -> Box { +pub fn get_decoder() -> Box { Box::new(RealVideo60Decoder::new()) }