From 6e24ec0bcf9d521c66551eebd198400c5342b0be Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Mon, 11 Nov 2019 18:42:58 +0100 Subject: [PATCH] check for missing reference frames in various decoders --- nihav-commonfmt/src/codecs/clearvideo.rs | 4 +++- nihav-duck/src/codecs/vp3.rs | 4 ++++ nihav-duck/src/codecs/vp56.rs | 4 ++++ nihav-duck/src/codecs/vp7.rs | 4 ++++ nihav-duck/src/codecs/vpcommon.rs | 3 +++ nihav-realmedia/src/codecs/rv3040.rs | 16 ++++++++++++++++ nihav-realmedia/src/codecs/rv60.rs | 16 ++++++++++++++++ 7 files changed, 50 insertions(+), 1 deletion(-) diff --git a/nihav-commonfmt/src/codecs/clearvideo.rs b/nihav-commonfmt/src/codecs/clearvideo.rs index 790ea3e..953e3c0 100644 --- a/nihav-commonfmt/src/codecs/clearvideo.rs +++ b/nihav-commonfmt/src/codecs/clearvideo.rs @@ -683,7 +683,9 @@ impl NADecoder for ClearVideoDecoder { self.decode_frame_intra(&mut br, &mut buf, vinfo.get_width(), vinfo.get_height())?; extend_edges(&mut buf, 1 << self.tsize); } else { - let mut prev = self.frmmgr.clone_ref().unwrap(); + let pref = self.frmmgr.clone_ref(); + if pref.is_none() { return Err(DecoderError::MissingReference); } + let mut prev = pref.unwrap(); extend_edges(&mut prev, 1 << self.tsize); self.decode_frame_inter(&mut br, &mut buf, &mut prev, vinfo.get_width(), vinfo.get_height())?; extend_edges(&mut buf, 1 << self.tsize); diff --git a/nihav-duck/src/codecs/vp3.rs b/nihav-duck/src/codecs/vp3.rs index dd71c8b..b56c62c 100644 --- a/nihav-duck/src/codecs/vp3.rs +++ b/nihav-duck/src/codecs/vp3.rs @@ -1814,6 +1814,10 @@ impl NADecoder for VP34Decoder { self.parse_header(&mut br)?; if self.is_intra { self.shuf.clear(); + } else { + if !self.shuf.has_refs() { + return Err(DecoderError::MissingReference); + } } let ret = supp.pool_u8.get_free(); diff --git a/nihav-duck/src/codecs/vp56.rs b/nihav-duck/src/codecs/vp56.rs index 28b1f06..03bd9fc 100644 --- a/nihav-duck/src/codecs/vp56.rs +++ b/nihav-duck/src/codecs/vp56.rs @@ -470,6 +470,10 @@ impl VP56Decoder { if hdr.is_intra { self.shuf.clear(); + } else { + if !self.shuf.has_refs() { + return Err(DecoderError::MissingReference); + } } let mut cr; diff --git a/nihav-duck/src/codecs/vp7.rs b/nihav-duck/src/codecs/vp7.rs index b96da83..4fc7dea 100644 --- a/nihav-duck/src/codecs/vp7.rs +++ b/nihav-duck/src/codecs/vp7.rs @@ -1141,6 +1141,10 @@ impl NADecoder for VP7Decoder { self.set_dimensions(width, height); self.dstate.reset(); + } else { + if !self.shuf.has_refs() { + return Err(DecoderError::MissingReference); + } } self.read_features(&mut bc)?; diff --git a/nihav-duck/src/codecs/vpcommon.rs b/nihav-duck/src/codecs/vpcommon.rs index 562a9a2..d1f6d44 100644 --- a/nihav-duck/src/codecs/vpcommon.rs +++ b/nihav-duck/src/codecs/vpcommon.rs @@ -68,6 +68,9 @@ impl VPShuffler { None } } + pub fn has_refs(&self) -> bool { + self.lastframe.is_some() + } } pub const VP56_COEF_BASE: [i16; 6] = [ 5, 7, 11, 19, 35, 67 ]; diff --git a/nihav-realmedia/src/codecs/rv3040.rs b/nihav-realmedia/src/codecs/rv3040.rs index 640de41..d19e3fe 100644 --- a/nihav-realmedia/src/codecs/rv3040.rs +++ b/nihav-realmedia/src/codecs/rv3040.rs @@ -1106,6 +1106,22 @@ impl RV34Decoder { self.base_ts += 1 << 13; } } + match hdr0.ftype { + FrameType::P => { + if self.ipbs.get_lastref().is_none() { + return Err(DecoderError::MissingReference); + } + }, + FrameType::B => { + if self.ipbs.get_lastref().is_none() { + return Err(DecoderError::MissingReference); + } + if self.ipbs.get_nextref().is_none() { + return Err(DecoderError::MissingReference); + } + }, + _ => {}, + }; let ts_diff = (self.next_ts << 3).wrapping_sub(hdr0.pts << 3) >> 3; let ts = self.base_ts + (self.next_ts as u64) - (ts_diff as u64); sstate.trd = (self.next_ts << 3).wrapping_sub(self.last_ts << 3) >> 3; diff --git a/nihav-realmedia/src/codecs/rv60.rs b/nihav-realmedia/src/codecs/rv60.rs index bf89a51..753b805 100644 --- a/nihav-realmedia/src/codecs/rv60.rs +++ b/nihav-realmedia/src/codecs/rv60.rs @@ -1431,6 +1431,22 @@ println!("???"); let hdr = FrameHeader::read(&mut br)?; let mut slices: Vec = Vec::new(); hdr.parse_slice_sizes(&mut br, &mut slices)?; + match hdr.ftype { + FrameType::P => { + if self.ipbs.get_lastref().is_none() { + return Err(DecoderError::MissingReference); + } + }, + FrameType::B => { + if self.ipbs.get_lastref().is_none() { + return Err(DecoderError::MissingReference); + } + if self.ipbs.get_nextref().is_none() { + return Err(DecoderError::MissingReference); + } + }, + _ => {}, + }; let tmp_vinfo = NAVideoInfo::new(hdr.width, hdr.height, false, YUV420_FORMAT); let ret = supp.pool_u8.get_free(); -- 2.39.5