Adjust RTP header extension overhead for RRID

which needs to be taken into account separately if the
primary SSRC has been acknowledged but the RTX SSRC has
not.

If nothing has been acknowledged, mid+rid are sent on the primary SSRC and mid+rrid are sent on the RTX SSRC.
If the primary SSRC has been acknowledged, no extensions are sent on the primary SSRC and mid+rrid are sent on the RTX SSRC.
If both the primary SSRC and the RTX SSRC have been ack'd, no extensions are sent on either primary or RTX SSRC.

BUG=webrtc:13896

Change-Id: Ice251fae23a881ee9c9edc71b5d5c45a32ac76d2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/288980
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Philipp Hancke <phancke@microsoft.com>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38949}
This commit is contained in:
Philipp Hancke 2022-12-22 17:28:26 +01:00 committed by WebRTC LUCI CQ
parent b3c8327850
commit 4e83af3a9a
2 changed files with 49 additions and 8 deletions

View File

@ -113,6 +113,7 @@ bool IsNonVolatile(RTPExtensionType type) {
case kRtpExtensionTransportSequenceNumber: case kRtpExtensionTransportSequenceNumber:
case kRtpExtensionTransportSequenceNumber02: case kRtpExtensionTransportSequenceNumber02:
case kRtpExtensionRtpStreamId: case kRtpExtensionRtpStreamId:
case kRtpExtensionRepairedRtpStreamId:
case kRtpExtensionMid: case kRtpExtensionMid:
case kRtpExtensionGenericFrameDescriptor00: case kRtpExtensionGenericFrameDescriptor00:
case kRtpExtensionGenericFrameDescriptor02: case kRtpExtensionGenericFrameDescriptor02:
@ -124,7 +125,6 @@ bool IsNonVolatile(RTPExtensionType type) {
case kRtpExtensionVideoContentType: case kRtpExtensionVideoContentType:
case kRtpExtensionVideoLayersAllocation: case kRtpExtensionVideoLayersAllocation:
case kRtpExtensionVideoTiming: case kRtpExtensionVideoTiming:
case kRtpExtensionRepairedRtpStreamId:
case kRtpExtensionColorSpace: case kRtpExtensionColorSpace:
case kRtpExtensionVideoFrameTrackingId: case kRtpExtensionVideoFrameTrackingId:
return false; return false;
@ -747,20 +747,23 @@ void RTPSender::UpdateHeaderSizes() {
rtp_header_length + RtpHeaderExtensionSize(kFecOrPaddingExtensionSizes, rtp_header_length + RtpHeaderExtensionSize(kFecOrPaddingExtensionSizes,
rtp_header_extension_map_); rtp_header_extension_map_);
// RtpStreamId and Mid are treated specially in that we check if they // RtpStreamId, Mid and RepairedRtpStreamId are treated specially in that
// currently are being sent. RepairedRtpStreamId is ignored because it is sent // we check if they currently are being sent. RepairedRtpStreamId can be
// instead of RtpStreamId on rtx packets and require the same size. // sent instead of RtpStreamID on RTX packets and may share the same space.
// When the primary SSRC has already been acked but the RTX SSRC has not
// yet been acked, RepairedRtpStreamId needs to be taken into account
// separately.
const bool send_mid_rid_on_rtx = const bool send_mid_rid_on_rtx =
rtx_ssrc_.has_value() && !rtx_ssrc_has_acked_; rtx_ssrc_.has_value() &&
const bool send_mid_rid = (always_send_mid_and_rid_ || !rtx_ssrc_has_acked_);
always_send_mid_and_rid_ || !ssrc_has_acked_ || send_mid_rid_on_rtx; const bool send_mid_rid = always_send_mid_and_rid_ || !ssrc_has_acked_;
std::vector<RtpExtensionSize> non_volatile_extensions; std::vector<RtpExtensionSize> non_volatile_extensions;
for (auto& extension : for (auto& extension :
audio_configured_ ? AudioExtensionSizes() : VideoExtensionSizes()) { audio_configured_ ? AudioExtensionSizes() : VideoExtensionSizes()) {
if (IsNonVolatile(extension.type)) { if (IsNonVolatile(extension.type)) {
switch (extension.type) { switch (extension.type) {
case RTPExtensionType::kRtpExtensionMid: case RTPExtensionType::kRtpExtensionMid:
if (send_mid_rid && !mid_.empty()) { if ((send_mid_rid || send_mid_rid_on_rtx) && !mid_.empty()) {
non_volatile_extensions.push_back(extension); non_volatile_extensions.push_back(extension);
} }
break; break;
@ -769,6 +772,11 @@ void RTPSender::UpdateHeaderSizes() {
non_volatile_extensions.push_back(extension); non_volatile_extensions.push_back(extension);
} }
break; break;
case RTPExtensionType::kRtpExtensionRepairedRtpStreamId:
if (send_mid_rid_on_rtx && !send_mid_rid && !rid_.empty()) {
non_volatile_extensions.push_back(extension);
}
break;
default: default:
non_volatile_extensions.push_back(extension); non_volatile_extensions.push_back(extension);
} }

View File

@ -921,6 +921,39 @@ TEST_F(RtpSenderTest, CountMidOnlyUntilAcked) {
EXPECT_EQ(rtp_sender_->ExpectedPerPacketOverhead(), 12u); EXPECT_EQ(rtp_sender_->ExpectedPerPacketOverhead(), 12u);
} }
TEST_F(RtpSenderTest, CountMidRidRridUntilAcked) {
RtpRtcpInterface::Configuration config = GetDefaultConfig();
CreateSender(config);
// Base RTP overhead is 12B and we use RTX which has an additional 2 bytes
// overhead.
EXPECT_EQ(rtp_sender_->ExpectedPerPacketOverhead(), 14u);
rtp_sender_->RegisterRtpHeaderExtension(RtpMid::Uri(), kMidExtensionId);
// Counted only if set.
EXPECT_EQ(rtp_sender_->ExpectedPerPacketOverhead(), 14u);
rtp_sender_->SetMid("foo");
EXPECT_EQ(rtp_sender_->ExpectedPerPacketOverhead(), 38u);
rtp_sender_->RegisterRtpHeaderExtension(RtpStreamId::Uri(), kRidExtensionId);
EXPECT_EQ(rtp_sender_->ExpectedPerPacketOverhead(), 54u);
// mid/rrid may be shared with mid/rid when both are active.
rtp_sender_->RegisterRtpHeaderExtension(RepairedRtpStreamId::Uri(),
kRepairedRidExtensionId);
EXPECT_EQ(rtp_sender_->ExpectedPerPacketOverhead(), 54u);
// Ack received, mid/rid no longer sent but we still need space for
// mid/rrid which can no longer be shared with mid/rid.
rtp_sender_->OnReceivedAckOnSsrc(0);
EXPECT_EQ(rtp_sender_->ExpectedPerPacketOverhead(), 54u);
// Ack received for RTX, no need to send RRID anymore.
rtp_sender_->OnReceivedAckOnRtxSsrc(0);
EXPECT_EQ(rtp_sender_->ExpectedPerPacketOverhead(), 14u);
}
TEST_F(RtpSenderTest, DontCountVolatileExtensionsIntoOverhead) { TEST_F(RtpSenderTest, DontCountVolatileExtensionsIntoOverhead) {
RtpRtcpInterface::Configuration config = GetDefaultConfig(); RtpRtcpInterface::Configuration config = GetDefaultConfig();
config.rtx_send_ssrc = {}; config.rtx_send_ssrc = {};