X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-indeo%2Fsrc%2Fcodecs%2Fivibr.rs;h=d544085f350fa54d68cb950a1ba9b438a700a225;hb=71d7f39706f0f5004820f8d1d36c87d5f9ec3e97;hp=dd43afa1b389a23ae5fa2227d72c088a543ff681;hpb=08a1fab72215ea7716f51adf7008f85372e80c71;p=nihav.git diff --git a/nihav-indeo/src/codecs/ivibr.rs b/nihav-indeo/src/codecs/ivibr.rs index dd43afa..d544085 100644 --- a/nihav-indeo/src/codecs/ivibr.rs +++ b/nihav-indeo/src/codecs/ivibr.rs @@ -171,6 +171,7 @@ fn read_trans_band_header(br: &mut BitReader, w: usize, h: usize, dst: &mut [i16 for i in 0..cb.len { cb.bits[i] = br.read(4)? as u8; } + cb = cb.init(); br.align(); let tile_start = br.tell(); @@ -227,7 +228,8 @@ let tile_end = tile_start + len * 8; 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 { @@ -256,7 +258,7 @@ fn decode_block8x8(br: &mut BitReader, blk_cb: &IVICodebook, rvmap: &RVMap, tabl } } idx += run; - validate!((idx >= 0) && (idx < 64)); + validate!((0..64).contains(&idx)); let spos = tables.scan[idx as usize]; let q = (u32::from(quant_mat[spos]) * u32::from(quant)) >> 9; @@ -277,7 +279,8 @@ fn decode_block8x8(br: &mut BitReader, blk_cb: &IVICodebook, rvmap: &RVMap, tabl (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 { @@ -305,7 +308,7 @@ fn decode_block4x4(br: &mut BitReader, blk_cb: &IVICodebook, rvmap: &RVMap, tabl } } idx += run; - validate!((idx >= 0) && (idx < 16)); + validate!((0..16).contains(&idx)); let spos = tables.scan[idx as usize]; let q = (u32::from(quant_mat[spos]) * u32::from(quant)) >> 9; @@ -481,13 +484,16 @@ pub struct IVIDecoder { bref: Option, bands: Vec, - tiles: Vec>, + band_tiles: usize, + tiles: Vec, 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 = Vec::with_capacity(12); bands.resize(12, BandHeader::new_empty(42, 42)); IVIDecoder { @@ -500,15 +506,18 @@ impl IVIDecoder { bref: None, 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; @@ -527,6 +536,9 @@ impl IVIDecoder { 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 }; @@ -538,7 +550,7 @@ impl IVIDecoder { 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(NABufferRef::new(tile)); + self.tiles.push(tile); self.num_tiles[plane][band] += 1; tstart += 1; x += tile_w; @@ -549,7 +561,7 @@ impl IVIDecoder { } 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 }, @@ -574,12 +586,12 @@ impl IVIDecoder { }; for tile_no in tstart..tend { { - let mut tile = self.tiles[tile_no].clone(); + 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)); } @@ -593,11 +605,10 @@ impl IVIDecoder { } 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].clone(); let ref_tile: Option<&IVITile>; let mv_scale; if (plane_no == 0) && (band_no == 0) { @@ -605,8 +616,10 @@ impl IVIDecoder { } 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]; + 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 { @@ -615,15 +628,15 @@ impl IVIDecoder { } 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].clone(); let ref_tile: Option<&IVITile>; let mv_scale; if (plane_no == 0) && (band_no == 0) { @@ -631,8 +644,10 @@ br.skip(skip_part as u32)?; } 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]; + let rtile = &ref_tiles[0]; if (tile.mb_w != rtile.mb_w) || (tile.mb_h != rtile.mb_h) { ref_tile = None; } else { @@ -648,7 +663,7 @@ br.skip(skip_part as u32)?; 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); @@ -660,22 +675,22 @@ br.skip(skip_part as u32)?; } } } - 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].clone(); + 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; @@ -723,23 +738,23 @@ br.skip(skip_part as u32)?; 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(&mut dst, dstidx + boff, stride, &blk, 4); + put_block(dst, dstidx + boff, stride, &blk, 4); } else { - add_block(&mut dst, dstidx + boff, stride, &blk, 4); + 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, band.blk_size); + put_block(dst, dstidx + boff, stride, &blk, band.blk_size); } } cbp >>= 1; @@ -783,24 +798,24 @@ br.skip(skip_part as u32)?; } 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); } } } @@ -809,7 +824,6 @@ br.skip(skip_part as u32)?; } dstidx += stride * band.mb_size; } - br.align(); Ok(()) } @@ -822,7 +836,7 @@ br.skip(skip_part as u32)?; unreachable!(); } - fn decode_single_frame<'a>(&mut self, dec: &mut IndeoXParser, br: &mut BitReader<'a>) -> DecoderResult { + fn decode_single_frame<'a>(&mut self, dec: &mut dyn IndeoXParser, br: &mut BitReader<'a>) -> DecoderResult { let pic_hdr = dec.decode_picture_header(br)?; self.ftype = pic_hdr.ftype; if pic_hdr.ftype.is_null() { @@ -866,22 +880,77 @@ br.skip(skip_part as u32)?; self.realloc(&pic_hdr)?; self.frames[self.cur_frame].realloc(&pic_hdr)?; - 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 !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 { + 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].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); + 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); + } } } } @@ -895,7 +964,7 @@ br.skip(skip_part as u32)?; } 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; @@ -909,7 +978,7 @@ br.skip(skip_part as u32)?; Ok(buftype) } - pub fn decode_frame<'a>(&mut self, dec: &mut IndeoXParser, br: &mut BitReader<'a>) -> DecoderResult { + pub fn decode_frame<'a>(&mut self, dec: &mut dyn IndeoXParser, br: &mut BitReader<'a>) -> DecoderResult { let res = self.decode_single_frame(dec, br); if res.is_err() { return res; } if (self.ftype == IVIFrameType::Intra) && (br.left() > 16) { @@ -926,13 +995,18 @@ br.skip(skip_part as u32)?; 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 = 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 = None;