X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-realmedia%2Fsrc%2Fcodecs%2Frv3040.rs;h=e45b62b0682204306551761a04f147b1a3871264;hp=39549eb4b31358ebb9816b2485f137e5b7af4962;hb=404d527a49c44e461ab887280b576969a80d87c0;hpb=08a1fab72215ea7716f51adf7008f85372e80c71 diff --git a/nihav-realmedia/src/codecs/rv3040.rs b/nihav-realmedia/src/codecs/rv3040.rs index 39549eb..e45b62b 100644 --- a/nihav-realmedia/src/codecs/rv3040.rs +++ b/nihav-realmedia/src/codecs/rv3040.rs @@ -1,9 +1,10 @@ use nihav_core::formats::YUV420_FORMAT; use nihav_core::frame::{NABufferType, NAVideoInfo, NAVideoBuffer, NAVideoBufferRef, FrameType, alloc_video_buffer}; -use nihav_core::codecs::{NADecoderSupport, 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_core::data::GenericCache; +use nihav_codec_support::data::GenericCache; use std::mem; use super::rv34codes::*; @@ -514,7 +515,7 @@ fn parse_slice_offsets(src: &[u8], offsets: &mut Vec) -> DecoderResult<() 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)?; @@ -538,10 +539,23 @@ fn decode_slice_header(br: &mut BitReader, bd: &mut RV34BitstreamDecoder, slice_ 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); } @@ -1080,7 +1094,7 @@ impl RV34Decoder { 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 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;