Skip to content

Commit

Permalink
interceptor: Add AssociatedStreamInfo and populate for rtx streams
Browse files Browse the repository at this point in the history
  • Loading branch information
anders-avos committed Aug 26, 2024
1 parent 23bbc1f commit caeaa88
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 9 deletions.
9 changes: 9 additions & 0 deletions interceptor/src/stream_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ pub struct StreamInfo {
pub channels: u16,
pub sdp_fmtp_line: String,
pub rtcp_feedback: Vec<RTCPFeedback>,
pub associated_stream: Option<AssociatedStreamInfo>,
}

/// AssociatedStreamInfo provides a mapping from an auxiliary stream (RTX, FEC,
/// etc.) back to the original stream.
#[derive(Default, Debug, Clone)]
pub struct AssociatedStreamInfo {
pub ssrc: u32,
pub payload_type: u8,
}

/// RTCPFeedback signals the connection to use additional RTCP packet types.
Expand Down
1 change: 1 addition & 0 deletions webrtc/src/peer_connection/peer_connection_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,7 @@ impl PeerConnectionInternal {
params.codecs[0].payload_type,
params.codecs[0].capability.clone(),
&params.header_extensions,
None,
);
let (rtp_read_stream, rtp_interceptor, rtcp_read_stream, rtcp_interceptor) = self
.dtls_transport
Expand Down
4 changes: 3 additions & 1 deletion webrtc/src/rtp_transceiver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::pin::Pin;
use std::sync::atomic::Ordering;
use std::sync::Arc;

use interceptor::stream_info::{RTPHeaderExtension, StreamInfo};
use interceptor::stream_info::{AssociatedStreamInfo, RTPHeaderExtension, StreamInfo};
use interceptor::Attributes;
use log::trace;
use portable_atomic::{AtomicBool, AtomicU8};
Expand Down Expand Up @@ -136,6 +136,7 @@ pub(crate) fn create_stream_info(
payload_type: PayloadType,
codec: RTCRtpCodecCapability,
webrtc_header_extensions: &[RTCRtpHeaderExtensionParameters],
associated_stream: Option<AssociatedStreamInfo>,
) -> StreamInfo {
let header_extensions: Vec<RTPHeaderExtension> = webrtc_header_extensions
.iter()
Expand Down Expand Up @@ -165,6 +166,7 @@ pub(crate) fn create_stream_info(
channels: codec.channels,
sdp_fmtp_line: codec.sdp_fmtp_line,
rtcp_feedback: feedbacks,
associated_stream,
}
}

Expand Down
28 changes: 28 additions & 0 deletions webrtc/src/rtp_transceiver/rtp_codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,31 @@ pub(crate) fn codec_parameters_fuzzy_search(

(RTCRtpCodecParameters::default(), CodecMatch::None)
}

pub(crate) fn codec_rtx_search(
original_codec: &RTCRtpCodecParameters,
available_codecs: &[RTCRtpCodecParameters],
) -> Option<RTCRtpCodecParameters> {
// find the rtx codec as defined in RFC4588

let (mime_kind, _) = original_codec.capability.mime_type.split_once("/")?;
let rtx_mime = format!("{mime_kind}/rtx");

for codec in available_codecs {
if codec.capability.mime_type != rtx_mime {
continue;
}

let params = fmtp::parse(&codec.capability.mime_type, &codec.capability.sdp_fmtp_line);

if params
.parameter("apt")
.and_then(|v| v.parse::<u8>().ok())
.is_some_and(|apt| apt == original_codec.payload_type)
{
return Some(codec.clone());
}
}

None
}
26 changes: 18 additions & 8 deletions webrtc/src/rtp_transceiver/rtp_receiver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::fmt;
use std::sync::Arc;

use arc_swap::ArcSwapOption;
use interceptor::stream_info::RTPHeaderExtension;
use interceptor::stream_info::{AssociatedStreamInfo, RTPHeaderExtension};
use interceptor::{Attributes, Interceptor};
use log::trace;
use smol_str::SmolStr;
Expand All @@ -16,12 +16,12 @@ use crate::dtls_transport::RTCDtlsTransport;
use crate::error::{flatten_errs, Error, Result};
use crate::peer_connection::sdp::TrackDetails;
use crate::rtp_transceiver::rtp_codec::{
codec_parameters_fuzzy_search, CodecMatch, RTCRtpCodecCapability, RTCRtpCodecParameters,
RTCRtpParameters, RTPCodecType,
codec_parameters_fuzzy_search, CodecMatch, RTCRtpCodecParameters, RTCRtpParameters,
RTPCodecType,
};
use crate::rtp_transceiver::rtp_transceiver_direction::RTCRtpTransceiverDirection;
use crate::rtp_transceiver::{
create_stream_info, RTCRtpDecodingParameters, RTCRtpReceiveParameters, SSRC,
codec_rtx_search, create_stream_info, RTCRtpDecodingParameters, RTCRtpReceiveParameters, SSRC,
};
use crate::track::track_remote::TrackRemote;
use crate::track::{TrackStream, TrackStreams};
Expand Down Expand Up @@ -519,9 +519,9 @@ impl RTCRtpReceiver {
};

let codec = if let Some(codec) = global_params.codecs.first() {
codec.capability.clone()
codec.clone()
} else {
RTCRtpCodecCapability::default()
RTCRtpCodecParameters::default()
};

for encoding in &parameters.encodings {
Expand All @@ -531,8 +531,9 @@ impl RTCRtpReceiver {
"".to_owned(),
encoding.ssrc,
0,
codec.clone(),
codec.capability.clone(),
&global_params.header_extensions,
None,
);
let (rtp_read_stream, rtp_interceptor, rtcp_read_stream, rtcp_interceptor) =
self.internal
Expand Down Expand Up @@ -585,12 +586,21 @@ impl RTCRtpReceiver {

let rtx_ssrc = encoding.rtx.ssrc;
if rtx_ssrc != 0 {
let rtx_info = AssociatedStreamInfo {
ssrc: encoding.ssrc,
payload_type: 0,
};

let rtx_codec =
codec_rtx_search(&codec, &global_params.codecs).unwrap_or(codec.clone());

let stream_info = create_stream_info(
"".to_owned(),
rtx_ssrc,
0,
codec.clone(),
rtx_codec.capability,
&global_params.header_extensions,
Some(rtx_info),
);
let (rtp_read_stream, rtp_interceptor, rtcp_read_stream, rtcp_interceptor) = self
.internal
Expand Down
1 change: 1 addition & 0 deletions webrtc/src/rtp_transceiver/rtp_sender/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ impl RTCRtpSender {
codec.payload_type,
codec.capability.clone(),
&parameters.rtp_parameters.header_extensions,
None,
);
context.params.codecs = vec![codec];

Expand Down

0 comments on commit caeaa88

Please sign in to comment.