1 use super::*; 2 use crate::error::Result; 3 use rtcp::packet::Packet; 4 use util::Marshal; 5 6 #[test] 7 fn test_chunk_add() -> Result<()> { 8 //"fill with not received" 9 { 10 let mut c = Chunk::default(); 11 12 for i in 0..MAX_RUN_LENGTH_CAP { 13 assert!(c.can_add(SymbolTypeTcc::PacketNotReceived as u16), "{}", i); 14 c.add(SymbolTypeTcc::PacketNotReceived as u16); 15 } 16 assert_eq!(c.deltas, vec![0u16; MAX_RUN_LENGTH_CAP]); 17 assert!(!c.has_different_types); 18 19 assert!(!c.can_add(SymbolTypeTcc::PacketNotReceived as u16)); 20 assert!(!c.can_add(SymbolTypeTcc::PacketReceivedSmallDelta as u16)); 21 assert!(!c.can_add(SymbolTypeTcc::PacketReceivedLargeDelta as u16)); 22 23 let status_chunk = c.encode(); 24 match status_chunk { 25 PacketStatusChunk::RunLengthChunk(_) => {} 26 _ => panic!(), 27 }; 28 29 let buf = status_chunk.marshal()?; 30 assert_eq!(&buf[..], &[0x1f, 0xff]); 31 } 32 33 //"fill with small delta" 34 { 35 let mut c = Chunk::default(); 36 37 for i in 0..MAX_ONE_BIT_CAP { 38 assert!( 39 c.can_add(SymbolTypeTcc::PacketReceivedSmallDelta as u16), 40 "{}", 41 i 42 ); 43 c.add(SymbolTypeTcc::PacketReceivedSmallDelta as u16); 44 } 45 46 assert_eq!(c.deltas, vec![1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]); 47 assert!(!c.has_different_types); 48 49 assert!(!c.can_add(SymbolTypeTcc::PacketReceivedLargeDelta as u16)); 50 assert!(!c.can_add(SymbolTypeTcc::PacketNotReceived as u16)); 51 52 let status_chunk = c.encode(); 53 match status_chunk { 54 PacketStatusChunk::RunLengthChunk(_) => {} 55 _ => panic!(), 56 }; 57 58 let buf = status_chunk.marshal()?; 59 assert_eq!(&buf[..], &[0x20, 0xe]); 60 } 61 62 //"fill with large delta" 63 { 64 let mut c = Chunk::default(); 65 66 for i in 0..MAX_TWO_BIT_CAP { 67 assert!( 68 c.can_add(SymbolTypeTcc::PacketReceivedLargeDelta as u16), 69 "{}", 70 i 71 ); 72 c.add(SymbolTypeTcc::PacketReceivedLargeDelta as u16); 73 } 74 75 assert_eq!(c.deltas, vec![2, 2, 2, 2, 2, 2, 2]); 76 assert!(c.has_large_delta); 77 assert!(!c.has_different_types); 78 79 assert!(!c.can_add(SymbolTypeTcc::PacketReceivedSmallDelta as u16)); 80 assert!(!c.can_add(SymbolTypeTcc::PacketNotReceived as u16)); 81 82 let status_chunk = c.encode(); 83 match status_chunk { 84 PacketStatusChunk::RunLengthChunk(_) => {} 85 _ => panic!(), 86 }; 87 88 let buf = status_chunk.marshal()?; 89 assert_eq!(&buf[..], &[0x40, 0x7]); 90 } 91 92 // "fill with different types" 93 { 94 let mut c = Chunk::default(); 95 96 assert!(c.can_add(SymbolTypeTcc::PacketReceivedSmallDelta as u16)); 97 c.add(SymbolTypeTcc::PacketReceivedSmallDelta as u16); 98 assert!(c.can_add(SymbolTypeTcc::PacketReceivedSmallDelta as u16)); 99 c.add(SymbolTypeTcc::PacketReceivedSmallDelta as u16); 100 assert!(c.can_add(SymbolTypeTcc::PacketReceivedSmallDelta as u16)); 101 c.add(SymbolTypeTcc::PacketReceivedSmallDelta as u16); 102 assert!(c.can_add(SymbolTypeTcc::PacketReceivedSmallDelta as u16)); 103 c.add(SymbolTypeTcc::PacketReceivedSmallDelta as u16); 104 105 assert!(c.can_add(SymbolTypeTcc::PacketReceivedLargeDelta as u16)); 106 c.add(SymbolTypeTcc::PacketReceivedLargeDelta as u16); 107 assert!(c.can_add(SymbolTypeTcc::PacketReceivedLargeDelta as u16)); 108 c.add(SymbolTypeTcc::PacketReceivedLargeDelta as u16); 109 assert!(c.can_add(SymbolTypeTcc::PacketReceivedLargeDelta as u16)); 110 c.add(SymbolTypeTcc::PacketReceivedLargeDelta as u16); 111 112 assert!(!c.can_add(SymbolTypeTcc::PacketReceivedLargeDelta as u16)); 113 114 let status_chunk = c.encode(); 115 match status_chunk { 116 PacketStatusChunk::StatusVectorChunk(_) => {} 117 _ => panic!(), 118 }; 119 120 let buf = status_chunk.marshal()?; 121 assert_eq!(&buf[..], &[0xd5, 0x6a]); 122 } 123 124 //"overfill and encode" 125 { 126 let mut c = Chunk::default(); 127 128 assert!(c.can_add(SymbolTypeTcc::PacketReceivedSmallDelta as u16)); 129 c.add(SymbolTypeTcc::PacketReceivedSmallDelta as u16); 130 assert!(c.can_add(SymbolTypeTcc::PacketNotReceived as u16)); 131 c.add(SymbolTypeTcc::PacketNotReceived as u16); 132 assert!(c.can_add(SymbolTypeTcc::PacketNotReceived as u16)); 133 c.add(SymbolTypeTcc::PacketNotReceived as u16); 134 assert!(c.can_add(SymbolTypeTcc::PacketNotReceived as u16)); 135 c.add(SymbolTypeTcc::PacketNotReceived as u16); 136 assert!(c.can_add(SymbolTypeTcc::PacketNotReceived as u16)); 137 c.add(SymbolTypeTcc::PacketNotReceived as u16); 138 assert!(c.can_add(SymbolTypeTcc::PacketNotReceived as u16)); 139 c.add(SymbolTypeTcc::PacketNotReceived as u16); 140 assert!(c.can_add(SymbolTypeTcc::PacketNotReceived as u16)); 141 c.add(SymbolTypeTcc::PacketNotReceived as u16); 142 assert!(c.can_add(SymbolTypeTcc::PacketNotReceived as u16)); 143 c.add(SymbolTypeTcc::PacketNotReceived as u16); 144 145 assert!(!c.can_add(SymbolTypeTcc::PacketReceivedLargeDelta as u16)); 146 147 let status_chunk1 = c.encode(); 148 match status_chunk1 { 149 PacketStatusChunk::StatusVectorChunk(_) => {} 150 _ => panic!(), 151 }; 152 assert_eq!(c.deltas.len(), 1); 153 154 assert!(c.can_add(SymbolTypeTcc::PacketReceivedLargeDelta as u16)); 155 c.add(SymbolTypeTcc::PacketReceivedLargeDelta as u16); 156 157 let status_chunk2 = c.encode(); 158 match status_chunk2 { 159 PacketStatusChunk::StatusVectorChunk(_) => {} 160 _ => panic!(), 161 }; 162 assert_eq!(c.deltas.len(), 0); 163 164 assert_eq!( 165 PacketStatusChunk::StatusVectorChunk(StatusVectorChunk { 166 type_tcc: StatusChunkTypeTcc::StatusVectorChunk, 167 symbol_size: SymbolSizeTypeTcc::TwoBit, 168 symbol_list: vec![ 169 SymbolTypeTcc::PacketNotReceived, 170 SymbolTypeTcc::PacketReceivedLargeDelta 171 ], 172 }), 173 status_chunk2 174 ); 175 } 176 177 Ok(()) 178 } 179 180 #[test] 181 fn test_feedback() -> Result<()> { 182 //"add simple" 183 { 184 let mut f = Feedback::default(); 185 let got = f.add_received(0, 10); 186 assert!(got); 187 } 188 189 //"add too large" 190 { 191 let mut f = Feedback::default(); 192 193 assert!(!f.add_received(12, 8200 * 1000 * 250)); 194 } 195 196 // "add received 1" 197 { 198 let mut f = Feedback::default(); 199 f.set_base(1, 1000 * 1000); 200 201 let got = f.add_received(1, 1023 * 1000); 202 203 assert!(got); 204 assert_eq!(f.next_sequence_number, 2); 205 assert_eq!(f.ref_timestamp64ms, 15); 206 207 let got = f.add_received(4, 1086 * 1000); 208 assert!(got); 209 assert_eq!(f.next_sequence_number, 5); 210 assert_eq!(f.ref_timestamp64ms, 15); 211 212 assert!(f.last_chunk.has_different_types); 213 assert_eq!(f.last_chunk.deltas.len(), 4); 214 assert!(!f 215 .last_chunk 216 .deltas 217 .contains(&(SymbolTypeTcc::PacketReceivedLargeDelta as u16))); 218 } 219 220 //"add received 2" 221 { 222 let mut f = Feedback::new(0, 0, 0); 223 f.set_base(5, 320 * 1000); 224 225 let mut got = f.add_received(5, 320 * 1000); 226 assert!(got); 227 got = f.add_received(7, 448 * 1000); 228 assert!(got); 229 got = f.add_received(8, 512 * 1000); 230 assert!(got); 231 got = f.add_received(11, 768 * 1000); 232 assert!(got); 233 234 let pkt = f.get_rtcp(); 235 236 assert!(pkt.header().padding); 237 assert_eq!(pkt.header().length, 7); 238 assert_eq!(pkt.base_sequence_number, 5); 239 assert_eq!(pkt.packet_status_count, 7); 240 assert_eq!(pkt.reference_time, 5); 241 assert_eq!(pkt.fb_pkt_count, 0); 242 assert_eq!(pkt.packet_chunks.len(), 1); 243 244 assert_eq!( 245 vec![PacketStatusChunk::StatusVectorChunk(StatusVectorChunk { 246 type_tcc: StatusChunkTypeTcc::StatusVectorChunk, 247 symbol_size: SymbolSizeTypeTcc::TwoBit, 248 symbol_list: vec![ 249 SymbolTypeTcc::PacketReceivedSmallDelta, 250 SymbolTypeTcc::PacketNotReceived, 251 SymbolTypeTcc::PacketReceivedLargeDelta, 252 SymbolTypeTcc::PacketReceivedLargeDelta, 253 SymbolTypeTcc::PacketNotReceived, 254 SymbolTypeTcc::PacketNotReceived, 255 SymbolTypeTcc::PacketReceivedLargeDelta, 256 ], 257 })], 258 pkt.packet_chunks 259 ); 260 261 let expected_deltas = vec![ 262 RecvDelta { 263 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 264 delta: 0, 265 }, 266 RecvDelta { 267 type_tcc_packet: SymbolTypeTcc::PacketReceivedLargeDelta, 268 delta: 0x0200 * TYPE_TCC_DELTA_SCALE_FACTOR, 269 }, 270 RecvDelta { 271 type_tcc_packet: SymbolTypeTcc::PacketReceivedLargeDelta, 272 delta: 0x0100 * TYPE_TCC_DELTA_SCALE_FACTOR, 273 }, 274 RecvDelta { 275 type_tcc_packet: SymbolTypeTcc::PacketReceivedLargeDelta, 276 delta: 0x0400 * TYPE_TCC_DELTA_SCALE_FACTOR, 277 }, 278 ]; 279 assert_eq!(pkt.recv_deltas.len(), expected_deltas.len()); 280 for (i, expected) in expected_deltas.iter().enumerate() { 281 assert_eq!(&pkt.recv_deltas[i], expected); 282 } 283 } 284 285 //"add received wrapped sequence number" 286 { 287 let mut f = Feedback::new(0, 0, 0); 288 f.set_base(65535, 320 * 1000); 289 290 let mut got = f.add_received(65535, 320 * 1000); 291 assert!(got); 292 got = f.add_received(7, 448 * 1000); 293 assert!(got); 294 got = f.add_received(8, 512 * 1000); 295 assert!(got); 296 got = f.add_received(11, 768 * 1000); 297 assert!(got); 298 299 let pkt = f.get_rtcp(); 300 301 assert!(pkt.header().padding); 302 assert_eq!(pkt.header().length, 7); 303 assert_eq!(pkt.base_sequence_number, 65535); 304 assert_eq!(pkt.packet_status_count, 13); 305 assert_eq!(pkt.reference_time, 5); 306 assert_eq!(pkt.fb_pkt_count, 0); 307 assert_eq!(pkt.packet_chunks.len(), 2); 308 309 assert_eq!( 310 vec![ 311 PacketStatusChunk::StatusVectorChunk(StatusVectorChunk { 312 type_tcc: StatusChunkTypeTcc::StatusVectorChunk, 313 symbol_size: SymbolSizeTypeTcc::TwoBit, 314 symbol_list: vec![ 315 SymbolTypeTcc::PacketReceivedSmallDelta, 316 SymbolTypeTcc::PacketNotReceived, 317 SymbolTypeTcc::PacketNotReceived, 318 SymbolTypeTcc::PacketNotReceived, 319 SymbolTypeTcc::PacketNotReceived, 320 SymbolTypeTcc::PacketNotReceived, 321 SymbolTypeTcc::PacketNotReceived, 322 ], 323 }), 324 PacketStatusChunk::StatusVectorChunk(StatusVectorChunk { 325 type_tcc: StatusChunkTypeTcc::StatusVectorChunk, 326 symbol_size: SymbolSizeTypeTcc::TwoBit, 327 symbol_list: vec![ 328 SymbolTypeTcc::PacketNotReceived, 329 SymbolTypeTcc::PacketReceivedLargeDelta, 330 SymbolTypeTcc::PacketReceivedLargeDelta, 331 SymbolTypeTcc::PacketNotReceived, 332 SymbolTypeTcc::PacketNotReceived, 333 SymbolTypeTcc::PacketReceivedLargeDelta, 334 ], 335 }), 336 ], 337 pkt.packet_chunks 338 ); 339 340 let expected_deltas = vec![ 341 RecvDelta { 342 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 343 delta: 0, 344 }, 345 RecvDelta { 346 type_tcc_packet: SymbolTypeTcc::PacketReceivedLargeDelta, 347 delta: 0x0200 * TYPE_TCC_DELTA_SCALE_FACTOR, 348 }, 349 RecvDelta { 350 type_tcc_packet: SymbolTypeTcc::PacketReceivedLargeDelta, 351 delta: 0x0100 * TYPE_TCC_DELTA_SCALE_FACTOR, 352 }, 353 RecvDelta { 354 type_tcc_packet: SymbolTypeTcc::PacketReceivedLargeDelta, 355 delta: 0x0400 * TYPE_TCC_DELTA_SCALE_FACTOR, 356 }, 357 ]; 358 assert_eq!(pkt.recv_deltas.len(), expected_deltas.len()); 359 for (i, expected) in expected_deltas.iter().enumerate() { 360 assert_eq!(&pkt.recv_deltas[i], expected); 361 } 362 } 363 364 //"get RTCP" 365 { 366 let tests = vec![(320, 1, 5, 1), (1000, 2, 15, 2)]; 367 for (arrival_ts, sequence_number, want_ref_time, want_base_sequence_number) in tests { 368 let mut f = Feedback::new(0, 0, 0); 369 f.set_base(sequence_number, arrival_ts * 1000); 370 371 let got = f.get_rtcp(); 372 assert_eq!(got.reference_time, want_ref_time); 373 assert_eq!(got.base_sequence_number, want_base_sequence_number); 374 } 375 } 376 377 Ok(()) 378 } 379 380 fn add_run(r: &mut Recorder, sequence_numbers: &[u16], arrival_times: &[i64]) { 381 assert_eq!(sequence_numbers.len(), arrival_times.len()); 382 383 for i in 0..sequence_numbers.len() { 384 r.record(5000, sequence_numbers[i], arrival_times[i]); 385 } 386 } 387 388 const TYPE_TCC_DELTA_SCALE_FACTOR: i64 = 250; 389 const SCALE_FACTOR_REFERENCE_TIME: i64 = 64000; 390 391 fn increase_time(arrival_time: &mut i64, increase_amount: i64) -> i64 { 392 *arrival_time += increase_amount; 393 *arrival_time 394 } 395 396 fn marshal_all(pkts: &[Box<dyn rtcp::packet::Packet + Send + Sync>]) -> Result<()> { 397 for pkt in pkts { 398 let _ = pkt.marshal()?; 399 } 400 Ok(()) 401 } 402 403 #[test] 404 fn test_build_feedback_packet() -> Result<()> { 405 let mut r = Recorder::new(5000); 406 407 let mut arrival_time = SCALE_FACTOR_REFERENCE_TIME; 408 add_run( 409 &mut r, 410 &[0, 1, 2, 3, 4, 5, 6, 7], 411 &[ 412 SCALE_FACTOR_REFERENCE_TIME, 413 increase_time(&mut arrival_time, TYPE_TCC_DELTA_SCALE_FACTOR), 414 increase_time(&mut arrival_time, TYPE_TCC_DELTA_SCALE_FACTOR), 415 increase_time(&mut arrival_time, TYPE_TCC_DELTA_SCALE_FACTOR), 416 increase_time(&mut arrival_time, TYPE_TCC_DELTA_SCALE_FACTOR), 417 increase_time(&mut arrival_time, TYPE_TCC_DELTA_SCALE_FACTOR), 418 increase_time(&mut arrival_time, TYPE_TCC_DELTA_SCALE_FACTOR), 419 increase_time(&mut arrival_time, TYPE_TCC_DELTA_SCALE_FACTOR * 256), 420 ], 421 ); 422 423 let rtcp_packets = r.build_feedback_packet(); 424 assert_eq!(1, rtcp_packets.len()); 425 426 let expected = TransportLayerCc { 427 sender_ssrc: 5000, 428 media_ssrc: 5000, 429 base_sequence_number: 0, 430 reference_time: 1, 431 fb_pkt_count: 0, 432 packet_status_count: 8, 433 packet_chunks: vec![ 434 PacketStatusChunk::RunLengthChunk(RunLengthChunk { 435 type_tcc: StatusChunkTypeTcc::RunLengthChunk, 436 packet_status_symbol: SymbolTypeTcc::PacketReceivedSmallDelta, 437 run_length: 7, 438 }), 439 PacketStatusChunk::RunLengthChunk(RunLengthChunk { 440 type_tcc: StatusChunkTypeTcc::RunLengthChunk, 441 packet_status_symbol: SymbolTypeTcc::PacketReceivedLargeDelta, 442 run_length: 1, 443 }), 444 ], 445 recv_deltas: vec![ 446 RecvDelta { 447 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 448 delta: 0, 449 }, 450 RecvDelta { 451 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 452 delta: TYPE_TCC_DELTA_SCALE_FACTOR, 453 }, 454 RecvDelta { 455 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 456 delta: TYPE_TCC_DELTA_SCALE_FACTOR, 457 }, 458 RecvDelta { 459 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 460 delta: TYPE_TCC_DELTA_SCALE_FACTOR, 461 }, 462 RecvDelta { 463 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 464 delta: TYPE_TCC_DELTA_SCALE_FACTOR, 465 }, 466 RecvDelta { 467 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 468 delta: TYPE_TCC_DELTA_SCALE_FACTOR, 469 }, 470 RecvDelta { 471 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 472 delta: TYPE_TCC_DELTA_SCALE_FACTOR, 473 }, 474 RecvDelta { 475 type_tcc_packet: SymbolTypeTcc::PacketReceivedLargeDelta, 476 delta: TYPE_TCC_DELTA_SCALE_FACTOR * 256, 477 }, 478 ], 479 }; 480 481 if let Some(tcc) = rtcp_packets[0].as_any().downcast_ref::<TransportLayerCc>() { 482 assert_eq!(tcc, &expected); 483 } else { 484 panic!(); 485 } 486 487 marshal_all(&rtcp_packets[..])?; 488 489 Ok(()) 490 } 491 492 #[test] 493 fn test_build_feedback_packet_rolling() -> Result<()> { 494 let mut r = Recorder::new(5000); 495 496 let mut arrival_time = SCALE_FACTOR_REFERENCE_TIME; 497 add_run(&mut r, &[3], &[arrival_time]); 498 499 let rtcp_packets = r.build_feedback_packet(); 500 assert_eq!(0, rtcp_packets.len()); 501 502 add_run( 503 &mut r, 504 &[4, 8, 9], 505 &[ 506 increase_time(&mut arrival_time, TYPE_TCC_DELTA_SCALE_FACTOR), 507 increase_time(&mut arrival_time, TYPE_TCC_DELTA_SCALE_FACTOR), 508 increase_time(&mut arrival_time, TYPE_TCC_DELTA_SCALE_FACTOR), 509 ], 510 ); 511 512 let rtcp_packets = r.build_feedback_packet(); 513 assert_eq!(rtcp_packets.len(), 1); 514 515 let expected = TransportLayerCc { 516 sender_ssrc: 5000, 517 media_ssrc: 5000, 518 base_sequence_number: 3, 519 reference_time: 1, 520 fb_pkt_count: 0, 521 packet_status_count: 7, 522 packet_chunks: vec![PacketStatusChunk::StatusVectorChunk(StatusVectorChunk { 523 type_tcc: StatusChunkTypeTcc::StatusVectorChunk, 524 symbol_size: SymbolSizeTypeTcc::TwoBit, 525 symbol_list: vec![ 526 SymbolTypeTcc::PacketReceivedSmallDelta, 527 SymbolTypeTcc::PacketReceivedSmallDelta, 528 SymbolTypeTcc::PacketNotReceived, 529 SymbolTypeTcc::PacketNotReceived, 530 SymbolTypeTcc::PacketNotReceived, 531 SymbolTypeTcc::PacketReceivedSmallDelta, 532 SymbolTypeTcc::PacketReceivedSmallDelta, 533 ], 534 })], 535 recv_deltas: vec![ 536 RecvDelta { 537 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 538 delta: 0, 539 }, 540 RecvDelta { 541 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 542 delta: TYPE_TCC_DELTA_SCALE_FACTOR, 543 }, 544 RecvDelta { 545 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 546 delta: TYPE_TCC_DELTA_SCALE_FACTOR, 547 }, 548 RecvDelta { 549 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 550 delta: TYPE_TCC_DELTA_SCALE_FACTOR, 551 }, 552 ], 553 }; 554 555 if let Some(tcc) = rtcp_packets[0].as_any().downcast_ref::<TransportLayerCc>() { 556 assert_eq!(tcc, &expected); 557 } else { 558 panic!(); 559 } 560 561 marshal_all(&rtcp_packets[..])?; 562 563 Ok(()) 564 } 565