From fecbe01e06c627f2310c167203176edb65b7ae29 Mon Sep 17 00:00:00 2001 From: Maksym Khomenko Date: Tue, 9 Jan 2024 18:48:37 +0200 Subject: [PATCH] webrtcsink: make 'extensions' property usage conditional Part-of: --- net/webrtc/src/webrtcsink/imp.rs | 92 +++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 25 deletions(-) diff --git a/net/webrtc/src/webrtcsink/imp.rs b/net/webrtc/src/webrtcsink/imp.rs index 8371bd5d..5d2b5352 100644 --- a/net/webrtc/src/webrtcsink/imp.rs +++ b/net/webrtc/src/webrtcsink/imp.rs @@ -1484,33 +1484,11 @@ impl BaseWebRTCSink { return Ok(()); } - let enabled_extensions: gst::Array = payloader.property("extensions"); - let twcc = enabled_extensions - .iter() - .find(|value| { - let value = value.get::().unwrap(); - - match value.uri() { - Some(v) => v == RTP_TWCC_URI, - None => false, - } - }) - .map(|value| value.get::().unwrap()); - - if let Some(ext) = twcc { - gst::debug!(CAT, obj: payloader, "TWCC extension is already mapped to id {} by application", ext.id()); + let Some(twcc_id) = self.pick_twcc_extension_id(payloader, extension_configuration_type) + else { return Ok(()); - } - - let twcc_id = match extension_configuration_type { - ExtensionConfigurationType::Auto => utils::find_smallest_available_ext_id( - enabled_extensions - .iter() - .map(|value| value.get::().unwrap().id()), - ), - ExtensionConfigurationType::Apply { twcc_id } => twcc_id, - ExtensionConfigurationType::Skip => unreachable!(), }; + gst::debug!(CAT, obj: payloader, "Mapping TWCC extension to ID {}", twcc_id); /* We only enforce TWCC in the offer caps, once a remote description @@ -1529,6 +1507,70 @@ impl BaseWebRTCSink { Ok(()) } + fn has_connected_payloader_setup_slots(&self) -> bool { + use glib::{signal, subclass}; + + let signal_id = + subclass::signal::SignalId::lookup("payloader-setup", BaseWebRTCSink::type_()).unwrap(); + + signal::signal_has_handler_pending( + self.obj().upcast_ref::(), + signal_id, + None, + false, + ) + } + + /// Returns Some with an available ID for TWCC extension or None if it's already configured + fn pick_twcc_extension_id( + &self, + payloader: &gst::Element, + extension_configuration_type: ExtensionConfigurationType, + ) -> Option { + match extension_configuration_type { + ExtensionConfigurationType::Auto => { + // GstRTPBasePayload::extensions property is only available since GStreamer 1.24 + if !payloader.has_property("extensions", Some(gst::Array::static_type())) + && self.has_connected_payloader_setup_slots() + { + gst::warning!(CAT, "'extensions' property is not available: TWCC extension ID will default to 1. \ + Application code must ensure to pick non-conflicting IDs for any additionally configured extensions. \ + Please consider updating GStreamer to 1.24."); + return Some(1); + } + + let enabled_extensions: gst::Array = payloader.property("extensions"); + + let twcc = enabled_extensions + .iter() + .find(|value| { + let value = value.get::().unwrap(); + + match value.uri() { + Some(v) => v == RTP_TWCC_URI, + None => false, + } + }) + .map(|value| value.get::().unwrap()); + + if let Some(ext) = twcc { + gst::debug!(CAT, obj: payloader, "TWCC extension is already mapped to id {} by application", ext.id()); + return None; + } + + let ext_id = utils::find_smallest_available_ext_id( + enabled_extensions + .iter() + .map(|value| value.get::().unwrap().id()), + ); + + Some(ext_id) + } + ExtensionConfigurationType::Apply { twcc_id } => Some(twcc_id), + ExtensionConfigurationType::Skip => unreachable!(), + } + } + fn configure_payloader( &self, peer_id: &str,