use super::*;
#[test]
fn test_vp9_packet_unmarshal() -> Result<()> {
let tests = vec![
(
"Empty",
Bytes::from_static(&[]),
Vp9Packet::default(),
Bytes::new(),
Some(Error::ErrShortPacket),
),
(
"NonFlexible",
Bytes::from_static(&[0x00, 0xAA]),
Vp9Packet::default(),
Bytes::from_static(&[0xAA]),
None,
),
(
"NonFlexiblePictureID",
Bytes::from_static(&[0x80, 0x02, 0xAA]),
Vp9Packet {
i: true,
picture_id: 0x02,
..Default::default()
},
Bytes::from_static(&[0xAA]),
None,
),
(
"NonFlexiblePictureIDExt",
Bytes::from_static(&[0x80, 0x81, 0xFF, 0xAA]),
Vp9Packet {
i: true,
picture_id: 0x01FF,
..Default::default()
},
Bytes::from_static(&[0xAA]),
None,
),
(
"NonFlexiblePictureIDExt_ShortPacket0",
Bytes::from_static(&[0x80, 0x81]),
Vp9Packet::default(),
Bytes::new(),
Some(Error::ErrShortPacket),
),
(
"NonFlexiblePictureIDExt_ShortPacket1",
Bytes::from_static(&[0x80]),
Vp9Packet::default(),
Bytes::new(),
Some(Error::ErrShortPacket),
),
(
"NonFlexibleLayerIndicePictureID",
Bytes::from_static(&[0xA0, 0x02, 0x23, 0x01, 0xAA]),
Vp9Packet {
i: true,
l: true,
picture_id: 0x02,
tid: 0x01,
sid: 0x01,
d: true,
tl0picidx: 0x01,
..Default::default()
},
Bytes::from_static(&[0xAA]),
None,
),
(
"FlexibleLayerIndicePictureID",
Bytes::from_static(&[0xB0, 0x02, 0x23, 0x01, 0xAA]),
Vp9Packet {
f: true,
i: true,
l: true,
picture_id: 0x02,
tid: 0x01,
sid: 0x01,
d: true,
..Default::default()
},
Bytes::from_static(&[0x01, 0xAA]),
None,
),
(
"NonFlexibleLayerIndicePictureID_ShortPacket0",
Bytes::from_static(&[0xA0, 0x02, 0x23]),
Vp9Packet::default(),
Bytes::new(),
Some(Error::ErrShortPacket),
),
(
"NonFlexibleLayerIndicePictureID_ShortPacket1",
Bytes::from_static(&[0xA0, 0x02]),
Vp9Packet::default(),
Bytes::new(),
Some(Error::ErrShortPacket),
),
(
"FlexiblePictureIDRefIndex",
Bytes::from_static(&[0xD0, 0x02, 0x03, 0x04, 0xAA]),
Vp9Packet {
i: true,
p: true,
f: true,
picture_id: 0x02,
pdiff: vec![0x01, 0x02],
..Default::default()
},
Bytes::from_static(&[0xAA]),
None,
),
(
"FlexiblePictureIDRefIndex_TooManyPDiff",
Bytes::from_static(&[0xD0, 0x02, 0x03, 0x05, 0x07, 0x09, 0x10, 0xAA]),
Vp9Packet::default(),
Bytes::new(),
Some(Error::ErrTooManyPDiff),
),
(
"FlexiblePictureIDRefIndexNoPayload",
Bytes::from_static(&[0xD0, 0x02, 0x03, 0x04]),
Vp9Packet {
i: true,
p: true,
f: true,
picture_id: 0x02,
pdiff: vec![0x01, 0x02],
..Default::default()
},
Bytes::from_static(&[]),
None,
),
(
"FlexiblePictureIDRefIndex_ShortPacket0",
Bytes::from_static(&[0xD0, 0x02, 0x03]),
Vp9Packet::default(),
Bytes::new(),
Some(Error::ErrShortPacket),
),
(
"FlexiblePictureIDRefIndex_ShortPacket1",
Bytes::from_static(&[0xD0, 0x02]),
Vp9Packet::default(),
Bytes::new(),
Some(Error::ErrShortPacket),
),
(
"FlexiblePictureIDRefIndex_ShortPacket2",
Bytes::from_static(&[0xD0]),
Vp9Packet::default(),
Bytes::new(),
Some(Error::ErrShortPacket),
),
(
"ScalabilityStructureResolutionsNoPayload",
Bytes::from_static(&[
0x0A,
(1 << 5) | (1 << 4), (640 >> 8) as u8,
(640 & 0xff) as u8,
(360 >> 8) as u8,
(360 & 0xff) as u8,
(1280 >> 8) as u8,
(1280 & 0xff) as u8,
(720 >> 8) as u8,
(720 & 0xff) as u8,
]),
Vp9Packet {
b: true,
v: true,
ns: 1,
y: true,
g: false,
ng: 0,
width: vec![640, 1280],
height: vec![360, 720],
..Default::default()
},
Bytes::new(),
None,
),
(
"ScalabilityStructureNoPayload",
Bytes::from_static(&[
0x0A,
(1 << 5) | (0 << 4) | (1 << 3), 2,
(0 << 5) | (1 << 4) | (0 << 2), (2 << 5) | (0 << 4) | (1 << 2), 33,
]),
Vp9Packet {
b: true,
v: true,
ns: 1,
y: false,
g: true,
ng: 2,
pgtid: vec![0, 2],
pgu: vec![true, false],
pgpdiff: vec![vec![], vec![33]],
..Default::default()
},
Bytes::new(),
None,
),
];
for (name, b, pkt, expected, err) in tests {
let mut p = Vp9Packet::default();
if let Some(expected) = err {
if let Err(actual) = p.depacketize(&b) {
assert_eq!(
expected, actual,
"{}: expected {}, but got {}",
name, expected, actual
);
} else {
assert!(false, "{}: expected error, but got passed", name);
}
} else {
let payload = p.depacketize(&b)?;
assert_eq!(pkt, p, "{}: expected {:?}, but got {:?}", name, pkt, p);
assert_eq!(payload, expected);
}
}
Ok(())
}
#[test]
fn test_vp9_payloader_payload() -> Result<()> {
let mut r0 = 8692;
let mut rands = vec![];
for _ in 0..10 {
rands.push(vec![(r0 >> 8) as u8 | 0x80, (r0 & 0xFF) as u8]);
r0 += 1;
}
let tests = vec![
("NilPayload", vec![Bytes::new()], 100, vec![]),
("SmallMTU", vec![Bytes::from(vec![0x00, 0x00])], 1, vec![]),
(
"NegativeMTU",
vec![Bytes::from(vec![0x00, 0x00])],
0,
vec![],
),
(
"OnePacket",
vec![Bytes::from(vec![0x01, 0x02])],
10,
vec![Bytes::from(vec![
0x9C,
rands[0][0],
rands[0][1],
0x01,
0x02,
])],
),
(
"TwoPackets",
vec![Bytes::from(vec![0x01, 0x02])],
4,
vec![
Bytes::from(vec![0x98, rands[0][0], rands[0][1], 0x01]),
Bytes::from(vec![0x94, rands[0][0], rands[0][1], 0x02]),
],
),
(
"ThreePackets",
vec![Bytes::from(vec![0x01, 0x02, 0x03])],
4,
vec![
Bytes::from(vec![0x98, rands[0][0], rands[0][1], 0x01]),
Bytes::from(vec![0x90, rands[0][0], rands[0][1], 0x02]),
Bytes::from(vec![0x94, rands[0][0], rands[0][1], 0x03]),
],
),
(
"TwoFramesFourPackets",
vec![Bytes::from(vec![0x01, 0x02, 0x03]), Bytes::from(vec![0x04])],
5,
vec![
Bytes::from(vec![0x98, rands[0][0], rands[0][1], 0x01, 0x02]),
Bytes::from(vec![0x94, rands[0][0], rands[0][1], 0x03]),
Bytes::from(vec![0x9C, rands[1][0], rands[1][1], 0x04]),
],
),
];
for (name, bs, mtu, expected) in tests {
let mut pck = Vp9Payloader {
initial_picture_id_fn: Some(Arc::new(|| -> u16 { 8692 })),
..Default::default()
};
let mut actual = vec![];
for b in &bs {
actual.extend(pck.payload(mtu, b)?);
}
assert_eq!(expected, actual, "{}: Payloaded packet", name);
}
{
let mut pck = Vp9Payloader {
initial_picture_id_fn: Some(Arc::new(|| -> u16 { 8692 })),
..Default::default()
};
let mut p_prev = Vp9Packet::default();
for i in 0..0x8000 {
let res = pck.payload(4, &Bytes::from_static(&[0x01]))?;
let mut p = Vp9Packet::default();
p.depacketize(&res[0])?;
if i > 0 {
if p_prev.picture_id == 0x7FFF {
assert_eq!(
p.picture_id, 0,
"Picture ID next to 0x7FFF must be 0, got {}",
p.picture_id
);
} else if p_prev.picture_id + 1 != p.picture_id {
assert!(
false,
"Picture ID next must be incremented by 1: {} -> {}",
p_prev.picture_id, p.picture_id,
);
}
}
p_prev = p;
}
}
Ok(())
}
#[test]
fn test_vp9_partition_head_checker_is_partition_head() -> Result<()> {
let vp9 = Vp9Packet::default();
assert!(
!vp9.is_partition_head(&Bytes::new()),
"Small packet should not be the head of a new partition"
);
assert!(
vp9.is_partition_head(&Bytes::from_static(&[0x18, 0x00, 0x00])),
"VP9 RTP packet with B flag should be head of a new partition"
);
assert!(
!vp9.is_partition_head(&Bytes::from_static(&[0x10, 0x00, 0x00])),
"VP9 RTP packet without B flag should not be head of a new partition"
);
Ok(())
}