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!(&header.signature, b"DKIF", "signature is 'DKIF'"); 39 assert_eq!(header.version, 0, "version should be 0"); 40 assert_eq!(&header.four_cc, b"VP80", "FourCC should be 'VP80'"); 41 assert_eq!(header.width, 176, "width should be 176"); 42 assert_eq!(header.height, 144, "height should be 144"); 43 assert_eq!( 44 header.timebase_denominator, 30000, 45 "timebase denominator should be 30000" 46 ); 47 assert_eq!( 48 header.timebase_numerator, 1000, 49 "timebase numerator should be 1000" 50 ); 51 assert_eq!(header.num_frames, 29, "number of frames should be 29"); 52 assert_eq!(header.unused, 0, "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!(header.frame_size, 4, "Frame header frameSize should be 4"); 83 assert_eq!(payload.len(), 4, "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 reader.bytes_read, 91 IVF_FILE_HEADER_SIZE + IVF_FRAME_HEADER_SIZE + header.frame_size as usize 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!(header.frame_size, 12, "Frame header frameSize should be 4"); 99 assert_eq!(payload.len(), 12, "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 reader.bytes_read, 109 previous_bytes_read + IVF_FRAME_HEADER_SIZE + header.frame_size as usize, 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 let result = reader.parse_next_frame(); 128 assert!(result.is_err(), "Expected Error but got Ok"); 129 130 Ok(()) 131 } 132 133 #[test] 134 fn test_ivf_reader_parse_incomplete_frame_payload() -> Result<()> { 135 // frame with header defining frameSize of 4 136 // but only 2 bytes available (missing 2 bytes) 137 let incomplete_frame = Bytes::from_static(&[ 138 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, 139 ]); 140 141 let ivf = build_ivf_container(&[incomplete_frame]); 142 let r = BufReader::new(&ivf[..]); 143 let (mut reader, _) = IVFReader::new(r)?; 144 145 // Parse Frame #1 146 let result = reader.parse_next_frame(); 147 assert!(result.is_err(), "Expected Error but got Ok"); 148 149 Ok(()) 150 } 151 152 #[test] 153 fn test_ivf_reader_eof_when_no_frames_left() -> Result<()> { 154 let ivf = build_ivf_container(&[]); 155 let r = BufReader::new(&ivf[..]); 156 let (mut reader, _) = IVFReader::new(r)?; 157 158 let result = reader.parse_next_frame(); 159 assert!(result.is_err(), "Expected Error but got Ok"); 160 161 Ok(()) 162 } 163