indeo5: implement scalable streams support
authorKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 13 Oct 2022 16:21:33 +0000 (18:21 +0200)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Thu, 13 Oct 2022 16:22:10 +0000 (18:22 +0200)
nihav-indeo/src/codecs/indeo5.rs
nihav-indeo/src/codecs/ivibr.rs

index 2d1e9bd0dcc6baf359d7ed218e57a6e76484025f..9a2fc8539c7e61b374652d520532a14d89a4ec1e 100644 (file)
@@ -850,4 +850,46 @@ mod test {
                             [0xc7f49f94, 0xca32d87c, 0x2e063788, 0x0229c6c0],
                             [0xa9ec4820, 0x576c7877, 0xc21211c3, 0x502af3d3]]));
     }
+    #[test]
+    fn test_indeo5_scalable() {
+        let mut dmx_reg = RegisteredDemuxers::new();
+        crate::indeo_register_all_demuxers(&mut dmx_reg);
+        let mut dec_reg = RegisteredDecoders::new();
+        indeo_register_all_decoders(&mut dec_reg);
+
+        test_decoding("ivf", "indeo5s", "assets/Indeo/TRAILERIIE.IVF", Some(31),
+                      &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
+                            [0xd6c5b653, 0x082e25e6, 0x90c0c112, 0xfa7f46c8],
+                            [0x75e96cdb, 0x198cdb95, 0xde228898, 0x3cf68cfc],
+                            [0xb1bed823, 0xad632d3e, 0x2e509143, 0x5e59e911],
+                            [0xe3e7e2f0, 0xb8c7d968, 0xcb0b9273, 0xb7e48207],
+                            [0xc6ef6975, 0xe0cc0b05, 0x983f7888, 0x64c9b89f],
+                            [0xda936fad, 0xa170c0f2, 0x889a3e0c, 0xfef1a626],
+                            [0xa85ccb32, 0x2c6847c4, 0x3259f48d, 0xe7e1b47b],
+                            [0xedbb8256, 0x1e889428, 0xbc268e66, 0xf41d15f1],
+                            [0xd6869899, 0x5121410d, 0xb12dfc96, 0x7dc67a24],
+                            [0x9a594172, 0x3d9269c7, 0x1a7277fd, 0xe597dd01],
+                            [0x3af07da6, 0x1968872d, 0xf7fc190e, 0x5c61c184],
+                            [0xd8eec91e, 0x1aa55dfe, 0x9703a2ce, 0x1ce30990],
+                            [0xea4821ae, 0x44ab9f2f, 0xa882bccb, 0xcae50f58],
+                            [0x6ddfb989, 0x1affb8ad, 0x7bb2d74a, 0xc28e1a1d],
+                            [0x4c9aa98d, 0xb6b2ddd2, 0xfb533baf, 0xc2d90242],
+                            [0x332c8e68, 0x47a942ea, 0x6ced7891, 0x7667ad97],
+                            [0x940ad339, 0x448ea27c, 0x3b7d0328, 0x4a4cf19f],
+                            [0x08a60746, 0x399949ef, 0xce81ef06, 0xbc1d7d6b],
+                            [0x4b5e51d0, 0xe26d32f1, 0xb1872663, 0xa70c6e65],
+                            [0x428fb122, 0xf3a55f40, 0xdc4316d7, 0xe2765f76],
+                            [0xcce4fa35, 0xb47d9848, 0xcbe7fef4, 0x5285022b],
+                            [0xde30af92, 0x28a04fe2, 0x317f6be8, 0xde5c161c],
+                            [0xe1f00bf7, 0xab2d4e91, 0x9eb674e6, 0x3b863314],
+                            [0xac944130, 0xa5d1171a, 0xe8a0b591, 0x09d7652d],
+                            [0x17c17612, 0x7cd40f67, 0x7aec3009, 0x2405b862],
+                            [0x1d88eb87, 0x44496fb8, 0x58665011, 0xc545f745],
+                            [0x04c32cce, 0x38eca98f, 0xd6227880, 0xc7d0f2bf],
+                            [0x76d9dcb8, 0x92a35e1a, 0x2b968e96, 0x2c362e4a],
+                            [0xda4904e7, 0x2d9d0a74, 0x63932049, 0x7bf9f0de],
+                            [0x4f18931c, 0x61b9046f, 0xf5eac763, 0x0c1826d5],
+                            [0x823d8746, 0x17debe43, 0xe256fda4, 0xdd1a6832],
+                            [0x0bb4b91d, 0xf66f1c19, 0x166ee91a, 0x69379e27]]));
+    }
 }
index 5831f801693d23181716b4ecc4e00c7f305432e5..d544085f350fa54d68cb950a1ba9b438a700a225 100644 (file)
@@ -880,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);
+                    }
                 }
             }
         }