1 use super::*; 2 3 #[test] 4 fn test_h264_payload() -> Result<()> { 5 let empty = Bytes::from_static(&[]); 6 let small_payload = Bytes::from_static(&[0x90, 0x90, 0x90]); 7 let multiple_payload = Bytes::from_static(&[0x00, 0x00, 0x01, 0x90, 0x00, 0x00, 0x01, 0x90]); 8 let large_payload = Bytes::from_static(&[ 9 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 10 0x12, 0x13, 0x14, 0x15, 11 ]); 12 let large_payload_packetized = vec![ 13 Bytes::from_static(&[0x1c, 0x80, 0x01, 0x02, 0x03]), 14 Bytes::from_static(&[0x1c, 0x00, 0x04, 0x05, 0x06]), 15 Bytes::from_static(&[0x1c, 0x00, 0x07, 0x08, 0x09]), 16 Bytes::from_static(&[0x1c, 0x00, 0x10, 0x11, 0x12]), 17 Bytes::from_static(&[0x1c, 0x40, 0x13, 0x14, 0x15]), 18 ]; 19 20 let mut pck = H264Payloader::default(); 21 22 // Positive MTU, empty payload 23 let result = pck.payload(1, &empty)?; 24 assert!(result.is_empty(), "Generated payload should be empty"); 25 26 // 0 MTU, small payload 27 let result = pck.payload(0, &small_payload)?; 28 assert_eq!(result.len(), 0, "Generated payload should be empty"); 29 30 // Positive MTU, small payload 31 let result = pck.payload(1, &small_payload)?; 32 assert_eq!(result.len(), 0, "Generated payload should be empty"); 33 34 // Positive MTU, small payload 35 let result = pck.payload(5, &small_payload)?; 36 assert_eq!(result.len(), 1, "Generated payload should be the 1"); 37 assert_eq!( 38 result[0].len(), 39 small_payload.len(), 40 "Generated payload should be the same size as original payload size" 41 ); 42 43 // Multiple NALU in a single payload 44 let result = pck.payload(5, &multiple_payload)?; 45 assert_eq!(result.len(), 2, "2 nal units should be broken out"); 46 for i in 0..2 { 47 assert_eq!( 48 result[i].len(), 49 1, 50 "Payload {} of 2 is packed incorrectly", 51 i + 1, 52 ); 53 } 54 55 // Large Payload split across multiple RTP Packets 56 let result = pck.payload(5, &large_payload)?; 57 assert_eq!( 58 result, large_payload_packetized, 59 "FU-A packetization failed" 60 ); 61 62 // Nalu type 9 or 12 63 let small_payload2 = Bytes::from_static(&[0x09, 0x00, 0x00]); 64 let result = pck.payload(5, &small_payload2)?; 65 assert_eq!(result.len(), 0, "Generated payload should be empty"); 66 67 Ok(()) 68 } 69 70 #[test] 71 fn test_h264_packet_unmarshal() -> Result<()> { 72 let single_payload = Bytes::from_static(&[0x90, 0x90, 0x90]); 73 let single_payload_unmarshaled = 74 Bytes::from_static(&[0x00, 0x00, 0x00, 0x01, 0x90, 0x90, 0x90]); 75 let single_payload_unmarshaled_avc = 76 Bytes::from_static(&[0x00, 0x00, 0x00, 0x03, 0x90, 0x90, 0x90]); 77 78 let large_payload = Bytes::from_static(&[ 79 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 80 0x11, 0x12, 0x13, 0x14, 0x15, 81 ]); 82 let large_payload_avc = Bytes::from_static(&[ 83 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 84 0x11, 0x12, 0x13, 0x14, 0x15, 85 ]); 86 let large_payload_packetized = vec![ 87 Bytes::from_static(&[0x1c, 0x80, 0x01, 0x02, 0x03]), 88 Bytes::from_static(&[0x1c, 0x00, 0x04, 0x05, 0x06]), 89 Bytes::from_static(&[0x1c, 0x00, 0x07, 0x08, 0x09]), 90 Bytes::from_static(&[0x1c, 0x00, 0x10, 0x11, 0x12]), 91 Bytes::from_static(&[0x1c, 0x40, 0x13, 0x14, 0x15]), 92 ]; 93 94 let single_payload_multi_nalu = Bytes::from_static(&[ 95 0x78, 0x00, 0x0f, 0x67, 0x42, 0xc0, 0x1f, 0x1a, 0x32, 0x35, 0x01, 0x40, 0x7a, 0x40, 0x3c, 96 0x22, 0x11, 0xa8, 0x00, 0x05, 0x68, 0x1a, 0x34, 0xe3, 0xc8, 97 ]); 98 let single_payload_multi_nalu_unmarshaled = Bytes::from_static(&[ 99 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1f, 0x1a, 0x32, 0x35, 0x01, 0x40, 0x7a, 0x40, 100 0x3c, 0x22, 0x11, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x68, 0x1a, 0x34, 0xe3, 0xc8, 101 ]); 102 let single_payload_multi_nalu_unmarshaled_avc = Bytes::from_static(&[ 103 0x00, 0x00, 0x00, 0x0f, 0x67, 0x42, 0xc0, 0x1f, 0x1a, 0x32, 0x35, 0x01, 0x40, 0x7a, 0x40, 104 0x3c, 0x22, 0x11, 0xa8, 0x00, 0x00, 0x00, 0x05, 0x68, 0x1a, 0x34, 0xe3, 0xc8, 105 ]); 106 107 let incomplete_single_payload_multi_nalu = Bytes::from_static(&[ 108 0x78, 0x00, 0x0f, 0x67, 0x42, 0xc0, 0x1f, 0x1a, 0x32, 0x35, 0x01, 0x40, 0x7a, 0x40, 0x3c, 109 0x22, 0x11, 110 ]); 111 112 let mut pkt = H264Packet::default(); 113 let mut avc_pkt = H264Packet { 114 is_avc: true, 115 ..Default::default() 116 }; 117 118 let data = Bytes::from_static(&[]); 119 let result = pkt.depacketize(&data); 120 assert!(result.is_err(), "Unmarshal did not fail on nil payload"); 121 122 let data = Bytes::from_static(&[0x00, 0x00]); 123 let result = pkt.depacketize(&data); 124 assert!( 125 result.is_err(), 126 "Unmarshal accepted a packet that is too small for a payload and header" 127 ); 128 129 let data = Bytes::from_static(&[0xFF, 0x00, 0x00]); 130 let result = pkt.depacketize(&data); 131 assert!( 132 result.is_err(), 133 "Unmarshal accepted a packet with a NALU Type we don't handle" 134 ); 135 136 let result = pkt.depacketize(&incomplete_single_payload_multi_nalu); 137 assert!( 138 result.is_err(), 139 "Unmarshal accepted a STAP-A packet with insufficient data" 140 ); 141 142 let payload = pkt.depacketize(&single_payload)?; 143 assert_eq!( 144 payload, single_payload_unmarshaled, 145 "Unmarshaling a single payload shouldn't modify the payload" 146 ); 147 148 let payload = avc_pkt.depacketize(&single_payload)?; 149 assert_eq!( 150 payload, single_payload_unmarshaled_avc, 151 "Unmarshaling a single payload into avc stream shouldn't modify the payload" 152 ); 153 154 let mut large_payload_result = BytesMut::new(); 155 for p in &large_payload_packetized { 156 let payload = pkt.depacketize(p)?; 157 large_payload_result.put(&*payload.clone()); 158 } 159 assert_eq!( 160 large_payload_result.freeze(), 161 large_payload, 162 "Failed to unmarshal a large payload" 163 ); 164 165 let mut large_payload_result_avc = BytesMut::new(); 166 for p in &large_payload_packetized { 167 let payload = avc_pkt.depacketize(p)?; 168 large_payload_result_avc.put(&*payload.clone()); 169 } 170 assert_eq!( 171 large_payload_result_avc.freeze(), 172 large_payload_avc, 173 "Failed to unmarshal a large payload into avc stream" 174 ); 175 176 let payload = pkt.depacketize(&single_payload_multi_nalu)?; 177 assert_eq!( 178 payload, single_payload_multi_nalu_unmarshaled, 179 "Failed to unmarshal a single packet with multiple NALUs" 180 ); 181 182 let payload = avc_pkt.depacketize(&single_payload_multi_nalu)?; 183 assert_eq!( 184 payload, single_payload_multi_nalu_unmarshaled_avc, 185 "Failed to unmarshal a single packet with multiple NALUs into avc stream" 186 ); 187 188 Ok(()) 189 } 190 191 #[test] 192 fn test_h264_partition_head_checker_is_partition_head() -> Result<()> { 193 let h264 = H264Packet::default(); 194 let empty_nalu = Bytes::from_static(&[]); 195 assert!( 196 !h264.is_partition_head(&empty_nalu), 197 "empty nalu must not be a partition head" 198 ); 199 200 let single_nalu = Bytes::from_static(&[1, 0]); 201 assert!( 202 h264.is_partition_head(&single_nalu), 203 "single nalu must be a partition head" 204 ); 205 206 let stapa_nalu = Bytes::from_static(&[STAPA_NALU_TYPE, 0]); 207 assert!( 208 h264.is_partition_head(&stapa_nalu), 209 "stapa nalu must be a partition head" 210 ); 211 212 let fua_start_nalu = Bytes::from_static(&[FUA_NALU_TYPE, FU_START_BITMASK]); 213 assert!( 214 h264.is_partition_head(&fua_start_nalu), 215 "fua start nalu must be a partition head" 216 ); 217 218 let fua_end_nalu = Bytes::from_static(&[FUA_NALU_TYPE, FU_END_BITMASK]); 219 assert!( 220 !h264.is_partition_head(&fua_end_nalu), 221 "fua end nalu must not be a partition head" 222 ); 223 224 let fub_start_nalu = Bytes::from_static(&[FUB_NALU_TYPE, FU_START_BITMASK]); 225 assert!( 226 h264.is_partition_head(&fub_start_nalu), 227 "fub start nalu must be a partition head" 228 ); 229 230 let fub_end_nalu = Bytes::from_static(&[FUB_NALU_TYPE, FU_END_BITMASK]); 231 assert!( 232 !h264.is_partition_head(&fub_end_nalu), 233 "fub end nalu must not be a partition head" 234 ); 235 236 Ok(()) 237 } 238 239 #[test] 240 fn test_h264_payloader_payload_sps_and_pps_handling() -> Result<()> { 241 let mut pck = H264Payloader::default(); 242 let expected = vec![ 243 Bytes::from_static(&[ 244 0x78, 0x00, 0x03, 0x07, 0x00, 0x01, 0x00, 0x03, 0x08, 0x02, 0x03, 245 ]), 246 Bytes::from_static(&[0x05, 0x04, 0x05]), 247 ]; 248 249 // When packetizing SPS and PPS are emitted with following NALU 250 let res = pck.payload(1500, &Bytes::from_static(&[0x07, 0x00, 0x01]))?; 251 assert!(res.is_empty(), "Generated payload should be empty"); 252 253 let res = pck.payload(1500, &Bytes::from_static(&[0x08, 0x02, 0x03]))?; 254 assert!(res.is_empty(), "Generated payload should be empty"); 255 256 let actual = pck.payload(1500, &Bytes::from_static(&[0x05, 0x04, 0x05]))?; 257 assert_eq!(actual, expected, "SPS and PPS aren't packed together"); 258 259 Ok(()) 260 } 261