From 82f6accc31a9d2f63da4a2b592d6c7032232fb42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Laignel?= Date: Mon, 11 Mar 2024 13:03:26 +0100 Subject: [PATCH] webrtc: SessionDescription: access the inner SDPMessage as & or &mut `WebRTCSessionDescription` owns its `SDPMessage`. The `sdp()` accessor used to return a copy of the `SDPMessage` which prevented the user from getting a ref and by extension from getting a mutable ref for in-place modification. This commit makes the accessor return a reference to the inner `SDPMessage` and adds a mutable accessor. Previous behaviour (getting an owned copy of the `SDPMessage`) is available by calling `to_owned()` on the reference returned by `sdp()`. Users who wish to change the type of `WebRTCSessionDescription` can call `set_type()`. Part-of: --- .../src/web_rtc_session_description.rs | 59 +++++++++++++++++-- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/gstreamer-webrtc/src/web_rtc_session_description.rs b/gstreamer-webrtc/src/web_rtc_session_description.rs index b884da5df..44c9431eb 100644 --- a/gstreamer-webrtc/src/web_rtc_session_description.rs +++ b/gstreamer-webrtc/src/web_rtc_session_description.rs @@ -1,7 +1,5 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use std::mem; - use glib::translate::*; use crate::{WebRTCSDPType, WebRTCSessionDescription}; @@ -11,10 +9,9 @@ impl WebRTCSessionDescription { pub fn new(type_: WebRTCSDPType, sdp: gst_sdp::SDPMessage) -> WebRTCSessionDescription { skip_assert_initialized!(); unsafe { - let mut sdp = mem::ManuallyDrop::new(sdp); from_glib_full(ffi::gst_webrtc_session_description_new( type_.into_glib(), - sdp.to_glib_none_mut().0, + sdp.into_glib_ptr(), )) } } @@ -24,8 +21,58 @@ impl WebRTCSessionDescription { unsafe { from_glib((*self.as_ptr()).type_) } } + // rustdoc-stripper-ignore-next + /// Changes the type of this Session Description to the specified variant. + pub fn set_type(&mut self, type_: WebRTCSDPType) { + unsafe { + (*self.as_ptr()).type_ = type_.into_glib(); + } + } + #[doc(alias = "get_sdp")] - pub fn sdp(&self) -> gst_sdp::SDPMessage { - unsafe { from_glib_none((*self.as_ptr()).sdp) } + pub fn sdp(&self) -> &gst_sdp::SDPMessageRef { + unsafe { &*((*self.as_ptr()).sdp as *const gst_sdp::SDPMessageRef) } + } + + pub fn sdp_mut(&mut self) -> &mut gst_sdp::SDPMessageRef { + unsafe { &mut *((*self.as_ptr()).sdp as *mut gst_sdp::SDPMessageRef) } + } +} + +#[cfg(test)] +mod tests { + use crate::WebRTCSDPType; + use gst_sdp::SDPMessage; + + #[test] + fn change_type() { + gst::init().unwrap(); + + let mut desc = + crate::WebRTCSessionDescription::new(crate::WebRTCSDPType::Offer, SDPMessage::new()); + assert_eq!(desc.type_(), WebRTCSDPType::Offer); + + desc.set_type(WebRTCSDPType::Rollback); + assert_eq!(desc.type_(), WebRTCSDPType::Rollback); + } + + #[test] + fn update_inner_msg() { + gst::init().unwrap(); + + let mut sdp = SDPMessage::new(); + sdp.set_information("init"); + + let mut desc = crate::WebRTCSessionDescription::new(WebRTCSDPType::Offer, sdp); + assert_eq!(desc.sdp().information(), Some("init")); + + let sdp_owned = desc.sdp().to_owned(); + + // update inner sdp message + desc.sdp_mut().set_information("update"); + assert_eq!(desc.sdp().information(), Some("update")); + + // previously acquired owned sdp message unchanged + assert_eq!(sdp_owned.information(), Some("init")); } }