mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-05-17 07:42:39 +00:00
086ffd7aff
GST_PLUGIN_FEATURE_RANK=rtspsrc2:1 gst-play-1.0 [URI] Features: * Live streaming N audio and N video - With RTCP-based A/V sync * Lower transports: TCP, UDP, UDP-Multicast * RTP, RTCP SR, RTCP RR * OPTIONS DESCRIBE SETUP PLAY TEARDOWN * Custom UDP socket management, does not use udpsrc/udpsink * Supports both rtpbin and the rtpbin2 rust rewrite - Set USE_RTPBIN2=1 to use rtpbin2 (needs other MRs) * Properties: - protocols selection and priority (NEW!) - location supports rtsp[ut]:// - port-start instead of port-range Co-Authored-by: Tim-Philipp Müller <tim@centricular.com> Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1425>
106 lines
3.7 KiB
Rust
106 lines
3.7 KiB
Rust
// GStreamer RTSP Source 2
|
|
//
|
|
// Copyright (C) 2023-2024 Nirbheek Chauhan <nirbheek centricular com>
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
|
|
// If a copy of the MPL was not distributed with this file, You can obtain one at
|
|
// <https://mozilla.org/MPL/2.0/>.
|
|
//
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
//
|
|
// https://www.rfc-editor.org/rfc/rfc2326.html
|
|
|
|
use super::imp::{RtspError, RtspProtocol};
|
|
use rtsp_types::headers::{transport::RtpTransport, RtpLowerTransport};
|
|
use std::{convert::TryFrom, net::IpAddr};
|
|
use tokio::net::UdpSocket;
|
|
|
|
#[derive(Debug)]
|
|
pub enum RtspTransportInfo {
|
|
Tcp {
|
|
channels: (u8, Option<u8>),
|
|
},
|
|
Udp {
|
|
source: Option<String>,
|
|
server_port: (u16, Option<u16>),
|
|
client_port: Option<(u16, Option<u16>)>,
|
|
sockets: Option<(UdpSocket, Option<UdpSocket>)>,
|
|
},
|
|
UdpMulticast {
|
|
dest: IpAddr,
|
|
port: (u16, Option<u16>),
|
|
ttl: Option<u8>,
|
|
},
|
|
}
|
|
|
|
impl TryFrom<&RtpTransport> for RtspTransportInfo {
|
|
type Error = RtspError;
|
|
|
|
fn try_from(t: &RtpTransport) -> Result<Self, Self::Error> {
|
|
match &t.lower_transport {
|
|
Some(RtpLowerTransport::Tcp) => match t.params.interleaved {
|
|
Some(v) => Ok(RtspTransportInfo::Tcp { channels: v }),
|
|
None => Err(RtspError::Fatal(format!(
|
|
"Expected interleaved channels: {t:#?}",
|
|
))),
|
|
},
|
|
Some(RtpLowerTransport::Udp) | None => {
|
|
if t.params.multicast {
|
|
let dest = if let Some(d) = t.params.destination.as_ref() {
|
|
match d.parse::<IpAddr>() {
|
|
Ok(d) => d,
|
|
Err(err) => {
|
|
return Err(RtspError::Fatal(format!(
|
|
"Failed to parse multicast dest addr: {err:?}"
|
|
)));
|
|
}
|
|
}
|
|
} else {
|
|
return Err(RtspError::Fatal(format!(
|
|
"Need multicast dest addr: {:#?}",
|
|
t.params,
|
|
)));
|
|
};
|
|
let Some(port) = t.params.port else {
|
|
return Err(RtspError::Fatal(format!(
|
|
"Need multicast UDP port(s): {:#?}",
|
|
t.params,
|
|
)));
|
|
};
|
|
Ok(RtspTransportInfo::UdpMulticast {
|
|
dest,
|
|
port,
|
|
ttl: t.params.ttl,
|
|
})
|
|
} else {
|
|
let Some(server_port) = t.params.server_port else {
|
|
return Err(RtspError::Fatal(format!(
|
|
"Need server unicast UDP port(s): {:#?}",
|
|
t.params,
|
|
)));
|
|
};
|
|
Ok(RtspTransportInfo::Udp {
|
|
source: t.params.source.clone(),
|
|
server_port,
|
|
client_port: t.params.client_port,
|
|
sockets: None,
|
|
})
|
|
}
|
|
}
|
|
Some(RtpLowerTransport::Other(token)) => Err(RtspError::Fatal(format!(
|
|
"Unsupported RTP lower transport {token:?}"
|
|
))),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl RtspTransportInfo {
|
|
pub fn to_protocol(&self) -> RtspProtocol {
|
|
match &self {
|
|
Self::Tcp { .. } => RtspProtocol::Tcp,
|
|
Self::Udp { .. } => RtspProtocol::Udp,
|
|
Self::UdpMulticast { .. } => RtspProtocol::UdpMulticast,
|
|
}
|
|
}
|
|
}
|