summaryrefslogtreecommitdiff
path: root/subprojects/gst-examples
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2023-01-19 20:38:12 +0200
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>2023-01-20 11:36:57 +0000
commit083b9f2a6e3af55cdaf1b45abd63ca993851880e (patch)
treea756e20dbd0722a6a2886c04e9aa82ec39649e17 /subprojects/gst-examples
parent8eeaeab6af9eca94a0646564d627942d728d9f24 (diff)
downloadgstreamer-083b9f2a6e3af55cdaf1b45abd63ca993851880e.tar.gz
examples: webrtc: sendrecv: rust: Use the correct payload types if the remote is the offerer
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3758>
Diffstat (limited to 'subprojects/gst-examples')
-rw-r--r--subprojects/gst-examples/webrtc/sendrecv/gst-rust/src/main.rs107
1 files changed, 87 insertions, 20 deletions
diff --git a/subprojects/gst-examples/webrtc/sendrecv/gst-rust/src/main.rs b/subprojects/gst-examples/webrtc/sendrecv/gst-rust/src/main.rs
index c06d777906..ef613cdfb0 100644
--- a/subprojects/gst-examples/webrtc/sendrecv/gst-rust/src/main.rs
+++ b/subprojects/gst-examples/webrtc/sendrecv/gst-rust/src/main.rs
@@ -115,8 +115,8 @@ impl App {
> {
// Create the GStreamer pipeline
let pipeline = gst::parse_launch(
- "videotestsrc pattern=ball is-live=true ! vp8enc deadline=1 ! rtpvp8pay pt=96 ! webrtcbin. \
- audiotestsrc is-live=true ! opusenc ! rtpopuspay pt=97 ! application/x-rtp,encoding-name=OPUS ! webrtcbin. \
+ "videotestsrc pattern=ball is-live=true ! vp8enc deadline=1 ! rtpvp8pay name=vpay pt=96 ! webrtcbin. \
+ audiotestsrc is-live=true ! opusenc perfect-timestamp=true ! rtpopuspay name=apay pt=97 ! application/x-rtp,encoding-name=OPUS ! webrtcbin. \
webrtcbin name=webrtcbin"
)?;
@@ -200,24 +200,20 @@ impl App {
}
});
- // Asynchronously set the pipeline to Playing
- app.pipeline.call_async(|pipeline| {
- // If this fails, post an error on the bus so we exit
- if pipeline.set_state(gst::State::Playing).is_err() {
- gst::element_error!(
- pipeline,
- gst::LibraryError::Failed,
- ("Failed to set pipeline to Playing")
- );
- }
- });
-
- // Asynchronously set the pipeline to Playing
- app.pipeline.call_async(|pipeline| {
- pipeline
- .set_state(gst::State::Playing)
- .expect("Couldn't set pipeline to Playing");
- });
+ // Asynchronously set the pipeline to Playing if we're creating the offer,
+ // otherwise do that after the offer was received.
+ if app.args.peer_id.is_some() {
+ app.pipeline.call_async(|pipeline| {
+ // If this fails, post an error on the bus so we exit
+ if pipeline.set_state(gst::State::Playing).is_err() {
+ gst::element_error!(
+ pipeline,
+ gst::LibraryError::Failed,
+ ("Failed to set pipeline to Playing")
+ );
+ }
+ });
+ }
Ok((app, send_gst_msg_rx, send_ws_msg_rx))
}
@@ -377,6 +373,63 @@ impl App {
Ok(())
}
+ fn configure_pipeline_on_offer(
+ &self,
+ offer: &gst_sdp::SDPMessage,
+ ) -> Result<(), anyhow::Error> {
+ // Extract audio/video payload types from the SDP and configure accordingly on the
+ // pipeline as these have to match with the offer
+ let mut opus_id = None;
+ let mut vp8_id = None;
+ for media in offer.medias() {
+ for fmt in media.formats() {
+ if fmt == "webrtc-datachannel" {
+ continue;
+ }
+
+ let pt = match fmt.parse::<u8>() {
+ Ok(pt) => pt,
+ Err(_) => continue,
+ };
+
+ let caps = match media.caps_from_media(pt as i32) {
+ Some(caps) if caps.size() > 0 => caps,
+ _ => continue,
+ };
+
+ let s = caps.structure(0).unwrap();
+ let encoding_name = match s.get::<&str>("encoding-name") {
+ Ok(encoding_name) => encoding_name,
+ Err(_) => continue,
+ };
+
+ if encoding_name == "VP8" && vp8_id.is_none() {
+ vp8_id = Some(pt);
+ } else if encoding_name == "OPUS" && opus_id.is_none() {
+ opus_id = Some(pt);
+ }
+ }
+ }
+
+ if let (Some(opus_id), Some(vp8_id)) = (opus_id, vp8_id) {
+ let apay = self.pipeline.by_name("apay").unwrap();
+ let vpay = self.pipeline.by_name("vpay").unwrap();
+
+ for (pay, pt) in [(apay, opus_id), (vpay, vp8_id)] {
+ pay.set_property("pt", pt as u32);
+ }
+ } else {
+ gst::element_error!(
+ self.pipeline,
+ gst::LibraryError::Failed,
+ ("Not all streams found in the offer")
+ );
+ bail!("Not all streams found in the offer");
+ }
+
+ Ok(())
+ }
+
// Handle incoming SDP answers from the peer
fn handle_sdp(&self, type_: &str, sdp: &str) -> Result<(), anyhow::Error> {
if type_ == "answer" {
@@ -403,6 +456,20 @@ impl App {
self.pipeline.call_async(move |_pipeline| {
let app = upgrade_weak!(app_clone);
+ if app.configure_pipeline_on_offer(&ret).is_err() {
+ return;
+ }
+
+ // If this fails, post an error on the bus so we exit
+ if app.pipeline.set_state(gst::State::Playing).is_err() {
+ gst::element_error!(
+ app.pipeline,
+ gst::LibraryError::Failed,
+ ("Failed to set pipeline to Playing")
+ );
+ return;
+ }
+
let offer = gst_webrtc::WebRTCSessionDescription::new(
gst_webrtc::WebRTCSDPType::Offer,
ret,