1 use super::*; 2 3 #[test] 4 fn test_h265_nalu_header() -> Result<()> { 5 #[derive(Default)] 6 struct TestType { 7 raw_header: Bytes, 8 9 fbit: bool, 10 typ: u8, 11 layer_id: u8, 12 tid: u8, 13 14 is_ap: bool, 15 is_fu: bool, 16 is_paci: bool, 17 } 18 19 let tests = vec![ 20 // fbit 21 TestType { 22 raw_header: Bytes::from_static(&[0x80, 0x00]), 23 typ: 0, 24 layer_id: 0, 25 tid: 0, 26 fbit: true, 27 ..Default::default() 28 }, 29 // VPS_NUT 30 TestType { 31 raw_header: Bytes::from_static(&[0x40, 0x01]), 32 typ: 32, 33 layer_id: 0, 34 tid: 1, 35 ..Default::default() 36 }, 37 // SPS_NUT 38 TestType { 39 raw_header: Bytes::from_static(&[0x42, 0x01]), 40 typ: 33, 41 layer_id: 0, 42 tid: 1, 43 ..Default::default() 44 }, 45 // PPS_NUT 46 TestType { 47 raw_header: Bytes::from_static(&[0x44, 0x01]), 48 typ: 34, 49 layer_id: 0, 50 tid: 1, 51 ..Default::default() 52 }, 53 // PREFIX_SEI_NUT 54 TestType { 55 raw_header: Bytes::from_static(&[0x4e, 0x01]), 56 typ: 39, 57 layer_id: 0, 58 tid: 1, 59 ..Default::default() 60 }, 61 // Fragmentation Unit 62 TestType { 63 raw_header: Bytes::from_static(&[0x62, 0x01]), 64 typ: H265NALU_FRAGMENTATION_UNIT_TYPE, 65 layer_id: 0, 66 tid: 1, 67 is_fu: true, 68 ..Default::default() 69 }, 70 ]; 71 72 for cur in tests { 73 let header = H265NALUHeader::new(cur.raw_header[0], cur.raw_header[1]); 74 75 assert_eq!(header.f(), cur.fbit, "invalid F bit"); 76 assert_eq!(header.nalu_type(), cur.typ, "invalid type"); 77 78 // For any type < 32, NAL is a VLC NAL unit. 79 assert_eq!( 80 header.is_type_vcl_unit(), 81 (header.nalu_type() < 32), 82 "invalid IsTypeVCLUnit" 83 ); 84 assert_eq!( 85 header.is_aggregation_packet(), 86 cur.is_ap, 87 "invalid type (aggregation packet)" 88 ); 89 assert_eq!( 90 header.is_fragmentation_unit(), 91 cur.is_fu, 92 "invalid type (fragmentation unit)" 93 ); 94 assert_eq!(header.is_paci_packet(), cur.is_paci, "invalid type (PACI)"); 95 assert_eq!(header.layer_id(), cur.layer_id, "invalid layer_id"); 96 assert_eq!(header.tid(), cur.tid, "invalid tid"); 97 } 98 99 Ok(()) 100 } 101 102 #[test] 103 fn test_h265_fu_header() -> Result<()> { 104 #[derive(Default)] 105 struct TestType { 106 header: H265FragmentationUnitHeader, 107 108 s: bool, 109 e: bool, 110 typ: u8, 111 } 112 113 let tests = vec![ 114 // Start | IDR_W_RADL 115 TestType { 116 header: H265FragmentationUnitHeader(0x93), 117 s: true, 118 e: false, 119 typ: 19, 120 }, 121 // Continuation | IDR_W_RADL 122 TestType { 123 header: H265FragmentationUnitHeader(0x13), 124 s: false, 125 e: false, 126 typ: 19, 127 }, 128 // End | IDR_W_RADL 129 TestType { 130 header: H265FragmentationUnitHeader(0x53), 131 s: false, 132 e: true, 133 typ: 19, 134 }, 135 // Start | TRAIL_R 136 TestType { 137 header: H265FragmentationUnitHeader(0x81), 138 s: true, 139 e: false, 140 typ: 1, 141 }, 142 // Continuation | TRAIL_R 143 TestType { 144 header: H265FragmentationUnitHeader(0x01), 145 s: false, 146 e: false, 147 typ: 1, 148 }, 149 // End | TRAIL_R 150 TestType { 151 header: H265FragmentationUnitHeader(0x41), 152 s: false, 153 e: true, 154 typ: 1, 155 }, 156 ]; 157 158 for cur in tests { 159 assert_eq!(cur.header.s(), cur.s, "invalid s field"); 160 assert_eq!(cur.header.e(), cur.e, "invalid e field"); 161 assert_eq!(cur.header.fu_type(), cur.typ, "invalid FuType field"); 162 } 163 164 Ok(()) 165 } 166 167 #[test] 168 fn test_h265_single_nalunit_packet() -> Result<()> { 169 #[derive(Default)] 170 struct TestType { 171 raw: Bytes, 172 with_donl: bool, 173 expected_packet: Option<H265SingleNALUnitPacket>, 174 expected_err: Option<Error>, 175 } 176 177 let tests = vec![ 178 TestType { 179 raw: Bytes::from_static(&[]), 180 expected_err: Some(Error::ErrShortPacket), 181 ..Default::default() 182 }, 183 TestType { 184 raw: Bytes::from_static(&[0x62]), 185 expected_err: Some(Error::ErrShortPacket), 186 ..Default::default() 187 }, 188 TestType { 189 raw: Bytes::from_static(&[0x62, 0x01, 0x93]), 190 expected_err: Some(Error::ErrShortPacket), 191 ..Default::default() 192 }, 193 // FBit enabled in H265NALUHeader 194 TestType { 195 raw: Bytes::from_static(&[0x80, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]), 196 expected_err: Some(Error::ErrH265CorruptedPacket), 197 ..Default::default() 198 }, 199 // Type '49' in H265NALUHeader 200 TestType { 201 raw: Bytes::from_static(&[0x62, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]), 202 expected_err: Some(Error::ErrInvalidH265PacketType), 203 ..Default::default() 204 }, 205 // Type '50' in H265NALUHeader 206 TestType { 207 raw: Bytes::from_static(&[0x64, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]), 208 expected_err: Some(Error::ErrInvalidH265PacketType), 209 ..Default::default() 210 }, 211 TestType { 212 raw: Bytes::from_static(&[0x01, 0x01, 0xab, 0xcd, 0xef]), 213 expected_packet: Some(H265SingleNALUnitPacket { 214 payload_header: H265NALUHeader::new(0x01, 0x01), 215 payload: Bytes::from_static(&[0xab, 0xcd, 0xef]), 216 ..Default::default() 217 }), 218 ..Default::default() 219 }, 220 // DONL, payload too small 221 TestType { 222 raw: Bytes::from_static(&[0x01, 0x01, 0x93, 0xaf]), 223 expected_err: Some(Error::ErrShortPacket), 224 with_donl: true, 225 ..Default::default() 226 }, 227 TestType { 228 raw: Bytes::from_static(&[0x01, 0x01, 0xaa, 0xbb, 0xcc]), 229 expected_packet: Some(H265SingleNALUnitPacket { 230 payload_header: H265NALUHeader::new(0x01, 0x01), 231 donl: Some((0xaa << 8) | 0xbb), 232 payload: Bytes::from_static(&[0xcc]), 233 ..Default::default() 234 }), 235 with_donl: true, 236 ..Default::default() 237 }, 238 ]; 239 240 for cur in tests { 241 let mut parsed = H265SingleNALUnitPacket::default(); 242 if cur.with_donl { 243 parsed.with_donl(cur.with_donl); 244 } 245 246 let result = parsed.depacketize(&cur.raw); 247 248 if cur.expected_err.is_some() && result.is_ok() { 249 assert!(false, "should error"); 250 } else if cur.expected_err.is_none() && result.is_err() { 251 assert!(false, "should not error"); 252 } 253 254 if let Some(expected_packet) = cur.expected_packet { 255 assert_eq!( 256 expected_packet.payload_header(), 257 parsed.payload_header(), 258 "invalid payload header" 259 ); 260 assert_eq!(expected_packet.donl(), parsed.donl(), "invalid DONL"); 261 262 assert_eq!( 263 expected_packet.payload(), 264 parsed.payload(), 265 "invalid payload" 266 ); 267 } 268 } 269 270 Ok(()) 271 } 272 273 #[test] 274 fn test_h265_aggregation_packet() -> Result<()> { 275 #[derive(Default)] 276 struct TestType { 277 raw: Bytes, 278 with_donl: bool, 279 expected_packet: Option<H265AggregationPacket>, 280 expected_err: Option<Error>, 281 } 282 283 let tests = vec![ 284 TestType { 285 raw: Bytes::from_static(&[]), 286 expected_err: Some(Error::ErrShortPacket), 287 ..Default::default() 288 }, 289 TestType { 290 raw: Bytes::from_static(&[0x62]), 291 expected_err: Some(Error::ErrShortPacket), 292 ..Default::default() 293 }, 294 TestType { 295 raw: Bytes::from_static(&[0x62, 0x01, 0x93]), 296 expected_err: Some(Error::ErrShortPacket), 297 ..Default::default() 298 }, 299 // FBit enabled in H265NALUHeader 300 TestType { 301 raw: Bytes::from_static(&[0x80, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]), 302 expected_err: Some(Error::ErrH265CorruptedPacket), 303 ..Default::default() 304 }, 305 // Type '48' in H265NALUHeader 306 TestType { 307 raw: Bytes::from_static(&[0xE0, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]), 308 expected_err: Some(Error::ErrInvalidH265PacketType), 309 ..Default::default() 310 }, 311 // Small payload 312 TestType { 313 raw: Bytes::from_static(&[0x60, 0x01, 0x00, 0x1]), 314 expected_err: Some(Error::ErrShortPacket), 315 ..Default::default() 316 }, 317 // Small payload 318 TestType { 319 raw: Bytes::from_static(&[0x60, 0x01, 0x00]), 320 expected_err: Some(Error::ErrShortPacket), 321 with_donl: true, 322 ..Default::default() 323 }, 324 // Small payload 325 TestType { 326 raw: Bytes::from_static(&[0x60, 0x01, 0x00, 0x1]), 327 expected_err: Some(Error::ErrShortPacket), 328 with_donl: true, 329 ..Default::default() 330 }, 331 // Small payload 332 TestType { 333 raw: Bytes::from_static(&[0x60, 0x01, 0x00, 0x01, 0x02]), 334 expected_err: Some(Error::ErrShortPacket), 335 with_donl: true, 336 ..Default::default() 337 }, 338 // Single Aggregation Unit 339 TestType { 340 raw: Bytes::from_static(&[0x60, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00]), 341 expected_err: Some(Error::ErrShortPacket), 342 with_donl: true, 343 ..Default::default() 344 }, 345 // Incomplete second Aggregation Unit 346 TestType { 347 raw: Bytes::from_static(&[ 348 0x60, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, // DONL 349 0x00, 350 ]), 351 expected_err: Some(Error::ErrShortPacket), 352 with_donl: true, 353 ..Default::default() 354 }, 355 // Incomplete second Aggregation Unit 356 TestType { 357 raw: Bytes::from_static(&[ 358 0x60, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 359 // DONL, NAL Unit size (2 bytes) 360 0x00, 0x55, 0x55, 361 ]), 362 expected_err: Some(Error::ErrShortPacket), 363 with_donl: true, 364 ..Default::default() 365 }, 366 // Valid Second Aggregation Unit 367 TestType { 368 raw: Bytes::from_static(&[ 369 0x60, 0x01, 0xcc, 0xdd, 0x00, 0x02, 0xff, 0xee, 370 // DONL, NAL Unit size (2 bytes), Payload 371 0x77, 0x00, 0x01, 0xaa, 372 ]), 373 with_donl: true, 374 expected_packet: Some(H265AggregationPacket { 375 first_unit: Some(H265AggregationUnitFirst { 376 donl: Some(0xccdd), 377 nal_unit_size: 2, 378 nal_unit: Bytes::from_static(&[0xff, 0xee]), 379 }), 380 other_units: vec![H265AggregationUnit { 381 dond: Some(0x77), 382 nal_unit_size: 1, 383 nal_unit: Bytes::from_static(&[0xaa]), 384 }], 385 might_need_donl: false, 386 }), 387 ..Default::default() 388 }, 389 ]; 390 391 for cur in tests { 392 let mut parsed = H265AggregationPacket::default(); 393 if cur.with_donl { 394 parsed.with_donl(cur.with_donl); 395 } 396 397 let result = parsed.depacketize(&cur.raw); 398 399 if cur.expected_err.is_some() && result.is_ok() { 400 assert!(false, "should error"); 401 } else if cur.expected_err.is_none() && result.is_err() { 402 assert!(false, "should not error"); 403 } 404 405 if let Some(expected_packet) = cur.expected_packet { 406 if let (Some(first_unit), Some(parsed_first_unit)) = 407 (expected_packet.first_unit(), parsed.first_unit()) 408 { 409 assert_eq!( 410 parsed_first_unit.nal_unit_size, first_unit.nal_unit_size, 411 "invalid first unit NALUSize" 412 ); 413 assert_eq!( 414 first_unit.donl(), 415 parsed_first_unit.donl(), 416 "invalid first unit DONL" 417 ); 418 assert_eq!( 419 first_unit.nal_unit(), 420 parsed_first_unit.nal_unit(), 421 "invalid first unit NalUnit" 422 ); 423 } 424 425 assert_eq!( 426 expected_packet.other_units().len(), 427 parsed.other_units().len(), 428 "number of other units mismatch" 429 ); 430 431 for ndx in 0..expected_packet.other_units().len() { 432 assert_eq!( 433 parsed.other_units()[ndx].nalu_size(), 434 expected_packet.other_units()[ndx].nalu_size(), 435 "invalid unit NALUSize" 436 ); 437 438 assert_eq!( 439 expected_packet.other_units()[ndx].dond(), 440 parsed.other_units()[ndx].dond(), 441 "invalid unit DOND" 442 ); 443 444 assert_eq!( 445 expected_packet.other_units()[ndx].nal_unit(), 446 parsed.other_units()[ndx].nal_unit(), 447 "invalid first unit NalUnit" 448 ); 449 } 450 451 assert_eq!( 452 expected_packet.other_units(), 453 parsed.other_units(), 454 "invalid payload" 455 ); 456 } 457 } 458 459 Ok(()) 460 } 461 462 #[test] 463 fn test_h265_fragmentation_unit_packet() -> Result<()> { 464 #[derive(Default)] 465 struct TestType { 466 raw: Bytes, 467 with_donl: bool, 468 expected_fu: Option<H265FragmentationUnitPacket>, 469 expected_err: Option<Error>, 470 } 471 let tests = vec![ 472 TestType { 473 raw: Bytes::from_static(&[]), 474 expected_err: Some(Error::ErrShortPacket), 475 ..Default::default() 476 }, 477 TestType { 478 raw: Bytes::from_static(&[0x62]), 479 expected_err: Some(Error::ErrShortPacket), 480 ..Default::default() 481 }, 482 TestType { 483 raw: Bytes::from_static(&[0x62, 0x01]), 484 expected_err: Some(Error::ErrShortPacket), 485 ..Default::default() 486 }, 487 TestType { 488 raw: Bytes::from_static(&[0x62, 0x01, 0x93]), 489 expected_err: Some(Error::ErrShortPacket), 490 ..Default::default() 491 }, 492 // FBit enabled in H265NALUHeader 493 TestType { 494 raw: Bytes::from_static(&[0x80, 0x01, 0x93, 0xaf]), 495 expected_err: Some(Error::ErrH265CorruptedPacket), 496 ..Default::default() 497 }, 498 // Type not '49' in H265NALUHeader 499 TestType { 500 raw: Bytes::from_static(&[0x40, 0x01, 0x93, 0xaf]), 501 expected_err: Some(Error::ErrInvalidH265PacketType), 502 ..Default::default() 503 }, 504 TestType { 505 raw: Bytes::from_static(&[0x62, 0x01, 0x93, 0xaf]), 506 expected_fu: Some(H265FragmentationUnitPacket { 507 payload_header: H265NALUHeader::new(0x62, 0x01), 508 fu_header: H265FragmentationUnitHeader(0x93), 509 donl: None, 510 payload: Bytes::from_static(&[0xaf]), 511 might_need_donl: false, 512 }), 513 ..Default::default() 514 }, 515 TestType { 516 raw: Bytes::from_static(&[0x62, 0x01, 0x93, 0xcc]), 517 with_donl: true, 518 expected_err: Some(Error::ErrShortPacket), 519 ..Default::default() 520 }, 521 TestType { 522 raw: Bytes::from_static(&[0x62, 0x01, 0x93, 0xcc, 0xdd, 0xaf, 0x0d, 0x5a]), 523 with_donl: true, 524 expected_fu: Some(H265FragmentationUnitPacket { 525 payload_header: H265NALUHeader::new(0x62, 0x01), 526 fu_header: H265FragmentationUnitHeader(0x93), 527 donl: Some((0xcc << 8) | 0xdd), 528 payload: Bytes::from_static(&[0xaf, 0x0d, 0x5a]), 529 might_need_donl: false, 530 }), 531 ..Default::default() 532 }, 533 ]; 534 535 for cur in tests { 536 let mut parsed = H265FragmentationUnitPacket::default(); 537 if cur.with_donl { 538 parsed.with_donl(cur.with_donl); 539 } 540 541 let result = parsed.depacketize(&cur.raw); 542 543 if cur.expected_err.is_some() && result.is_ok() { 544 assert!(false, "should error"); 545 } else if cur.expected_err.is_none() && result.is_err() { 546 assert!(false, "should not error"); 547 } 548 549 if let Some(expected_fu) = &cur.expected_fu { 550 assert_eq!( 551 parsed.payload_header(), 552 expected_fu.payload_header(), 553 "invalid payload header" 554 ); 555 assert_eq!( 556 parsed.fu_header(), 557 expected_fu.fu_header(), 558 "invalid FU header" 559 ); 560 assert_eq!(parsed.donl(), expected_fu.donl(), "invalid DONL"); 561 assert_eq!(parsed.payload(), expected_fu.payload(), "invalid Payload"); 562 } 563 } 564 565 Ok(()) 566 } 567 568 #[test] 569 fn test_h265_temporal_scalability_control_information() -> Result<()> { 570 #[derive(Default)] 571 struct TestType { 572 value: H265TSCI, 573 expected_tl0picidx: u8, 574 expected_irap_pic_id: u8, 575 expected_s: bool, 576 expected_e: bool, 577 expected_res: u8, 578 } 579 580 let tests = vec![ 581 TestType { 582 value: H265TSCI(((0xCA) << 24) | ((0xFE) << 16)), 583 expected_tl0picidx: 0xCA, 584 expected_irap_pic_id: 0xFE, 585 ..Default::default() 586 }, 587 TestType { 588 value: H265TSCI((1) << 15), 589 expected_s: true, 590 ..Default::default() 591 }, 592 TestType { 593 value: H265TSCI((1) << 14), 594 expected_e: true, 595 ..Default::default() 596 }, 597 TestType { 598 value: H265TSCI((0x0A) << 8), 599 expected_res: 0x0A, 600 ..Default::default() 601 }, 602 // Sets RES, and force sets S and E to 0. 603 TestType { 604 value: H265TSCI(((0xAA) << 8) & (u32::MAX ^ ((1) << 15)) & (u32::MAX ^ ((1) << 14))), 605 expected_res: 0xAA & 0b00111111, 606 ..Default::default() 607 }, 608 ]; 609 610 for cur in tests { 611 assert_eq!( 612 cur.value.tl0picidx(), 613 cur.expected_tl0picidx, 614 "invalid TL0PICIDX" 615 ); 616 assert_eq!( 617 cur.value.irap_pic_id(), 618 cur.expected_irap_pic_id, 619 "invalid IrapPicID" 620 ); 621 assert_eq!(cur.value.s(), cur.expected_s, "invalid S"); 622 assert_eq!(cur.value.e(), cur.expected_e, "invalid E"); 623 assert_eq!(cur.value.res(), cur.expected_res, "invalid RES"); 624 } 625 626 Ok(()) 627 } 628 629 #[test] 630 fn test_h265_paci_packet() -> Result<()> { 631 #[derive(Default)] 632 struct TestType { 633 raw: Bytes, 634 expected_fu: Option<H265PACIPacket>, 635 expected_err: Option<Error>, 636 } 637 638 let tests = vec![ 639 TestType { 640 raw: Bytes::from_static(&[]), 641 expected_err: Some(Error::ErrShortPacket), 642 ..Default::default() 643 }, 644 TestType { 645 raw: Bytes::from_static(&[0x62, 0x01, 0x93]), 646 expected_err: Some(Error::ErrShortPacket), 647 ..Default::default() 648 }, 649 // FBit enabled in H265NALUHeader 650 TestType { 651 raw: Bytes::from_static(&[0x80, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]), 652 expected_err: Some(Error::ErrH265CorruptedPacket), 653 ..Default::default() 654 }, 655 // Type not '50' in H265NALUHeader 656 TestType { 657 raw: Bytes::from_static(&[0x40, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]), 658 expected_err: Some(Error::ErrInvalidH265PacketType), 659 ..Default::default() 660 }, 661 // Invalid header extension size 662 TestType { 663 raw: Bytes::from_static(&[0x64, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]), 664 expected_err: Some(Error::ErrInvalidH265PacketType), 665 ..Default::default() 666 }, 667 // No Header Extension 668 TestType { 669 raw: Bytes::from_static(&[0x64, 0x01, 0x64, 0x00, 0xab, 0xcd, 0xef]), 670 expected_fu: Some(H265PACIPacket { 671 payload_header: H265NALUHeader::new(0x64, 0x01), 672 paci_header_fields: ((0x64) << 8), 673 phes: Bytes::from_static(&[]), 674 payload: Bytes::from_static(&[0xab, 0xcd, 0xef]), 675 }), 676 ..Default::default() 677 }, 678 // Header Extension 1 byte 679 TestType { 680 raw: Bytes::from_static(&[0x64, 0x01, 0x64, 0x10, 0xff, 0xab, 0xcd, 0xef]), 681 expected_fu: Some(H265PACIPacket { 682 payload_header: H265NALUHeader::new(0x64, 0x01), 683 paci_header_fields: ((0x64) << 8) | (0x10), 684 phes: Bytes::from_static(&[0xff]), 685 payload: Bytes::from_static(&[0xab, 0xcd, 0xef]), 686 }), 687 ..Default::default() 688 }, 689 // Header Extension TSCI 690 TestType { 691 raw: Bytes::from_static(&[ 692 0x64, 0x01, 0x64, 0b00111000, 0xaa, 0xbb, 0x80, 0xab, 0xcd, 0xef, 693 ]), 694 expected_fu: Some(H265PACIPacket { 695 payload_header: H265NALUHeader::new(0x64, 0x01), 696 paci_header_fields: ((0x64) << 8) | (0b00111000), 697 phes: Bytes::from_static(&[0xaa, 0xbb, 0x80]), 698 payload: Bytes::from_static(&[0xab, 0xcd, 0xef]), 699 }), 700 ..Default::default() 701 }, 702 ]; 703 704 for cur in tests { 705 let mut parsed = H265PACIPacket::default(); 706 707 let result = parsed.depacketize(&cur.raw); 708 709 if cur.expected_err.is_some() && result.is_ok() { 710 assert!(false, "should error"); 711 } else if cur.expected_err.is_none() && result.is_err() { 712 assert!(false, "should not error"); 713 } 714 715 if let Some(expected_fu) = &cur.expected_fu { 716 assert_eq!( 717 expected_fu.payload_header(), 718 parsed.payload_header(), 719 "invalid PayloadHeader" 720 ); 721 assert_eq!(expected_fu.a(), parsed.a(), "invalid A"); 722 assert_eq!(expected_fu.ctype(), parsed.ctype(), "invalid CType"); 723 assert_eq!(expected_fu.phs_size(), parsed.phs_size(), "invalid PHSsize"); 724 assert_eq!(expected_fu.f0(), parsed.f0(), "invalid F0"); 725 assert_eq!(expected_fu.f1(), parsed.f1(), "invalid F1"); 726 assert_eq!(expected_fu.f2(), parsed.f2(), "invalid F2"); 727 assert_eq!(expected_fu.y(), parsed.y(), "invalid Y"); 728 assert_eq!(expected_fu.phes(), parsed.phes(), "invalid PHES"); 729 assert_eq!(expected_fu.payload(), parsed.payload(), "invalid Payload"); 730 assert_eq!(expected_fu.tsci(), parsed.tsci(), "invalid TSCI"); 731 } 732 } 733 734 Ok(()) 735 } 736 737 #[test] 738 fn test_h265_packet() -> Result<()> { 739 #[derive(Default)] 740 struct TestType { 741 raw: Bytes, 742 with_donl: bool, 743 expected_packet_type: Option<H265Payload>, 744 expected_err: Option<Error>, 745 } 746 let tests = vec![ 747 TestType { 748 raw: Bytes::from_static(&[]), 749 expected_err: Some(Error::ErrShortPacket), 750 ..Default::default() 751 }, 752 TestType { 753 raw: Bytes::from_static(&[0x62, 0x01, 0x93]), 754 expected_err: Some(Error::ErrShortPacket), 755 ..Default::default() 756 }, 757 TestType { 758 raw: Bytes::from_static(&[0x64, 0x01, 0x93, 0xaf]), 759 expected_err: Some(Error::ErrShortPacket), 760 ..Default::default() 761 }, 762 TestType { 763 raw: Bytes::from_static(&[0x01, 0x01]), 764 with_donl: true, 765 expected_err: Some(Error::ErrShortPacket), 766 ..Default::default() 767 }, 768 // FBit enabled in H265NALUHeader 769 TestType { 770 raw: Bytes::from_static(&[0x80, 0x01, 0x93, 0xaf, 0xaf, 0xaf, 0xaf]), 771 expected_err: Some(Error::ErrH265CorruptedPacket), 772 ..Default::default() 773 }, 774 // Valid H265SingleNALUnitPacket 775 TestType { 776 raw: Bytes::from_static(&[0x01, 0x01, 0xab, 0xcd, 0xef]), 777 expected_packet_type: Some(H265Payload::H265SingleNALUnitPacket( 778 H265SingleNALUnitPacket::default(), 779 )), 780 ..Default::default() 781 }, 782 // Invalid H265SingleNALUnitPacket 783 TestType { 784 raw: Bytes::from_static(&[0x01, 0x01, 0x93, 0xaf]), 785 expected_err: Some(Error::ErrShortPacket), 786 with_donl: true, 787 ..Default::default() 788 }, 789 // Valid H265PACIPacket 790 TestType { 791 raw: Bytes::from_static(&[ 792 0x64, 0x01, 0x64, 0b00111000, 0xaa, 0xbb, 0x80, 0xab, 0xcd, 0xef, 793 ]), 794 expected_packet_type: Some(H265Payload::H265PACIPacket(H265PACIPacket::default())), 795 ..Default::default() 796 }, 797 // Valid H265FragmentationUnitPacket 798 TestType { 799 raw: Bytes::from_static(&[0x62, 0x01, 0x93, 0xcc, 0xdd, 0xaf, 0x0d, 0x5a]), 800 expected_packet_type: Some(H265Payload::H265FragmentationUnitPacket( 801 H265FragmentationUnitPacket::default(), 802 )), 803 with_donl: true, 804 ..Default::default() 805 }, 806 // Valid H265AggregationPacket 807 TestType { 808 raw: Bytes::from_static(&[ 809 0x60, 0x01, 0xcc, 0xdd, 0x00, 0x02, 0xff, 0xee, 0x77, 0x00, 0x01, 0xaa, 810 ]), 811 expected_packet_type: Some(H265Payload::H265AggregationPacket( 812 H265AggregationPacket::default(), 813 )), 814 with_donl: true, 815 ..Default::default() 816 }, 817 // Invalid H265AggregationPacket 818 TestType { 819 raw: Bytes::from_static(&[0x60, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00]), 820 expected_err: Some(Error::ErrShortPacket), 821 with_donl: true, 822 ..Default::default() 823 }, 824 ]; 825 826 for cur in tests { 827 let mut pck = H265Packet::default(); 828 if cur.with_donl { 829 pck.with_donl(true); 830 } 831 832 let result = pck.depacketize(&cur.raw); 833 834 if cur.expected_err.is_some() && result.is_ok() { 835 assert!(false, "should error"); 836 } else if cur.expected_err.is_none() && result.is_err() { 837 assert!(false, "should not error"); 838 } 839 840 if cur.expected_err.is_some() { 841 continue; 842 } 843 844 if let Some(expected_packet_type) = &cur.expected_packet_type { 845 //TODO: assert_eq!(pck.packet(), expected_packet_type, "invalid packet type"); 846 let pck_packet = pck.payload(); 847 match (pck_packet, expected_packet_type) { 848 ( 849 &H265Payload::H265SingleNALUnitPacket(_), 850 &H265Payload::H265SingleNALUnitPacket(_), 851 ) => assert!(true), 852 ( 853 &H265Payload::H265FragmentationUnitPacket(_), 854 &H265Payload::H265FragmentationUnitPacket(_), 855 ) => assert!(true), 856 ( 857 &H265Payload::H265AggregationPacket(_), 858 &H265Payload::H265AggregationPacket(_), 859 ) => assert!(true), 860 (&H265Payload::H265PACIPacket(_), &H265Payload::H265PACIPacket(_)) => { 861 assert!(true) 862 } 863 _ => assert!(false), 864 }; 865 } 866 } 867 868 Ok(()) 869 } 870 871 #[test] 872 fn test_h265_packet_real() -> Result<()> { 873 // Tests decoding of real H265 payloads extracted from a Wireshark dump. 874 let tests = vec![ 875 b"\x40\x01\x0c\x01\xff\xff\x01\x60\x00\x00\x03\x00\xb0\x00\x00\x03\x00\x00\x03\x00\x7b\xac\x09".to_vec(), 876 b"\x42\x01\x01\x01\x60\x00\x00\x03\x00\xb0\x00\x00\x03\x00\x00\x03\x00\x7b\xa0\x03\xc0\x80\x10\xe5\x8d\xae\x49\x32\xf4\xdc\x04\x04\x04\x02".to_vec(), 877 b"\x44\x01\xc0\xf2\xf0\x3c\x90".to_vec(), 878 b"\x4e\x01\xe5\x04\x61\x0c\x00\x00\x80".to_vec(), 879 b"\x62\x01\x93\xaf\x0d\x5a\xfe\x67\x77\x29\xc0\x74\xf3\x57\x4c\x16\x94\xaa\x7c\x2a\x64\x5f\xe9\xa5\xb7\x2a\xa3\x95\x9d\x94\xa7\xb4\xd3\xc4\x4a\xb1\xb7\x69\xca\xbe\x75\xc5\x64\xa8\x97\x4b\x8a\xbf\x7e\xf0\x0f\xc3\x22\x60\x67\xab\xae\x96\xd6\x99\xca\x7a\x8d\x35\x93\x1a\x67\x60\xe7\xbe\x7e\x13\x95\x3c\xe0\x11\xc1\xc1\xa7\x48\xef\xf7\x7b\xb0\xeb\x35\x49\x81\x4e\x4e\x54\xf7\x31\x6a\x38\xa1\xa7\x0c\xd6\xbe\x3b\x25\xba\x08\x19\x0b\x49\xfd\x90\xbb\x73\x7a\x45\x8c\xb9\x73\x43\x04\xc5\x5f\xda\x0f\xd5\x70\x4c\x11\xee\x72\xb8\x6a\xb4\x95\x62\x64\xb6\x23\x14\x7e\xdb\x0e\xa5\x0f\x86\x31\xe4\xd1\x64\x56\x43\xf6\xb7\xe7\x1b\x93\x4a\xeb\xd0\xa6\xe3\x1f\xce\xda\x15\x67\x05\xb6\x77\x36\x8b\x27\x5b\xc6\xf2\x95\xb8\x2b\xcc\x9b\x0a\x03\x05\xbe\xc3\xd3\x85\xf5\x69\xb6\x19\x1f\x63\x2d\x8b\x65\x9e\xc3\x9d\xd2\x44\xb3\x7c\x86\x3b\xea\xa8\x5d\x02\xe5\x40\x03\x20\x76\x48\xff\xf6\x2b\x0d\x18\xd6\x4d\x49\x70\x1a\x5e\xb2\x89\xca\xec\x71\x41\x79\x4e\x94\x17\x0c\x57\x51\x55\x14\x61\x40\x46\x4b\x3e\x17\xb2\xc8\xbd\x1c\x06\x13\x91\x72\xf8\xc8\xfc\x6f\xb0\x30\x9a\xec\x3b\xa6\xc9\x33\x0b\xa5\xe5\xf4\x65\x7a\x29\x8b\x76\x62\x81\x12\xaf\x20\x4c\xd9\x21\x23\x9e\xeb\xc9\x0e\x5b\x29\x35\x7f\x41\xcd\xce\xa1\xc4\xbe\x01\x30\xb9\x11\xc3\xb1\xe4\xce\x45\xd2\x5c\xb3\x1e\x69\x78\xba\xb1\x72\xe4\x88\x54\xd8\x5d\xd0\xa8\x3a\x74\xad\xe5\xc7\xc1\x59\x7c\x78\x15\x26\x37\x3d\x50\xae\xb3\xa4\x5b\x6c\x7d\x65\x66\x85\x4d\x16\x9a\x67\x74\xad\x55\x32\x3a\x84\x85\x0b\x6a\xeb\x24\x97\xb4\x20\x4d\xca\x41\x61\x7a\xd1\x7b\x60\xdb\x7f\xd5\x61\x22\xcf\xd1\x7e\x4c\xf3\x85\xfd\x13\x63\xe4\x9d\xed\xac\x13\x0a\xa0\x92\xb7\x34\xde\x65\x0f\xd9\x0f\x9b\xac\xe2\x47\xe8\x5c\xb3\x11\x8e\xc6\x08\x19\xd0\xb0\x85\x52\xc8\x5c\x1b\x08\x0a\xce\xc9\x6b\xa7\xef\x95\x2f\xd0\xb8\x63\xe5\x4c\xd4\xed\x6e\x87\xe9\xd4\x0a\xe6\x11\x44\x63\x00\x94\x18\xe9\x28\xba\xcf\x92\x43\x06\x59\xdd\x37\x4f\xd3\xef\x9d\x31\x5e\x9b\x48\xf9\x1f\x3e\x7b\x95\x3a\xbd\x1f\x71\x55\x0c\x06\xf9\x86\xf8\x3d\x39\x16\x50\xb3\x21\x11\x19\x6f\x70\xa9\x48\xe8\xbb\x0a\x11\x23\xf8\xab\xfe\x44\xe0\xbb\xe8\x64\xfa\x85\xe4\x02\x55\x88\x41\xc6\x30\x7f\x10\xad\x75\x02\x4b\xef\xe1\x0b\x06\x3c\x10\x49\x83\xf9\xd1\x3e\x3e\x67\x86\x4c\xf8\x9d\xde\x5a\xc4\xc8\xcf\xb6\xf4\xb0\xd3\x34\x58\xd4\x7b\x4d\xd3\x37\x63\xb2\x48\x8a\x7e\x20\x00\xde\xb4\x42\x8f\xda\xe9\x43\x9e\x0c\x16\xce\x79\xac\x2c\x70\xc1\x89\x05\x36\x62\x6e\xd9\xbc\xfb\x63\xc6\x79\x89\x3c\x90\x89\x2b\xd1\x8c\xe0\xc2\x54\xc7\xd6\xb4\xe8\x9e\x96\x55\x6e\x7b\xd5\x7f\xac\xd4\xa7\x1c\xa0\xdf\x01\x30\xad\xc0\x9f\x69\x06\x10\x43\x7f\xf4\x5d\x62\xa3\xea\x73\xf2\x14\x79\x19\x13\xea\x59\x14\x79\xa8\xe7\xce\xce\x44\x25\x13\x41\x18\x57\xdd\xce\xe4\xbe\xcc\x20\x80\x29\x71\x73\xa7\x7c\x86\x39\x76\xf4\xa7\x1c\x63\x24\x21\x93\x1e\xb5\x9a\x5c\x8a\x9e\xda\x8b\x9d\x88\x97\xfc\x98\x7d\x26\x74\x04\x1f\xa8\x10\x4f\x45\xcd\x46\xe8\x28\xe4\x8e\x59\x67\x63\x4a\xcf\x1e\xed\xdd\xbb\x79\x2f\x8d\x94\xab\xfc\xdb\xc5\x79\x1a\x4d\xcd\x53\x41\xdf\xd1\x7a\x8f\x46\x3e\x1f\x79\x88\xe3\xee\x9f\xc4\xc1\xe6\x2e\x89\x4d\x28\xc9\xca\x28\xc2\x0a\xc5\xc7\xf1\x22\xcd\xb3\x36\xfa\xe3\x7e\xa6\xcd\x95\x55\x5e\x0e\x1a\x75\x7f\x65\x27\xd3\x37\x4f\x23\xc5\xab\x49\x68\x4e\x02\xb5\xbf\xd7\x95\xc0\x78\x67\xbc\x1a\xe9\xae\x6f\x44\x58\x8a\xc2\xce\x42\x98\x4e\x77\xc7\x2a\xa0\xa7\x7d\xe4\x3b\xd1\x20\x82\x1a\xd3\xe2\xc7\x76\x5d\x06\x46\xb5\x24\xd7\xfb\x57\x63\x2b\x19\x51\x48\x65\x6d\xfb\xe0\x98\xd1\x14\x0e\x17\x64\x29\x34\x6f\x6e\x66\x9e\x8d\xc9\x89\x49\x69\xee\x74\xf3\x35\xe6\x8b\x67\x56\x95\x7f\x1b\xe9\xed\x8c\x0f\xe2\x19\x59\xbf\x03\x35\x55\x3c\x04\xbc\x40\x52\x90\x10\x08\xad\xa7\x65\xe0\x31\xcb\xcf\x3d\xd4\x62\x68\x01\x0d\xed\xf5\x28\x64\x2d\xaa\x7c\x99\x15\x8d\x70\x32\x53\xb8\x9d\x0a\x3c\xbf\x91\x02\x04\xd0\xee\x87\xce\x04\xcc\x3e\xa8\x20\xfd\x97\xdf\xbf\x4a\xbc\xfc\xc9\x7c\x77\x21\xcc\x23\x6f\x59\x38\xd8\xd9\xa0\x0e\xb1\x23\x4e\x04\x3f\x14\x9e\xcc\x05\x54\xab\x20\x69\xed\xa4\xd5\x1d\xb4\x1b\x52\xed\x6a\xea\xeb\x7f\xd1\xbc\xfd\x75\x20\xa0\x1c\x59\x8c\x5a\xa1\x2a\x70\x64\x11\xb1\x7b\xc1\x24\x80\x28\x51\x4c\x94\xa1\x95\x64\x72\xe8\x90\x67\x38\x74\x2b\xab\x38\x46\x12\x71\xce\x19\x98\x98\xf7\x89\xd4\xfe\x2f\x2a\xc5\x61\x20\xd0\xa4\x1a\x51\x3c\x82\xc8\x18\x31\x7a\x10\xe8\x1c\xc6\x95\x5a\xa0\x82\x88\xce\x8f\x4b\x47\x85\x7e\x89\x95\x95\x52\x1e\xac\xce\x45\x57\x61\x38\x97\x2b\x62\xa5\x14\x6f\xc3\xaa\x6c\x35\x83\xc9\xa3\x1e\x30\x89\xf4\xb1\xea\x4f\x39\xde\xde\xc7\x46\x5c\x0e\x85\x41\xec\x6a\xa4\xcb\xee\x70\x9c\x57\xd9\xf4\xa1\xc3\x9c\x2a\x0a\xf0\x5d\x58\xb0\xae\xd4\xdc\xc5\x6a\xa8\x34\xfa\x23\xef\xef\x08\x39\xc3\x3d\xea\x11\x6e\x6a\xe0\x1e\xd0\x52\xa8\xc3\x6e\xc9\x1c\xfc\xd0\x0c\x4c\xea\x0d\x82\xcb\xdd\x29\x1a\xc4\x4f\x6e\xa3\x4d\xcb\x7a\x38\x77\xe5\x15\x6e\xad\xfa\x9d\x2f\x02\xb6\x39\x84\x3a\x60\x8f\x71\x9f\x92\xe5\x24\x4f\xbd\x18\x49\xd5\xef\xbf\x70\xfb\xd1\x4c\x2e\xfc\x2f\x36\xf3\x00\x31\x2e\x90\x18\xcc\xf4\x71\xb9\xe4\xf9\xbe\xcb\x5e\xff\xf3\xe7\xf8\xca\x03\x60\x66\xb3\xc9\x5a\xf9\x74\x09\x02\x57\xb6\x90\x94\xfc\x41\x35\xdc\x35\x3f\x32\x7a\xa6\xa5\xcd\x8a\x8f\xc8\x3d\xc8\x81\xc3\xec\x37\x74\x86\x61\x41\x0d\xc5\xe2\xc8\x0c\x84\x2b\x3b\x71\x58\xde\x1b\xe3\x20\x65\x2e\x76\xf4\x98\xd8\xaa\x78\xe6\xeb\xb8\x85\x0d\xa0\xd0\xf5\x57\x64\x01\x58\x55\x82\xd5\x0f\x2d\x9c\x3e\x2a\xa0\x7e\xaf\x42\xf3\x37\xd1\xb3\xaf\xda\x5b\xa9\xda\xe3\x89\x5d\xf1\xca\xa5\x12\x3d\xe7\x91\x95\x53\x21\x72\xca\x7f\xf6\x79\x59\x21\xcf\x30\x18\xfb\x78\x55\x40\x59\xc3\xf9\xf1\xdd\x58\x44\x5e\x83\x11\x5c\x2d\x1d\x91\xf6\x01\x3d\x3f\xd4\x33\x81\x66\x6c\x40\x7a\x9d\x70\x10\x58\xe6\x53\xad\x85\x11\x99\x3e\x4b\xbc\x31\xc6\x78\x9d\x79\xc5\xde\x9f\x2e\x43\xfa\x76\x84\x2f\xfd\x28\x75\x12\x48\x25\xfd\x15\x8c\x29\x6a\x91\xa4\x63\xc0\xa2\x8c\x41\x3c\xf1\xb0\xf8\xdf\x66\xeb\xbd\x14\x88\xa9\x81\xa7\x35\xc4\x41\x40\x6c\x10\x3f\x09\xbd\xb5\xd3\x7a\xee\x4b\xd5\x86\xff\x36\x03\x6b\x78\xde".to_vec(), 880 b"\x62\x01\x53\x8a\xe9\x25\xe1\x06\x09\x8e\xba\x12\x74\x87\x09\x9a\x95\xe4\x86\x62\x2b\x4b\xf9\xa6\x2e\x7b\x35\x43\xf7\x39\x99\x0f\x3b\x6f\xfd\x1a\x6e\x23\x54\x70\xb5\x1d\x10\x1c\x63\x40\x96\x99\x41\xb6\x96\x0b\x70\x98\xec\x17\xb0\xaa\xdc\x4a\xab\xe8\x3b\xb7\x6b\x00\x1c\x5b\xc3\xe0\xa2\x8b\x7c\x17\xc8\x92\xc9\xb0\x92\xb6\x70\x84\x95\x30".to_vec(), 881 b"\x4e\x01\xe5\x04\x35\xac\x00\x00\x80".to_vec(), 882 b"\x62\x01\x41\xb0\x75\x5c\x27\x46\xef\x8a\xe7\x1d\x50\x38\xb2\x13\x33\xe0\x79\x35\x1b\xc2\xb5\x79\x73\xe7\xc2\x6f\xb9\x1a\x8c\x21\x0e\xa9\x54\x17\x6c\x41\xab\xc8\x16\x57\xec\x5e\xeb\x89\x3b\xa9\x90\x8c\xff\x4d\x46\x8b\xf0\xd9\xc0\xd0\x51\xcf\x8b\x88\xf1\x5f\x1e\x9e\xc1\xb9\x1f\xe3\x06\x45\x35\x8a\x47\xe8\x9a\xf2\x4f\x19\x4c\xf8\xce\x68\x1b\x63\x34\x11\x75\xea\xe5\xb1\x0f\x38\xcc\x05\x09\x8b\x3e\x2b\x88\x84\x9d\xc5\x03\xc3\xc0\x90\x32\xe2\x45\x69\xb1\xe5\xf7\x68\x6b\x16\x90\xa0\x40\xe6\x18\x74\xd8\x68\xf3\x34\x38\x99\xf2\x6c\xb7\x1a\x35\x21\xca\x52\x56\x4c\x7f\xb2\xa3\xd5\xb8\x40\x50\x48\x3e\xdc\xdf\x0b\xf5\x54\x5a\x15\x1a\xe2\xc3\xb4\x94\xda\x3f\xb5\x34\xa2\xca\xbc\x2f\xe0\xa4\xe5\x69\xf4\xbf\x62\x4d\x15\x21\x1b\x11\xfc\x39\xaa\x86\x74\x96\x63\xfd\x07\x53\x26\xf6\x34\x72\xeb\x14\x37\x98\x0d\xf4\x68\x91\x2c\x6b\x46\x83\x88\x82\x04\x8b\x9f\xb8\x32\x73\x75\x8b\xf9\xac\x71\x42\xd1\x2d\xb4\x28\x28\xf5\x78\xe0\x32\xf3\xe1\xfc\x43\x6b\xf9\x92\xf7\x48\xfe\x7f\xc0\x17\xbd\xfd\xba\x2f\x58\x6f\xee\x84\x03\x18\xce\xb0\x9d\x8d\xeb\x22\xf1\xfc\xb1\xcf\xff\x2f\xb2\x9f\x6c\xe5\xb4\x69\xdc\xdd\x20\x93\x00\x30\xad\x56\x04\x66\x7e\xa3\x3c\x18\x4b\x43\x66\x00\x27\x1e\x1c\x09\x11\xd8\xf4\x8a\x9e\xc5\x6a\x94\xe5\xae\x0b\x8a\xbe\x84\xda\xe5\x44\x7f\x38\x1c\xe7\xbb\x03\x19\x66\xe1\x5d\x1d\xc1\xbd\x3d\xc6\xb7\xe3\xff\x7f\x8e\xff\x1e\xf6\x9e\x6f\x58\x27\x74\x65\xef\x02\x5d\xa4\xde\x27\x7f\x51\xe3\x4b\x9e\x3f\x79\x83\xbd\x1b\x8f\x0d\x77\xfb\xbc\xc5\x9f\x15\xa7\x4e\x05\x8a\x24\x97\x66\xb2\x7c\xf6\xe1\x84\x54\xdb\x39\x5e\xf6\x1b\x8f\x05\x73\x1d\xb6\x8e\xd7\x09\x9a\xc5\x92\x80".to_vec(), 883 ]; 884 885 for cur in tests { 886 let mut pck = H265Packet::default(); 887 let _ = pck.depacketize(&Bytes::from(cur))?; 888 } 889 890 Ok(()) 891 } 892