pub(crate) mod internal;
pub(crate) mod rtcp_parameters;
pub(crate) mod rtp_capabilities;
pub(crate) mod rtp_codec;
pub(crate) mod rtp_codec_parameters;
pub(crate) mod rtp_coding_parameters;
pub(crate) mod rtp_encoding_parameters;
pub(crate) mod rtp_header_extension_capability;
pub(crate) mod rtp_header_extension_parameters;
pub(crate) mod rtp_parameters;
pub(crate) mod rtp_receiver_parameters;
pub(crate) mod rtp_send_parameters;
pub(crate) mod set_parameter_options;
use crate::media_stream::MediaStreamId;
use crate::media_stream::track::MediaStreamTrack;
use crate::peer_connection::RTCPeerConnection;
use crate::peer_connection::message::RTCMessage;
use crate::rtp_transceiver::RTCRtpSenderId;
use crate::rtp_transceiver::rtp_sender::rtp_codec::{CodecMatch, codec_parameters_fuzzy_search};
use interceptor::{Interceptor, NoopInterceptor};
use sansio::Protocol;
use shared::error::{Error, Result};
pub use rtcp_parameters::{RTCPFeedback, RTCRtcpParameters};
pub use rtcp_parameters::{
TYPE_RTCP_FB_ACK, TYPE_RTCP_FB_CCM, TYPE_RTCP_FB_GOOG_REMB, TYPE_RTCP_FB_NACK,
TYPE_RTCP_FB_TRANSPORT_CC,
};
pub use rtp_capabilities::RTCRtpCapabilities;
pub use rtp_codec::{RTCRtpCodec, RtpCodecKind};
pub use rtp_codec_parameters::RTCRtpCodecParameters;
pub use rtp_coding_parameters::{RTCRtpCodingParameters, RTCRtpFecParameters, RTCRtpRtxParameters};
pub use rtp_encoding_parameters::RTCRtpEncodingParameters;
pub use rtp_header_extension_capability::RTCRtpHeaderExtensionCapability;
pub use rtp_header_extension_parameters::RTCRtpHeaderExtensionParameters;
pub use rtp_parameters::RTCRtpParameters;
pub use rtp_receiver_parameters::RTCRtpReceiveParameters;
pub use rtp_send_parameters::RTCRtpSendParameters;
pub use set_parameter_options::RTCSetParameterOptions;
pub struct RTCRtpSender<'a, I = NoopInterceptor>
where
I: Interceptor,
{
pub(crate) id: RTCRtpSenderId,
pub(crate) peer_connection: &'a mut RTCPeerConnection<I>,
}
impl<I> RTCRtpSender<'_, I>
where
I: Interceptor,
{
pub fn track(&self) -> &MediaStreamTrack {
self.peer_connection.rtp_transceivers[self.id.0]
.sender
.as_ref()
.unwrap()
.track()
}
pub fn get_capabilities(&self, kind: RtpCodecKind) -> Option<RTCRtpCapabilities> {
self.peer_connection.rtp_transceivers[self.id.0]
.sender
.as_ref()
.unwrap()
.get_capabilities(kind, &self.peer_connection.media_engine)
}
pub fn set_parameters(
&mut self,
parameters: RTCRtpSendParameters,
set_parameter_options: Option<RTCSetParameterOptions>,
) -> Result<()> {
self.peer_connection.rtp_transceivers[self.id.0]
.sender
.as_mut()
.unwrap()
.set_parameters(parameters, set_parameter_options)
}
pub fn get_parameters(&mut self) -> &RTCRtpSendParameters {
self.peer_connection.rtp_transceivers[self.id.0]
.sender
.as_mut()
.unwrap()
.get_parameters(&self.peer_connection.media_engine)
}
pub fn replace_track(&mut self, track: MediaStreamTrack) -> Result<()> {
self.peer_connection.rtp_transceivers[self.id.0]
.sender
.as_mut()
.unwrap()
.replace_track(track)
}
pub fn set_streams(&mut self, streams: Vec<MediaStreamId>) {
self.peer_connection.rtp_transceivers[self.id.0]
.sender
.as_mut()
.unwrap()
.set_streams(streams);
}
pub fn write_rtp(&mut self, mut packet: rtp::Packet) -> Result<()> {
let (sender, media_engine) = (
self.peer_connection.rtp_transceivers[self.id.0]
.sender
.as_mut()
.unwrap(),
&mut self.peer_connection.media_engine,
);
if !sender
.track()
.ssrcs()
.any(|ssrc| ssrc == packet.header.ssrc)
{
return Err(Error::ErrSenderWithNoSSRCs);
}
let parameters = sender.get_parameters(media_engine);
let (codecs, encodings) = (¶meters.rtp_parameters.codecs, ¶meters.encodings);
let encoding = encodings
.iter()
.find(|encoding| {
encoding
.rtp_coding_parameters
.ssrc
.is_some_and(|s| s == packet.header.ssrc)
})
.ok_or(Error::ErrRTPSenderNoBaseEncoding)?;
let (codec, match_type) = codec_parameters_fuzzy_search(&encoding.codec, codecs);
if match_type == CodecMatch::None {
return Err(Error::ErrRTPTransceiverCodecUnsupported);
}
let track_id = sender.track().track_id().to_string();
packet.header.payload_type = codec.payload_type;
self.peer_connection
.handle_write(RTCMessage::RtpPacket(track_id, packet))
}
pub fn write_rtcp(&mut self, packets: Vec<Box<dyn rtcp::Packet>>) -> Result<()> {
let sender = self.peer_connection.rtp_transceivers[self.id.0]
.sender
.as_mut()
.unwrap();
let track_id = sender.track().track_id().to_string();
self.peer_connection
.handle_write(RTCMessage::RtcpPacket(track_id, packets))
}
}