rtpbin2: Implement support for reduced size RTCP (RFC 5506)

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
This commit is contained in:
Sebastian Dröge 2024-01-02 12:46:31 +02:00 committed by Matthew Waters
parent 1e4a966c92
commit e09ad990fa
3 changed files with 58 additions and 0 deletions

View file

@ -7263,6 +7263,18 @@
"type": "guint", "type": "guint",
"writable": true "writable": true
}, },
"reduced-size-rtcp": {
"blurb": "Use reduced size RTCP. Only has an effect if rtp-profile=avpf",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "false",
"mutable": "ready",
"readable": true,
"type": "gboolean",
"writable": true
},
"rtp-profile": { "rtp-profile": {
"blurb": "RTP Profile to use", "blurb": "RTP Profile to use",
"conditionally-available": false, "conditionally-available": false,

View file

@ -22,6 +22,7 @@ use crate::rtpbin2::RUNTIME;
const DEFAULT_LATENCY: gst::ClockTime = gst::ClockTime::from_mseconds(0); const DEFAULT_LATENCY: gst::ClockTime = gst::ClockTime::from_mseconds(0);
const DEFAULT_MIN_RTCP_INTERVAL: Duration = RTCP_MIN_REPORT_INTERVAL; const DEFAULT_MIN_RTCP_INTERVAL: Duration = RTCP_MIN_REPORT_INTERVAL;
const DEFAULT_REDUCED_SIZE_RTCP: bool = false;
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| { static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
gst::DebugCategory::new( gst::DebugCategory::new(
@ -65,6 +66,7 @@ struct Settings {
latency: gst::ClockTime, latency: gst::ClockTime,
min_rtcp_interval: Duration, min_rtcp_interval: Duration,
profile: Profile, profile: Profile,
reduced_size_rtcp: bool,
} }
impl Default for Settings { impl Default for Settings {
@ -73,6 +75,7 @@ impl Default for Settings {
latency: DEFAULT_LATENCY, latency: DEFAULT_LATENCY,
min_rtcp_interval: DEFAULT_MIN_RTCP_INTERVAL, min_rtcp_interval: DEFAULT_MIN_RTCP_INTERVAL,
profile: Profile::default(), profile: Profile::default(),
reduced_size_rtcp: DEFAULT_REDUCED_SIZE_RTCP,
} }
} }
} }
@ -161,6 +164,9 @@ impl BinSession {
.session .session
.set_min_rtcp_interval(settings.min_rtcp_interval); .set_min_rtcp_interval(settings.min_rtcp_interval);
inner.session.set_profile(settings.profile.into()); inner.session.set_profile(settings.profile.into());
inner
.session
.set_reduced_size_rtcp(settings.reduced_size_rtcp);
Self { Self {
id, id,
inner: Arc::new(Mutex::new(inner)), inner: Arc::new(Mutex::new(inner)),
@ -1066,6 +1072,12 @@ impl ObjectImpl for RtpBin2 {
.default_value(Profile::default()) .default_value(Profile::default())
.mutable_ready() .mutable_ready()
.build(), .build(),
glib::ParamSpecBoolean::builder("reduced-size-rtcp")
.nick("Reduced Size RTCP")
.blurb("Use reduced size RTCP. Only has an effect if rtp-profile=avpf")
.default_value(DEFAULT_REDUCED_SIZE_RTCP)
.mutable_ready()
.build(),
] ]
}); });
@ -1097,6 +1109,10 @@ impl ObjectImpl for RtpBin2 {
let mut settings = self.settings.lock().unwrap(); let mut settings = self.settings.lock().unwrap();
settings.profile = value.get::<Profile>().expect("Type checked upstream"); settings.profile = value.get::<Profile>().expect("Type checked upstream");
} }
"reduced-size-rtcp" => {
let mut settings = self.settings.lock().unwrap();
settings.reduced_size_rtcp = value.get::<bool>().expect("Type checked upstream");
}
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
@ -1119,6 +1135,10 @@ impl ObjectImpl for RtpBin2 {
let settings = self.settings.lock().unwrap(); let settings = self.settings.lock().unwrap();
settings.profile.to_value() settings.profile.to_value()
} }
"reduced-size-rtcp" => {
let settings = self.settings.lock().unwrap();
settings.reduced_size_rtcp.to_value()
}
_ => unimplemented!(), _ => unimplemented!(),
} }
} }

View file

@ -72,6 +72,7 @@ pub struct Session {
// settings // settings
min_rtcp_interval: Duration, min_rtcp_interval: Duration,
profile: RtpProfile, profile: RtpProfile,
reduced_size_rtcp: bool,
// state // state
local_senders: HashMap<u32, LocalSendSource>, local_senders: HashMap<u32, LocalSendSource>,
local_receivers: HashMap<u32, LocalReceiveSource>, local_receivers: HashMap<u32, LocalReceiveSource>,
@ -162,6 +163,7 @@ impl Session {
Self { Self {
min_rtcp_interval: RTCP_MIN_REPORT_INTERVAL, min_rtcp_interval: RTCP_MIN_REPORT_INTERVAL,
profile: RtpProfile::default(), profile: RtpProfile::default(),
reduced_size_rtcp: false,
local_senders: HashMap::new(), local_senders: HashMap::new(),
// also known as remote_senders // also known as remote_senders
local_receivers: HashMap::new(), local_receivers: HashMap::new(),
@ -197,6 +199,11 @@ impl Session {
self.profile = profile; self.profile = profile;
} }
/// Set usage of reduced size RTCP
pub fn set_reduced_size_rtcp(&mut self, reduced_size_rtcp: bool) {
self.reduced_size_rtcp = reduced_size_rtcp;
}
fn n_members(&self) -> usize { fn n_members(&self) -> usize {
self.bye_state self.bye_state
.as_ref() .as_ref()
@ -759,6 +766,11 @@ impl Session {
minimum: bool, // RFC 4585 minimum: bool, // RFC 4585
ssrcs_reported: &mut Vec<u32>, ssrcs_reported: &mut Vec<u32>,
) -> CompoundBuilder<'a> { ) -> CompoundBuilder<'a> {
// Don't include in an early reduced-size RTCP packet
if minimum && self.reduced_size_rtcp_allowed() {
return rtcp;
}
let ntp_time = system_time_to_ntp_time_u64(ntp_now); let ntp_time = system_time_to_ntp_time_u64(ntp_now);
if self if self
.local_senders .local_senders
@ -844,6 +856,10 @@ impl Session {
rtcp rtcp
} }
fn reduced_size_rtcp_allowed(&self) -> bool {
self.reduced_size_rtcp && matches!(self.profile, RtpProfile::Avpf)
}
fn have_ssrc(&self, ssrc: u32) -> bool { fn have_ssrc(&self, ssrc: u32) -> bool {
self.local_senders.contains_key(&ssrc) self.local_senders.contains_key(&ssrc)
|| self.local_receivers.contains_key(&ssrc) || self.local_receivers.contains_key(&ssrc)
@ -882,6 +898,11 @@ impl Session {
minimum: bool, // RFC 4585 minimum: bool, // RFC 4585
ssrcs_reported: &mut Vec<u32>, ssrcs_reported: &mut Vec<u32>,
) -> CompoundBuilder<'a> { ) -> CompoundBuilder<'a> {
// Don't include in an early reduced-size RTCP packet
if minimum && self.reduced_size_rtcp_allowed() {
return rtcp;
}
if self if self
.local_senders .local_senders
.values() .values()
@ -924,6 +945,11 @@ impl Session {
rtcp: CompoundBuilder<'a>, rtcp: CompoundBuilder<'a>,
minimum: bool, // RFC 4585 minimum: bool, // RFC 4585
) -> CompoundBuilder<'a> { ) -> CompoundBuilder<'a> {
// Don't include in an early reduced-size RTCP packet
if minimum && self.reduced_size_rtcp_allowed() {
return rtcp;
}
let mut sdes = Sdes::builder(); let mut sdes = Sdes::builder();
let mut have_chunk = false; let mut have_chunk = false;
for sender in self.local_senders.values() { for sender in self.local_senders.values() {