Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Unreleased

* Add RFC 2198 RED (redundant audio) support for all audio codecs #982
* Preserve the RFC 6464 audio-level voice activity bit when serializing #1032

# 0.23.1

Expand Down
33 changes: 32 additions & 1 deletion src/rtp/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -664,7 +664,11 @@ impl Extension {
AudioLevel => {
let v1 = ev.audio_level?;
let v2 = ev.voice_activity?;
buf[0] = if v2 { 0x80 } else { 0 } | (-(0x7f & v1) as u8);
// `v1` is negative, so masking it before negating leaves the
// sign bit in place: for -37 the expression `-(0x7f & v1)`
// yields 0xA5, which already has bit 7 set. Taking the
// magnitude first keeps the sign out of the V bit.
buf[0] = if v2 { 0x80 } else { 0 } | (v1.unsigned_abs() & 0x7f);
Some(1)
}
TransmissionTimeOffset => {
Expand Down Expand Up @@ -1580,4 +1584,31 @@ mod test {
vec![(12, &VideoOrientation), (14, &TransportSequenceNumber)]
);
}

#[test]
fn audio_level_round_trip() {
// The V bit (voice activity) must survive serialization for every
// level on the scale, not just when it is set.
let mut exts = ExtensionMap::empty();
exts.set(1, Extension::AudioLevel);

for level in -127..=0 {
for voice_activity in [false, true] {
let ev = ExtensionValues {
audio_level: Some(level),
voice_activity: Some(voice_activity),
..Default::default()
};

let mut buf = vec![0_u8; 8];
exts.write_to(&mut buf[..], &ev, ExtensionsForm::OneByte);

let mut ev2 = ExtensionValues::default();
exts.parse(&buf, ExtensionsForm::OneByte, &mut ev2);

assert_eq!(ev2.audio_level, Some(level));
assert_eq!(ev2.voice_activity, Some(voice_activity));
}
}
}
}
18 changes: 12 additions & 6 deletions src/rtp/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,20 +465,24 @@ mod test {
}

let mut exts = ExtensionMap::empty();
// The expected bytes below carry the level with the V bit CLEAR, which
// is what `voice_activity: Some(false)` above asks for. They used to
// have bit 7 set (170 = 0xAA rather than 42 = 0x2A) because the
// serializer let the sign of the negative level spill into that bit.
exts.set(3, Extension::AudioLevel);

let buf1 = mk_header(47_000, 10_000, -42, false, &exts);
let buf2 = mk_header(47_001, 12_000, -43, true, &exts);
let buf3 = mk_header(47_002, 14_000, -44, false, &exts);

let p1 = &[
144, 33, 183, 152, 0, 0, 39, 16, 0, 0, 0, 44, 0xBE, 0xDE, 0, 1, 48, 170, 0, 0,
144, 33, 183, 152, 0, 0, 39, 16, 0, 0, 0, 44, 0xBE, 0xDE, 0, 1, 48, 42, 0, 0,
];
let p2 = &[
144, 161, 183, 153, 0, 0, 46, 224, 0, 0, 0, 44, 0xBE, 0xDE, 0, 1, 48, 171, 0, 0,
144, 161, 183, 153, 0, 0, 46, 224, 0, 0, 0, 44, 0xBE, 0xDE, 0, 1, 48, 43, 0, 0,
];
let p3 = &[
144, 33, 183, 154, 0, 0, 54, 176, 0, 0, 0, 44, 0xBE, 0xDE, 0, 1, 48, 172, 0, 0,
144, 33, 183, 154, 0, 0, 54, 176, 0, 0, 0, 44, 0xBE, 0xDE, 0, 1, 48, 44, 0, 0,
];

assert_eq!(&buf1, p1);
Expand Down Expand Up @@ -510,6 +514,8 @@ mod test {
}

let mut exts = ExtensionMap::empty();
// Same correction as above: the V bit is clear because the header
// asks for `voice_activity: Some(false)`.
// An ID larger than 14 forces the 2-byte header extension form
exts.set(15, Extension::AudioLevel);

Expand All @@ -518,13 +524,13 @@ mod test {
let buf3 = mk_header(47_002, 14_000, -44, false, &exts);

let p1 = &[
144, 33, 183, 152, 0, 0, 39, 16, 0, 0, 0, 44, 0x10, 0x00, 0, 1, 15, 1, 170, 0,
144, 33, 183, 152, 0, 0, 39, 16, 0, 0, 0, 44, 0x10, 0x00, 0, 1, 15, 1, 42, 0,
];
let p2 = &[
144, 161, 183, 153, 0, 0, 46, 224, 0, 0, 0, 44, 0x10, 0x00, 0, 1, 15, 1, 171, 0,
144, 161, 183, 153, 0, 0, 46, 224, 0, 0, 0, 44, 0x10, 0x00, 0, 1, 15, 1, 43, 0,
];
let p3 = &[
144, 33, 183, 154, 0, 0, 54, 176, 0, 0, 0, 44, 0x10, 0x00, 0, 1, 15, 1, 172, 0,
144, 33, 183, 154, 0, 0, 54, 176, 0, 0, 0, 44, 0x10, 0x00, 0, 1, 15, 1, 44, 0,
];

assert_eq!(&buf1, p1);
Expand Down
Loading