Add generation of CCFB in offer (RFC8888 support)

Bug: webrtc:42225697
Change-Id: I288a808c4aae852212b09fdf9551e20fe3066e39
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/367205
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43341}
This commit is contained in:
Harald Alvestrand 2024-10-31 16:35:03 +00:00 committed by WebRTC LUCI CQ
parent 24c35756f4
commit a25c1c061c
6 changed files with 66 additions and 1 deletions

View File

@ -2213,6 +2213,7 @@ if (rtc_include_tests && !build_with_chromium) {
rtc_test("peerconnection_unittests") {
testonly = true
sources = [
"congestion_control_integrationtest.cc",
"data_channel_integrationtest.cc",
"data_channel_unittest.cc",
"dtmf_sender_unittest.cc",

View File

@ -14,6 +14,7 @@ include_rules = [
"+net/dcsctp",
"+p2p",
"+system_wrappers",
"+absl/strings/str_cat.h",
]
specific_include_rules = {

View File

@ -0,0 +1,44 @@
/*
* Copyright 2024 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// This file contains tests that verify that congestion control options
// are correctly negotiated in the SDP offer/answer.
#include <string>
#include "absl/strings/str_cat.h"
#include "api/peer_connection_interface.h"
#include "pc/test/integration_test_helpers.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"
namespace webrtc {
using testing::HasSubstr;
class PeerConnectionCongestionControlTest
: public PeerConnectionIntegrationBaseTest {
public:
PeerConnectionCongestionControlTest()
: PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
};
TEST_F(PeerConnectionCongestionControlTest, OfferContainsCcfbIfEnabled) {
test::ScopedFieldTrials trials(
"WebRTC-RFC8888CongestionControlFeedback/Enabled/");
ASSERT_TRUE(CreatePeerConnectionWrappers());
caller()->AddAudioVideoTracks();
auto offer = caller()->CreateOfferAndWait();
std::string offer_str = absl::StrCat(*offer);
EXPECT_THAT(offer_str, HasSubstr("a=rtcp-fb:* ack ccfb\r\n"));
}
} // namespace webrtc

View File

@ -1974,7 +1974,10 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForOffer(
} else {
content_description = std::make_unique<VideoContentDescription>();
}
// RFC 8888 support.
content_description->set_rtcp_fb_ack_ccfb(
transport_desc_factory_->trials().IsEnabled(
"WebRTC-RFC8888CongestionControlFeedback"));
auto error = CreateMediaContentOffer(
media_description_options, session_options, codecs_to_include,
header_extensions, ssrc_generator(), current_streams,

View File

@ -114,6 +114,13 @@ class MediaContentDescription {
remote_estimate_ = remote_estimate;
}
// Support of RFC 8888 feedback messages.
// This is a transport-wide property, but is signalled in SDP
// at the m-line level; its mux category is IDENTICAL-PER-PT,
// and only wildcard is allowed. RFC 8888 section 6.
bool rtcp_fb_ack_ccfb() const { return rtcp_fb_ack_ccfb_; }
void set_rtcp_fb_ack_ccfb(bool enable) { rtcp_fb_ack_ccfb_ = enable; }
int bandwidth() const { return bandwidth_; }
void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; }
std::string bandwidth_type() const { return bandwidth_type_; }
@ -257,6 +264,7 @@ class MediaContentDescription {
bool rtcp_mux_ = false;
bool rtcp_reduced_size_ = false;
bool remote_estimate_ = false;
bool rtcp_fb_ack_ccfb_ = false;
int bandwidth_ = kAutoBandwidth;
std::string bandwidth_type_ = kApplicationSpecificBandwidth;

View File

@ -1947,6 +1947,14 @@ void BuildRtpmap(const MediaContentDescription* media_desc,
AddAttributeLine(kCodecParamPTime, ptime, message);
}
}
if (media_desc->rtcp_fb_ack_ccfb()) {
// RFC 8888 section 6
rtc::StringBuilder os;
InitAttrLine(kAttributeRtcpFb, &os);
os << kSdpDelimiterColon;
os << "* ack ccfb";
AddLine(os.str(), message);
}
}
void BuildCandidate(const std::vector<Candidate>& candidates,