1 use super::*; 2 use bytes::Bytes; 3 use std::io::BufReader; 4 5 /// build_ivf_container takes frames and prepends valid IVF file header 6 fn build_ivf_container(frames: &[Bytes]) -> Bytes { 7 // Valid IVF file header taken from: https://github.com/webmproject/... 8 // vp8-test-vectors/blob/master/vp80-00-comprehensive-001.ivf 9 // Video Image Width - 176 10 // Video Image Height - 144 11 // Frame Rate Rate - 30000 12 // Frame Rate Scale - 1000 13 // Video Length in Frames - 29 14 // BitRate: 64.01 kb/s 15 let header = Bytes::from_static(&[ 16 0x44, 0x4b, 0x49, 0x46, 0x00, 0x00, 0x20, 0x00, 0x56, 0x50, 0x38, 0x30, 0xb0, 0x00, 0x90, 17 0x00, 0x30, 0x75, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 18 0x00, 0x00, 19 ]); 20 21 let mut ivf = BytesMut::new(); 22 ivf.extend(header); 23 24 for frame in frames { 25 ivf.extend(frame); 26 } 27 28 ivf.freeze() 29 } 30 31 #[test] 32 fn test_ivf_reader_parse_valid_file_header() -> Result<()> { 33 let ivf = build_ivf_container(&[]); 34 35 let r = BufReader::new(&ivf[..]); 36 let (_, header) = IVFReader::new(r)?; 37 38 assert_eq!(b"DKIF", &header.signature, "signature is 'DKIF'"); 39 assert_eq!(0, header.version, "version should be 0"); 40 assert_eq!(b"VP80", &header.four_cc, "FourCC should be 'VP80'"); 41 assert_eq!(176, header.width, "width should be 176"); 42 assert_eq!(144, header.height, "height should be 144"); 43 assert_eq!( 44 30000, header.timebase_denominator, 45 "timebase denominator should be 30000" 46 ); 47 assert_eq!( 48 1000, header.timebase_numerator, 49 "timebase numerator should be 1000" 50 ); 51 assert_eq!(29, header.num_frames, "number of frames should be 29"); 52 assert_eq!(0, header.unused, "bytes should be unused"); 53 54 Ok(()) 55 } 56 57 #[test] 58 fn test_ivf_reader_parse_valid_frames() -> Result<()> { 59 // Frame Length - 4 60 // Timestamp - None 61 // Frame Payload - 0xDEADBEEF 62 let valid_frame1 = Bytes::from_static(&[ 63 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, 0xBE, 64 0xEF, 65 ]); 66 67 // Frame Length - 12 68 // Timestamp - None 69 // Frame Payload - 0xDEADBEEFDEADBEEF 70 let valid_frame2 = Bytes::from_static(&[ 71 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, 0xBE, 72 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 73 ]); 74 75 let ivf = build_ivf_container(&[valid_frame1, valid_frame2]); 76 let r = BufReader::new(&ivf[..]); 77 let (mut reader, _) = IVFReader::new(r)?; 78 79 // Parse Frame #1 80 let (payload, header) = reader.parse_next_frame()?; 81 82 assert_eq!(4, header.frame_size, "Frame header frameSize should be 4"); 83 assert_eq!(4, payload.len(), "Payload should be length 4"); 84 assert_eq!( 85 payload, 86 Bytes::from_static(&[0xDE, 0xAD, 0xBE, 0xEF,]), 87 "Payload value should be 0xDEADBEEF" 88 ); 89 assert_eq!( 90 IVF_FILE_HEADER_SIZE + IVF_FRAME_HEADER_SIZE + header.frame_size as usize, 91 reader.bytes_read 92 ); 93 let previous_bytes_read = reader.bytes_read; 94 95 // Parse Frame #2 96 let (payload, header) = reader.parse_next_frame()?; 97 98 assert_eq!(12, header.frame_size, "Frame header frameSize should be 4"); 99 assert_eq!(12, payload.len(), "Payload should be length 12"); 100 assert_eq!( 101 payload, 102 Bytes::from_static(&[ 103 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 0xDE, 0xAD, 0xBE, 0xEF, 104 ]), 105 "Payload value should be 0xDEADBEEFDEADBEEF" 106 ); 107 assert_eq!( 108 previous_bytes_read + IVF_FRAME_HEADER_SIZE + header.frame_size as usize, 109 reader.bytes_read, 110 ); 111 112 Ok(()) 113 } 114 115 #[test] 116 fn test_ivf_reader_parse_incomplete_frame_header() -> Result<()> { 117 // frame with 11-byte header (missing 1 byte) 118 let incomplete_frame = Bytes::from_static(&[ 119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 120 ]); 121 122 let ivf = build_ivf_container(&[incomplete_frame]); 123 let r = BufReader::new(&ivf[..]); 124 let (mut reader, _) = IVFReader::new(r)?; 125 126 // Parse Frame #1 127 if let Err(err) = reader.parse_next_frame() { 128 assert!(true, "{}", err); 129 } else { 130 assert!(false); 131 } 132 133 Ok(()) 134 } 135 136 #[test] 137 fn test_ivf_reader_parse_incomplete_frame_payload() -> Result<()> { 138 // frame with header defining frameSize of 4 139 // but only 2 bytes available (missing 2 bytes) 140 let incomplete_frame = Bytes::from_static(&[ 141 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, 142 ]); 143 144 let ivf = build_ivf_container(&[incomplete_frame]); 145 let r = BufReader::new(&ivf[..]); 146 let (mut reader, _) = IVFReader::new(r)?; 147 148 // Parse Frame #1 149 if let Err(err) = reader.parse_next_frame() { 150 assert!(true, "{}", err); 151 } else { 152 assert!(false); 153 } 154 155 Ok(()) 156 } 157 158 #[test] 159 fn test_ivf_reader_eof_when_no_frames_left() -> Result<()> { 160 let ivf = build_ivf_container(&[]); 161 let r = BufReader::new(&ivf[..]); 162 let (mut reader, _) = IVFReader::new(r)?; 163 164 if let Err(err) = reader.parse_next_frame() { 165 assert!(true, "{}", err); 166 } else { 167 assert!(false); 168 } 169 170 Ok(()) 171 } 172