check for missing reference frames in various decoders
authorKostya Shishkov <kostya.shishkov@gmail.com>
Mon, 11 Nov 2019 17:42:58 +0000 (18:42 +0100)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Mon, 11 Nov 2019 17:42:58 +0000 (18:42 +0100)
nihav-commonfmt/src/codecs/clearvideo.rs
nihav-duck/src/codecs/vp3.rs
nihav-duck/src/codecs/vp56.rs
nihav-duck/src/codecs/vp7.rs
nihav-duck/src/codecs/vpcommon.rs
nihav-realmedia/src/codecs/rv3040.rs
nihav-realmedia/src/codecs/rv60.rs

index 790ea3e00b369d91a2e5b4fc3a1b6faccc983ba6..953e3c097004030ec5cfeab6943c6bdc48c6a029 100644 (file)
@@ -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);
index dd71c8b9cb1e1271672efbce65a0475da0087283..b56c62c59eed90510a5710462c5c03e30be16616 100644 (file)
@@ -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();
index 28b1f0695b82d78cde10a9d1b4475a2910ea268d..03bd9fc9b052ec4c9730ca185a3855251d74e93c 100644 (file)
@@ -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;
index b96da83bfe40832c16cfe5b074403c42085208e7..4fc7deaaa526a1414b4c531cdc92736f3dd2848b 100644 (file)
@@ -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)?;
index 562a9a2601dcbaf0c4d09983e4312b39390baf74..d1f6d446266041824673c6ff41de987c032d43a0 100644 (file)
@@ -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 ];
index 640de417ebeb572a8ad0a5b145feb96a54dadb4a..d19e3fe5c520805d8ae760e84da98ec7b78b7b4d 100644 (file)
@@ -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;
index bf89a5151361423cddb78f8b979c18417a7aec14..753b8050178d1d2ae8fbe844fda8f90967783363 100644 (file)
@@ -1431,6 +1431,22 @@ println!("???");
         let hdr = FrameHeader::read(&mut br)?;
         let mut slices: Vec<usize> = 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();