bref: Option<NABufferType>,
bands: Vec<BandHeader>,
+ 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 {
bref: None,
bands,
+ band_tiles: 0,
tiles: Vec::new(), tile_start: [[0; 4]; 4], num_tiles: [[0; 4]; 4],
+
+ scalable,
}
}
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 };
}
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 (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 = &ref_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 {
}
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 {
}
dstidx += stride * band.mb_size;
}
- br.align();
Ok(())
}
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);
+ }
}
}
}
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;