use std::mem;
-use std::rc::Rc;
-use std::cell::{Ref,RefCell};
use nihav_core::io::bitreader::*;
//use io::intcode::*;
use nihav_core::codecs::*;
-use nihav_core::formats::*;
-use nihav_core::frame::*;
+use nihav_core::frame::NABufferRef;
use super::ivi::*;
use super::ividsp::*;
pub fn scale_mv(val: i32, scale: u8) -> i32 {
- (val + (if val > 0 { 1 } else { 0 }) + (scale as i32) - 1) >> scale
+ (val + (if val > 0 { 1 } else { 0 }) + i32::from(scale) - 1) >> scale
}
#[derive(Clone,Copy)]
Ok(base + add)
} else {
let nbits = cb.bits[0];
- return Ok(IVI_REVS[nbits as usize][self.read(nbits)? as usize]);
+ Ok(IVI_REVS[nbits as usize][self.read(nbits)? as usize])
}
}
#[inline(always)]
];
#[allow(unused_variables)]
+#[allow(clippy::many_single_char_names)]
fn read_trans_band_header(br: &mut BitReader, w: usize, h: usize, dst: &mut [i16], dstride: usize) -> DecoderResult<()> {
let color_plane = br.read(2)?;
let bit_depth = br.read(3)?;
for i in 0..cb.len {
cb.bits[i] = br.read(4)? as u8;
}
+ cb = cb.init();
br.align();
let tile_start = br.tell();
Ok(())
}
-fn decode_block8x8(br: &mut BitReader, blk_cb: &IVICodebook, rvmap: &RVMap, tables: &TxParams8x8, is_intra: bool, is_2d: bool, prev_dc: &mut i32, quant: u8, coeffs: &mut [i32; 64], transform: &TrFunc) -> DecoderResult<()> {
+#[allow(clippy::cast_lossless)]
+fn decode_block8x8(br: &mut BitReader, blk_cb: &IVICodebook, rvmap: &RVMap, tables: &TxParams8x8, is_intra: bool, is_2d: bool, prev_dc: &mut i32, quant: u8, coeffs: &mut [i32; 64], transform: TrFunc) -> DecoderResult<()> {
let mut idx: isize = -1;
let quant_mat = if is_intra { tables.quant_intra } else { tables.quant_inter };
while idx <= 64 {
}
}
idx += run;
- validate!((idx >= 0) && (idx < 64));
+ validate!((0..64).contains(&idx));
let spos = tables.scan[idx as usize];
- let q = ((quant_mat[spos] as u32) * (quant as u32)) >> 9;
+ let q = (u32::from(quant_mat[spos]) * u32::from(quant)) >> 9;
if q > 1 {
let qq = q as i32;
let bias = (((q ^ 1) - 1) >> 1) as i32;
(transform)(coeffs);
Ok(())
}
-fn decode_block4x4(br: &mut BitReader, blk_cb: &IVICodebook, rvmap: &RVMap, tables: &TxParams4x4, is_intra: bool, is_2d: bool, prev_dc: &mut i32, quant: u8, coeffs: &mut [i32; 64], transform: &TrFunc) -> DecoderResult<()> {
+#[allow(clippy::cast_lossless)]
+fn decode_block4x4(br: &mut BitReader, blk_cb: &IVICodebook, rvmap: &RVMap, tables: &TxParams4x4, is_intra: bool, is_2d: bool, prev_dc: &mut i32, quant: u8, coeffs: &mut [i32; 64], transform: TrFunc) -> DecoderResult<()> {
let mut idx: isize = -1;
let quant_mat = if is_intra { tables.quant_intra } else { tables.quant_inter };
while idx <= 64 {
}
}
idx += run;
- validate!((idx >= 0) && (idx < 16));
+ validate!((0..16).contains(&idx));
let spos = tables.scan[idx as usize];
- let q = ((quant_mat[spos] as u32) * (quant as u32)) >> 9;
+ let q = (u32::from(quant_mat[spos]) * u32::from(quant)) >> 9;
if q > 1 {
let qq = q as i32;
let bias = (((q ^ 1) - 1) >> 1) as i32;
fn put_block(frame: &mut [i16], offs: usize, stride: usize, blk: &[i32], blk_size: usize) {
unsafe {
- let mut dptr = frame.as_mut_ptr().offset(offs as isize);
+ let mut dptr = frame.as_mut_ptr().add(offs);
for y in 0..blk_size {
for x in 0..blk_size {
- *dptr.offset(x as isize) = blk[x + y * blk_size] as i16;
+ *dptr.add(x) = blk[x + y * blk_size] as i16;
}
- dptr = dptr.offset(stride as isize);
+ dptr = dptr.add(stride);
}
}
}
fn add_block(frame: &mut [i16], offs: usize, stride: usize, blk: &[i32], blk_size: usize) {
unsafe {
- let mut dptr = frame.as_mut_ptr().offset(offs as isize);
+ let mut dptr = frame.as_mut_ptr().add(offs);
for y in 0..blk_size {
for x in 0..blk_size {
- *dptr.offset(x as isize) = (*dptr.offset(x as isize)).wrapping_add(blk[x + y * blk_size] as i16);
+ *dptr.add(x) = (*dptr.add(x)).wrapping_add(blk[x + y * blk_size] as i16);
}
- dptr = dptr.offset(stride as isize);
+ dptr = dptr.add(stride);
}
}
}
}
impl FrameData {
- fn new() -> Rc<RefCell<Self>> {
- Rc::new(RefCell::new(FrameData {
+ fn new() -> NABufferRef<Self> {
+ NABufferRef::new(FrameData {
plane_buf: [Vec::new(), Vec::new(), Vec::new(), Vec::new()],
plane_stride: [0, 0, 0, 0],
pic_hdr: PictureHeader::new_null(IVIFrameType::Intra),
- }))
+ })
}
fn realloc(&mut self, pic_hdr: &PictureHeader) -> DecoderResult<()> {
let width = align(pic_hdr.width, 6);
Ok(())
}
fn fill_plane(&mut self, vb: &mut NAVideoBuffer<u8>, plane: usize) {
- let (w, h) = vb.get_dimensions(plane);
- let mut didx = vb.get_offset(plane);
- let dstride = vb.get_stride(plane);
- let mut dst = vb.get_data_mut();
+ let dplane = if (plane == 1) || (plane == 2) { plane ^ 3 } else { plane };
+ let (w, h) = vb.get_dimensions(dplane);
+ let mut didx = vb.get_offset(dplane);
+ let dstride = vb.get_stride(dplane);
+ let dst = vb.get_data_mut().unwrap();
let src = &self.plane_buf[plane];
let mut sidx = 0;
let sstride = self.plane_stride[plane];
}
}
+#[allow(clippy::many_single_char_names)]
fn do_mc(dst: &mut [i16], dstride: usize, src: &[i16], sstride: usize, x: usize, y: usize, l: usize, r: usize, t: usize, b: usize, mv_x: i32, mv_y: i32, is_hpel: bool, blk_size: usize) {
let (xoff, yoff, mv_mode) = if is_hpel {
(mv_x >> 1, mv_y >> 1, ((mv_x & 1) + (mv_y & 1) * 2) as u8)
}
}
+#[allow(clippy::many_single_char_names)]
fn do_mc_b(dst: &mut [i16], dstride: usize, src1: &[i16], sstride1: usize, src2: &[i16], sstride2: usize, x: usize, y: usize, l: usize, r: usize, t: usize, b: usize, mv_x: i32, mv_y: i32, mv2_x: i32, mv2_y: i32, is_hpel: bool, blk_size: usize) {
let (xoff1, yoff1, mv_mode1) = if is_hpel {
(mv_x >> 1, mv_y >> 1, ((mv_x & 1) + (mv_y & 1) * 2) as u8)
pub trait IndeoXParser {
fn decode_picture_header(&mut self, br: &mut BitReader) -> DecoderResult<PictureHeader>;
fn decode_band_header(&mut self, br: &mut BitReader, pic_hdr: &PictureHeader, plane: usize, band: usize) -> DecoderResult<BandHeader>;
- fn decode_mb_info(&mut self, br: &mut BitReader, pic_hdr: &PictureHeader, band_hdr: &BandHeader, tile: &mut IVITile, ref_tile: Option<Ref<IVITile>>, mv_scale: u8) -> DecoderResult<()>;
+ fn decode_mb_info(&mut self, br: &mut BitReader, pic_hdr: &PictureHeader, band_hdr: &BandHeader, tile: &mut IVITile, ref_tile: Option<&IVITile>, mv_scale: u8) -> DecoderResult<()>;
fn recombine_plane(&mut self, src: &[i16], sstride: usize, dst: &mut [u8], dstride: usize, w: usize, h: usize);
}
pub struct IVIDecoder {
ftype: IVIFrameType,
- frames: [Rc<RefCell<FrameData>>; 4],
+ frames: [NABufferRef<FrameData>; 4],
cur_frame: usize,
prev_frame: usize,
next_frame: usize,
bref: Option<NABufferType>,
bands: Vec<BandHeader>,
- tiles: Vec<Rc<RefCell<IVITile>>>,
+ band_tiles: usize,
+ tiles: Vec<IVITile>,
num_tiles: [[usize; 4]; 4],
tile_start: [[usize; 4]; 4],
+
+ scalable: bool,
}
impl IVIDecoder {
- pub fn new() -> Self {
+ pub fn new(scalable: bool) -> Self {
let mut bands: Vec<BandHeader> = Vec::with_capacity(12);
bands.resize(12, BandHeader::new_empty(42, 42));
IVIDecoder {
vinfoa: NAVideoInfo::new(0, 0, false, YUVA410_FORMAT),
bref: None,
- bands: bands,
+ bands,
+ band_tiles: 0,
tiles: Vec::new(), tile_start: [[0; 4]; 4], num_tiles: [[0; 4]; 4],
+
+ scalable,
}
}
fn realloc(&mut self, pic_hdr: &PictureHeader) -> DecoderResult<()> {
let planes = if pic_hdr.transparent { 4 } else { 3 };
- //self.bands.truncate(0);
- self.tiles.truncate(0);
+ //self.bands.clear();
+ self.tiles.clear();
self.num_tiles = [[0; 4]; 4];
self.tile_start = [[0; 4]; 4];
let mut tstart: usize = 0;
tile_h = (tile_h + 1) >> 1;
}
}
+ if plane == 0 {
+ self.band_tiles = ((band_w + tile_w - 1) / tile_w) * ((band_h + tile_h - 1) / tile_h);
+ }
for band in 0..bands {
self.tile_start[plane][band] = tstart;
let band_xoff = if (band & 1) == 1 { band_w } else { 0 };
while x < band_w {
let cur_w = if x + tile_w <= band_w { tile_w } else { band_w - x };
let tile = IVITile::new(band_xoff + x, band_yoff + y, cur_w, cur_h);
- self.tiles.push(Rc::new(RefCell::new(tile)));
+ self.tiles.push(tile);
self.num_tiles[plane][band] += 1;
tstart += 1;
x += tile_w;
}
Ok(())
}
- fn decode_band(&mut self, pic_hdr: &PictureHeader, dec: &mut IndeoXParser, br: &mut BitReader, plane_no: usize, band_no: usize) -> DecoderResult<()> {
+ fn decode_band(&mut self, pic_hdr: &PictureHeader, dec: &mut dyn IndeoXParser, br: &mut BitReader, plane_no: usize, band_no: usize) -> DecoderResult<()> {
let bidx = match plane_no {
0 => { band_no },
_ => { pic_hdr.luma_bands + plane_no - 1 },
};
for tile_no in tstart..tend {
{
- let mut tile = self.tiles[tile_no].borrow_mut();
+ let tile = &mut self.tiles[tile_no];
let mb_w = (tile.w + mb_size - 1) / mb_size;
let mb_h = (tile.h + mb_size - 1) / mb_size;
tile.mb_w = mb_w;
tile.mb_h = mb_h;
- tile.mb.truncate(0);
+ tile.mb.clear();
tile.mb.resize(mb_w * mb_h, MB::new(0, 0));
}
}
br.align();
validate!(len > 0);
- let tile_end = tile_start + len * 8;
+ let tile_end = (tile_start & !7) + len * 8;
validate!(tile_end > br.tell());
validate!(tile_end <= br.tell() + (br.left() as usize));
{
- let mut tile = self.tiles[tile_no].borrow_mut();
- let ref_tile: Option<Ref<IVITile>>;
+ let ref_tile: Option<&IVITile>;
let mv_scale;
if (plane_no == 0) && (band_no == 0) {
mv_scale = 0;
} else {
mv_scale = (((self.bands[0].mb_size >> 3) as i8) - ((band.mb_size >> 3) as i8)) as u8;
}
+ let (ref_tiles, cur_tiles) = self.tiles.split_at_mut(tile_no);
+ let tile = &mut cur_tiles[0];
if plane_no != 0 || band_no != 0 {
- let rtile = self.tiles[0].borrow();
+ let rtile = &ref_tiles[tile_no % self.band_tiles];
if (tile.mb_w != rtile.mb_w) || (tile.mb_h != rtile.mb_h) {
ref_tile = None;
} else {
} else {
ref_tile = None;
}
- dec.decode_mb_info(br, pic_hdr, &band, &mut tile, ref_tile, mv_scale)?;
+ dec.decode_mb_info(br, pic_hdr, &band, tile, ref_tile, mv_scale)?;
}
- self.decode_tile(br, &band, tile_no, &tr, &tr_dc)?;
+ self.decode_tile(br, &band, tile_no, tr, tr_dc)?;
+ br.align();
let skip_part = tile_end - br.tell();
br.skip(skip_part as u32)?;
} else {
{
- let mut tile = self.tiles[tile_no].borrow_mut();
- let ref_tile: Option<Ref<IVITile>>;
+ let ref_tile: Option<&IVITile>;
let mv_scale;
if (plane_no == 0) && (band_no == 0) {
mv_scale = 0;
} else {
mv_scale = (((self.bands[0].mb_size >> 3) as i8) - ((band.mb_size >> 3) as i8)) as u8;
}
+ let (ref_tiles, cur_tiles) = self.tiles.split_at_mut(tile_no);
+ let tile = &mut cur_tiles[0];
if plane_no != 0 || band_no != 0 {
- let rtile = self.tiles[0].borrow();
+ let rtile = &ref_tiles[0];
if (tile.mb_w != rtile.mb_w) || (tile.mb_h != rtile.mb_h) {
ref_tile = None;
} else {
mb.mtype = MBType::Inter;
mb.cbp = 0;
if band.inherit_mv {
- if let Some(ref tileref) = ref_tile {
+ if let Some(tileref) = ref_tile {
let mx = tileref.mb[mb_idx].mv_x;
let my = tileref.mb[mb_idx].mv_y;
mb.mv_x = scale_mv(mx, mv_scale);
}
}
}
- self.decode_tile(br, &band, tile_no, &tr, &tr_dc)?;
+ self.decode_tile(br, &band, tile_no, tr, tr_dc)?;
}
}
self.bands[bidx] = band;
br.align();
Ok(())
}
- fn decode_tile(&mut self, br: &mut BitReader, band: &BandHeader, tile_no: usize, tr: &TrFunc, transform_dc: &TrFuncDC) -> DecoderResult<()> {
+ fn decode_tile(&mut self, br: &mut BitReader, band: &BandHeader, tile_no: usize, tr: TrFunc, transform_dc: TrFuncDC) -> DecoderResult<()> {
let mut mb_idx = 0;
let mut prev_dc: i32 = 0;
- let mut tile = self.tiles[tile_no].borrow_mut();
- let mut frame = self.frames[self.cur_frame].borrow_mut();
+ let tile = &mut self.tiles[tile_no];
+ let mut frame = self.frames[self.cur_frame].clone();
let stride = frame.plane_stride[band.plane_no];
let mut dstidx = tile.pos_x + tile.pos_y * stride;
- let mut dst = &mut frame.plane_buf[band.plane_no];
+ let dst = &mut frame.plane_buf[band.plane_no];
let pos_x = tile.pos_x;
let pos_y = tile.pos_y;
let tile_w = (tile.w + 15) & !15;
let mut cbp = mb.cbp;
for blk_no in 0..4 {
let mut blk: [i32; 64] = [0; 64];
- let boff = (blk_no & 1) * 8 + (blk_no & 2) * 4 * stride + mb_x * 16;
+ let boff = (blk_no & 1) * band.blk_size + (blk_no >> 1) * band.blk_size * stride + mb_x * band.mb_size;
if !is_intra {
if mb.mtype != MBType::Bidir {
let idx;
} else {
idx = self.next_frame;
}
- let pf = self.frames[idx].borrow();
+ let pf = &self.frames[idx];
do_mc(&mut dst[dstidx + boff..], stride,
&pf.plane_buf[band.plane_no], pf.plane_stride[band.plane_no],
- pos_x + mb_x * 16 + (blk_no & 1) * 8,
- pos_y + mb_y * 16 + (blk_no & 2) * 4,
+ pos_x + mb_x * band.mb_size + (blk_no & 1) * band.blk_size,
+ pos_y + mb_y * band.mb_size + (blk_no >> 1) * band.blk_size,
pos_x, pos_x + tile_w, pos_y, pos_y + tile_h,
- mb.mv_x, mb.mv_y, band.halfpel, 8);
+ mb.mv_x, mb.mv_y, band.halfpel, band.blk_size);
} else {
- let pf = self.frames[self.prev_frame].borrow();
- let nf = self.frames[self.next_frame].borrow();
+ let pf = &self.frames[self.prev_frame];
+ let nf = &self.frames[self.next_frame];
do_mc_b(&mut dst[dstidx + boff..], stride,
&pf.plane_buf[band.plane_no], pf.plane_stride[band.plane_no],
&nf.plane_buf[band.plane_no], nf.plane_stride[band.plane_no],
- pos_x + mb_x * 16 + (blk_no & 1) * 8,
- pos_y + mb_y * 16 + (blk_no & 2) * 4,
+ pos_x + mb_x * band.mb_size + (blk_no & 1) * band.blk_size,
+ pos_y + mb_y * band.mb_size + (blk_no >> 1) * band.blk_size,
pos_x, pos_x + tile_w, pos_y, pos_y + tile_h,
mb.mv_x, mb.mv_y, mb.mv2_x, mb.mv2_y, band.halfpel,
band.blk_size);
if let TxType::Transform8(ref params) = band.ttype {
decode_block8x8(br, &band.blk_cb, &band.rvmap, params, is_intra, band.tr.is_2d(), &mut prev_dc, mb.q, &mut blk, tr)?;
if is_intra {
- put_block(&mut dst, dstidx + boff, stride, &blk, 8);
+ put_block(dst, dstidx + boff, stride, &blk, 8);
} else {
- add_block(&mut dst, dstidx + boff, stride, &blk, 8);
+ add_block(dst, dstidx + boff, stride, &blk, 8);
+ }
+ }
+ if let TxType::Transform4(ref params) = band.ttype {
+ decode_block4x4(br, &band.blk_cb, &band.rvmap, params, is_intra, band.tr.is_2d(), &mut prev_dc, mb.q, &mut blk, tr)?;
+ if is_intra {
+ put_block(dst, dstidx + boff, stride, &blk, 4);
+ } else {
+ add_block(dst, dstidx + boff, stride, &blk, 4);
}
}
} else {
if is_intra {
(transform_dc)(&mut blk, prev_dc);
- put_block(&mut dst, dstidx + boff, stride, &blk, 8);
+ put_block(dst, dstidx + boff, stride, &blk, band.blk_size);
}
}
cbp >>= 1;
} else {
idx = self.next_frame;
}
- let pf = self.frames[idx].borrow();
+ let pf = &self.frames[idx];
do_mc(&mut dst[dstidx + mb_x * band.blk_size..], stride,
&pf.plane_buf[band.plane_no], pf.plane_stride[band.plane_no],
pos_x + mb_x * band.mb_size,
pos_x, pos_x + tile_w, pos_y, pos_y + tile_h,
mb.mv_x, mb.mv_y, band.halfpel, band.blk_size);
} else {
- let pf = self.frames[self.prev_frame].borrow();
- let nf = self.frames[self.next_frame].borrow();
+ let pf = &self.frames[self.prev_frame];
+ let nf = &self.frames[self.next_frame];
do_mc_b(&mut dst[dstidx + mb_x * band.blk_size..], stride,
&pf.plane_buf[band.plane_no], pf.plane_stride[band.plane_no],
&nf.plane_buf[band.plane_no], nf.plane_stride[band.plane_no],
}
if is_intra {
if band.blk_size == 8 {
- put_block(&mut dst, dstidx + mb_x * band.blk_size, stride, &blk, 8);
+ put_block(dst, dstidx + mb_x * band.blk_size, stride, &blk, 8);
} else {
- put_block(&mut dst, dstidx + mb_x * band.blk_size, stride, &blk, 4);
+ put_block(dst, dstidx + mb_x * band.blk_size, stride, &blk, 4);
}
} else {
if band.blk_size == 8 {
- add_block(&mut dst, dstidx + mb_x * band.blk_size, stride, &blk, 8);
+ add_block(dst, dstidx + mb_x * band.blk_size, stride, &blk, 8);
} else {
- add_block(&mut dst, dstidx + mb_x * band.blk_size, stride, &blk, 4);
+ add_block(dst, dstidx + mb_x * band.blk_size, stride, &blk, 4);
}
}
} else {
if is_intra {
(transform_dc)(&mut blk, prev_dc);
if band.blk_size == 8 {
- put_block(&mut dst, dstidx + mb_x * band.blk_size, stride, &blk, 8);
+ put_block(dst, dstidx + mb_x * band.blk_size, stride, &blk, 8);
} else {
- put_block(&mut dst, dstidx + mb_x * band.blk_size, stride, &blk, 4);
+ put_block(dst, dstidx + mb_x * band.blk_size, stride, &blk, 4);
}
}
}
}
dstidx += stride * band.mb_size;
}
- br.align();
Ok(())
}
unreachable!();
}
- fn decode_single_frame<'a>(&mut self, dec: &mut IndeoXParser, br: &mut BitReader<'a>) -> DecoderResult<NABufferType> {
+ fn decode_single_frame<'a>(&mut self, dec: &mut dyn IndeoXParser, br: &mut BitReader<'a>) -> DecoderResult<NABufferType> {
let pic_hdr = dec.decode_picture_header(br)?;
self.ftype = pic_hdr.ftype;
if pic_hdr.ftype.is_null() {
_ => {},
};
- let mut vinfo;
- if pic_hdr.transparent {
- vinfo = self.vinfoa.clone();
- } else {
- vinfo = self.vinfo.clone();
- }
+ let mut vinfo = if pic_hdr.transparent { self.vinfoa } else { self.vinfo };
vinfo.set_width(pic_hdr.width);
vinfo.set_height(pic_hdr.height);
let mut buftype = alloc_video_buffer(vinfo, 0)?;
self.realloc(&pic_hdr)?;
- self.frames[self.cur_frame].borrow_mut().realloc(&pic_hdr)?;
+ self.frames[self.cur_frame].realloc(&pic_hdr)?;
+
+ if !self.scalable {
+ for plane in 0..3 {
+ let num_bands = if plane == 0 { pic_hdr.luma_bands } else { pic_hdr.chroma_bands };
+ for band in 0..num_bands {
+ self.decode_band(&pic_hdr, dec, br, plane, band)?;
+ }
+ if let NABufferType::Video(ref mut vb) = buftype {
+ let mut frame = self.frames[self.cur_frame].clone();
+ if num_bands == 1 {
+ frame.fill_plane(vb, plane);
+ } else {
+ let dplane = if (plane == 1) || (plane == 2) { plane ^ 3 } else { plane };
+ let (w, h) = vb.get_dimensions(dplane);
+ let dstride = vb.get_stride(dplane);
+ let off = vb.get_offset(dplane);
+ let dst = vb.get_data_mut().unwrap();
+ dec.recombine_plane(&frame.plane_buf[plane], frame.plane_stride[plane], &mut dst[off..], dstride, w, h);
+ }
+ }
+ }
+ } else {
+ let mut bands_decoded = [[false; 10]; 3];
+ let mut num_decoded = 0;
+
+ let num_bands = [ pic_hdr.luma_bands, pic_hdr.chroma_bands, pic_hdr.chroma_bands ];
- for plane in 0..3 {
- let num_bands = if plane == 0 { pic_hdr.luma_bands } else { pic_hdr.chroma_bands };
- for band in 0..num_bands {
- self.decode_band(&pic_hdr, dec, br, plane, band)?;
+ for plane in 0..3 {
+ for band in 0..num_bands[plane] {
+ if br.peek(8) == 0x01 { // skipped scalable bands
+ br.skip(8)?;
+ continue;
+ }
+ self.decode_band(&pic_hdr, dec, br, plane, band)?;
+ bands_decoded[plane][band] = true;
+ num_decoded += 1;
+ }
+ }
+ if (num_decoded < num_bands[0] + num_bands[1] + num_bands[2]) && (br.left() > 0) {
+ validate!(br.read(8)? == 0x00);
+ while br.peek(8) == 0x00 {
+ if br.skip(8).is_err() { // happens at the end of data
+ break;
+ }
+ }
+ validate!((br.tell() & 31) == 0);
+
+ for plane in 0..3 {
+ for band in 0..num_bands[plane] {
+ if bands_decoded[plane][band] || br.left() == 0 {
+ continue;
+ }
+ self.decode_band(&pic_hdr, dec, br, plane, band)?;
+ bands_decoded[plane][band] = true;
+ num_decoded += 1;
+ }
+ }
}
+
if let NABufferType::Video(ref mut vb) = buftype {
- let mut frame = self.frames[self.cur_frame].borrow_mut();
- if num_bands == 1 {
- frame.fill_plane(vb, plane);
- } else {
- let (w, h) = vb.get_dimensions(plane);
- let dstride = vb.get_stride(plane);
- let off = vb.get_offset(plane);
- let mut dst = vb.get_data_mut();
- dec.recombine_plane(&frame.plane_buf[plane], frame.plane_stride[plane], &mut dst[off..], dstride, w, h);
+ for plane in 0..3 {
+ let mut frame = self.frames[self.cur_frame].clone();
+ if num_bands[plane] == 1 {
+ frame.fill_plane(vb, plane);
+ } else {
+ let dplane = if (plane == 1) || (plane == 2) { plane ^ 3 } else { plane };
+ let (w, h) = vb.get_dimensions(dplane);
+ let dstride = vb.get_stride(dplane);
+ let off = vb.get_offset(dplane);
+ let dst = vb.get_data_mut().unwrap();
+ dec.recombine_plane(&frame.plane_buf[plane], frame.plane_stride[plane], &mut dst[off..], dstride, w, h);
+ }
}
}
}
if pic_hdr.transparent {
- let mut frame = self.frames[self.cur_frame].borrow_mut();
+ let mut frame = self.frames[self.cur_frame].clone();
let stride = frame.plane_stride[3];
read_trans_band_header(br, pic_hdr.width, pic_hdr.height, &mut frame.plane_buf[3], stride)?;
if let NABufferType::Video(ref mut vb) = buftype {
}
match self.ftype {
- IVIFrameType::Intra | IVIFrameType::Inter => {
+ IVIFrameType::Intra | IVIFrameType::Intra1 | IVIFrameType::Inter => {
self.iref_1 = self.iref_0;
self.iref_0 = self.cur_frame;
self.scal_ref = self.cur_frame;
Ok(buftype)
}
- pub fn decode_frame<'a>(&mut self, dec: &mut IndeoXParser, br: &mut BitReader<'a>) -> DecoderResult<NABufferType> {
+ pub fn decode_frame<'a>(&mut self, dec: &mut dyn IndeoXParser, br: &mut BitReader<'a>) -> DecoderResult<NABufferType> {
let res = self.decode_single_frame(dec, br);
if res.is_err() { return res; }
if (self.ftype == IVIFrameType::Intra) && (br.left() > 16) {
let seq = br.peek(21);
if seq == 0xBFFF8 {
let res2 = self.decode_single_frame(dec, br);
- if res2.is_ok() {
- self.bref = Some(res2.unwrap());
+ if let Ok(res) = res2 {
+ self.bref = Some(res);
}
}
self.ftype = IVIFrameType::Intra;
}
}
+ if self.bref.is_some() && self.ftype == IVIFrameType::Inter {
+ let mut bref: Option<NABufferType> = Some(res.unwrap());
+ mem::swap(&mut bref, &mut self.bref);
+ return Ok(bref.unwrap());
+ }
if let Ok(NABufferType::None) = res {
if self.bref.is_some() {
let mut bref: Option<NABufferType> = None;
res
}
- pub fn is_intra(&mut self) -> bool {
+ pub fn flush(&mut self) {
+ self.prev_frame = MISSING_REF;
+ self.next_frame = MISSING_REF;
+ self.iref_0 = MISSING_REF;
+ self.iref_1 = MISSING_REF;
+ self.scal_ref = MISSING_REF;
+ }
+
+ pub fn is_intra(&self) -> bool {
self.ftype.is_intra()
}
- pub fn get_frame_type(&mut self) -> FrameType {
+ pub fn get_frame_type(&self) -> FrameType {
match self.ftype {
IVIFrameType::Intra => { FrameType::I },
IVIFrameType::Intra1 => { FrameType::I },
let mut valtab: [i8; 256] = [0; 256];
runtab.copy_from_slice(&self.runtab);
valtab.copy_from_slice(&self.valtab);
- RVMap { eob_sym: self.eob_sym, esc_sym: self.esc_sym, runtab: runtab, valtab: valtab }
+ RVMap { eob_sym: self.eob_sym, esc_sym: self.esc_sym, runtab, valtab }
}
}