mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-29 23:11:01 +00:00
webrtcsink: implement per-transceiver navigation support
This commit is contained in:
parent
29ed333b97
commit
d40b804952
1 changed files with 50 additions and 4 deletions
|
@ -5,7 +5,6 @@ use gst::prelude::*;
|
||||||
use gst::subclass::prelude::*;
|
use gst::subclass::prelude::*;
|
||||||
use gst_rtp::prelude::*;
|
use gst_rtp::prelude::*;
|
||||||
use gst_utils::StreamProducer;
|
use gst_utils::StreamProducer;
|
||||||
use gst_video::prelude::*;
|
|
||||||
use gst_video::subclass::prelude::*;
|
use gst_video::subclass::prelude::*;
|
||||||
use gst_webrtc::WebRTCDataChannel;
|
use gst_webrtc::WebRTCDataChannel;
|
||||||
|
|
||||||
|
@ -212,6 +211,13 @@ enum SignallerState {
|
||||||
Stopped,
|
Stopped,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize)]
|
||||||
|
struct NavigationEvent {
|
||||||
|
mid: Option<String>,
|
||||||
|
#[serde(flatten)]
|
||||||
|
event: gst_video::NavigationEvent,
|
||||||
|
}
|
||||||
|
|
||||||
/* Our internal state */
|
/* Our internal state */
|
||||||
struct State {
|
struct State {
|
||||||
signaller: Box<dyn super::SignallableObject>,
|
signaller: Box<dyn super::SignallableObject>,
|
||||||
|
@ -229,13 +235,42 @@ struct State {
|
||||||
video_serial: u32,
|
video_serial: u32,
|
||||||
streams: HashMap<String, InputStream>,
|
streams: HashMap<String, InputStream>,
|
||||||
navigation_handler: Option<NavigationEventHandler>,
|
navigation_handler: Option<NavigationEventHandler>,
|
||||||
|
mids: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_navigation_event<N: IsA<gst_video::Navigation>>(sink: &N, msg: &str) {
|
fn create_navigation_event(sink: &super::WebRTCSink, msg: &str) {
|
||||||
let event: Result<gst_video::NavigationEvent, _> = serde_json::from_str(msg);
|
let event: Result<NavigationEvent, _> = serde_json::from_str(msg);
|
||||||
|
|
||||||
if let Ok(event) = event {
|
if let Ok(event) = event {
|
||||||
sink.send_event(event.structure());
|
gst::log!(CAT, obj: sink, "Processing navigation event: {:?}", event);
|
||||||
|
|
||||||
|
if let Some(mid) = event.mid {
|
||||||
|
let this = WebRTCSink::from_instance(sink);
|
||||||
|
|
||||||
|
let state = this.state.lock().unwrap();
|
||||||
|
if let Some(stream_name) = state.mids.get(&mid) {
|
||||||
|
if let Some(stream) = state.streams.get(stream_name) {
|
||||||
|
let event = gst::event::Navigation::new(event.event.structure());
|
||||||
|
|
||||||
|
if !stream.sink_pad.push_event(event.clone()) {
|
||||||
|
gst::info!(CAT, "Could not send event: {:?}", event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let this = WebRTCSink::from_instance(sink);
|
||||||
|
|
||||||
|
let state = this.state.lock().unwrap();
|
||||||
|
let event = gst::event::Navigation::new(event.event.structure());
|
||||||
|
state.streams.iter().for_each(|(_, stream)| {
|
||||||
|
if stream.sink_pad.name().starts_with("video_") {
|
||||||
|
gst::log!(CAT, "Navigating to: {:?}", event);
|
||||||
|
if !stream.sink_pad.push_event(event.clone()) {
|
||||||
|
gst::info!(CAT, "Could not send event: {:?}", event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
gst::error!(CAT, "Invalid navigation event: {:?}", msg);
|
gst::error!(CAT, "Invalid navigation event: {:?}", msg);
|
||||||
}
|
}
|
||||||
|
@ -304,6 +339,7 @@ impl Default for State {
|
||||||
video_serial: 0,
|
video_serial: 0,
|
||||||
streams: HashMap::new(),
|
streams: HashMap::new(),
|
||||||
navigation_handler: None,
|
navigation_handler: None,
|
||||||
|
mids: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1975,6 +2011,16 @@ impl WebRTCSink {
|
||||||
|
|
||||||
if let Some(mut consumer) = state.consumers.remove(&peer_id) {
|
if let Some(mut consumer) = state.consumers.remove(&peer_id) {
|
||||||
for webrtc_pad in consumer.webrtc_pads.clone().values() {
|
for webrtc_pad in consumer.webrtc_pads.clone().values() {
|
||||||
|
let transceiver = webrtc_pad
|
||||||
|
.pad
|
||||||
|
.property::<gst_webrtc::WebRTCRTPTransceiver>("transceiver");
|
||||||
|
|
||||||
|
if let Some(mid) = transceiver.mid() {
|
||||||
|
state
|
||||||
|
.mids
|
||||||
|
.insert(mid.to_string(), webrtc_pad.stream_name.clone());
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(producer) = state
|
if let Some(producer) = state
|
||||||
.streams
|
.streams
|
||||||
.get(&webrtc_pad.stream_name)
|
.get(&webrtc_pad.stream_name)
|
||||||
|
|
Loading…
Reference in a new issue