remove StreamContextRef type
Turns out it's not a problem to keep around a StreamContext, so let's avoid the complexity of another public type (and another internal type).
This commit is contained in:
parent
8caa1d9ae3
commit
1b6491370f
@ -32,7 +32,7 @@ fn h264_aac<F: FnMut(CodecItem) -> ()>(mut f: F) {
|
|||||||
Depacketizer::new("video", "h264", 90_000, None, Some("packetization-mode=1;profile-level-id=42C01E;sprop-parameter-sets=Z0LAHtkDxWhAAAADAEAAAAwDxYuS,aMuMsg==")).unwrap(),
|
Depacketizer::new("video", "h264", 90_000, None, Some("packetization-mode=1;profile-level-id=42C01E;sprop-parameter-sets=Z0LAHtkDxWhAAAADAEAAAAwDxYuS,aMuMsg==")).unwrap(),
|
||||||
];
|
];
|
||||||
let conn_ctx = retina::ConnectionContext::dummy();
|
let conn_ctx = retina::ConnectionContext::dummy();
|
||||||
let stream_ctx = retina::StreamContextRef::dummy();
|
let stream_ctx = retina::StreamContext::dummy();
|
||||||
let pkt_ctx = retina::PacketContext::dummy();
|
let pkt_ctx = retina::PacketContext::dummy();
|
||||||
while !remaining.is_empty() {
|
while !remaining.is_empty() {
|
||||||
assert!(remaining.len() > 4);
|
assert!(remaining.len() > 4);
|
||||||
@ -50,7 +50,7 @@ fn h264_aac<F: FnMut(CodecItem) -> ()>(mut f: F) {
|
|||||||
};
|
};
|
||||||
let pkt = match rtps[stream_id].rtp(
|
let pkt = match rtps[stream_id].rtp(
|
||||||
&retina::client::SessionOptions::default(),
|
&retina::client::SessionOptions::default(),
|
||||||
stream_ctx,
|
&stream_ctx,
|
||||||
None,
|
None,
|
||||||
&conn_ctx,
|
&conn_ctx,
|
||||||
&pkt_ctx,
|
&pkt_ctx,
|
||||||
@ -63,7 +63,7 @@ fn h264_aac<F: FnMut(CodecItem) -> ()>(mut f: F) {
|
|||||||
};
|
};
|
||||||
depacketizers[stream_id].push(pkt).unwrap();
|
depacketizers[stream_id].push(pkt).unwrap();
|
||||||
while let Some(pkt) = depacketizers[stream_id]
|
while let Some(pkt) = depacketizers[stream_id]
|
||||||
.pull(&conn_ctx, stream_ctx)
|
.pull(&conn_ctx, &stream_ctx)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
f(pkt);
|
f(pkt);
|
||||||
|
@ -12,7 +12,7 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
let mut timestamp = retina::Timestamp::new(0, NonZeroU32::new(90_000).unwrap(), 0).unwrap();
|
let mut timestamp = retina::Timestamp::new(0, NonZeroU32::new(90_000).unwrap(), 0).unwrap();
|
||||||
let mut sequence_number: u16 = 0;
|
let mut sequence_number: u16 = 0;
|
||||||
let conn_ctx = retina::ConnectionContext::dummy();
|
let conn_ctx = retina::ConnectionContext::dummy();
|
||||||
let stream_ctx = retina::StreamContextRef::dummy();
|
let stream_ctx = retina::StreamContext::dummy();
|
||||||
let pkt_ctx = retina::PacketContext::dummy();
|
let pkt_ctx = retina::PacketContext::dummy();
|
||||||
loop {
|
loop {
|
||||||
let (hdr, rest) = match data.split_first() {
|
let (hdr, rest) = match data.split_first() {
|
||||||
@ -50,7 +50,7 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
if depacketizer.push(pkt).is_err() {
|
if depacketizer.push(pkt).is_err() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while let Some(item) = depacketizer.pull(&conn_ctx, stream_ctx).transpose() {
|
while let Some(item) = depacketizer.pull(&conn_ctx, &stream_ctx).transpose() {
|
||||||
if item.is_err() {
|
if item.is_err() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let conn_ctx = retina::ConnectionContext::dummy();
|
let conn_ctx = retina::ConnectionContext::dummy();
|
||||||
let stream_ctx = retina::StreamContextRef::dummy();
|
let stream_ctx = retina::StreamContext::dummy();
|
||||||
let max_payload_size = u16::from_be_bytes([data[0], data[1]]);
|
let max_payload_size = u16::from_be_bytes([data[0], data[1]]);
|
||||||
let mut p = match retina::codec::h264::Packetizer::new(max_payload_size, 0, 0, 0, 0) {
|
let mut p = match retina::codec::h264::Packetizer::new(max_payload_size, 0, 0, 0, 0) {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
@ -43,7 +43,7 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
if d.push(pkt).is_err() {
|
if d.push(pkt).is_err() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
match d.pull(&conn_ctx, stream_ctx) {
|
match d.pull(&conn_ctx, &stream_ctx) {
|
||||||
Err(_) => return,
|
Err(_) => return,
|
||||||
Ok(Some(retina::codec::CodecItem::VideoFrame(f))) => {
|
Ok(Some(retina::codec::CodecItem::VideoFrame(f))) => {
|
||||||
assert!(mark);
|
assert!(mark);
|
||||||
@ -69,6 +69,6 @@ fuzz_target!(|data: &[u8]| {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
assert_eq!(&data[2..], &frame.data()[..]);
|
assert_eq!(&data[2..], &frame.data()[..]);
|
||||||
assert!(matches!(d.pull(&conn_ctx, stream_ctx), Ok(None)));
|
assert!(matches!(d.pull(&conn_ctx, &stream_ctx), Ok(None)));
|
||||||
assert!(matches!(p.pull(), Ok(None)));
|
assert!(matches!(p.pull(), Ok(None)));
|
||||||
});
|
});
|
||||||
|
@ -25,7 +25,7 @@ use url::Url;
|
|||||||
use crate::client::parse::SessionHeader;
|
use crate::client::parse::SessionHeader;
|
||||||
use crate::codec::CodecItem;
|
use crate::codec::CodecItem;
|
||||||
use crate::{
|
use crate::{
|
||||||
Error, ErrorInt, RtspMessageContext, StreamContextRef, StreamContextRefInner, TcpStreamContext,
|
Error, ErrorInt, RtspMessageContext, StreamContext, StreamContextInner, TcpStreamContext,
|
||||||
UdpStreamContext,
|
UdpStreamContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -771,33 +771,18 @@ impl Stream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum StreamTransport {
|
struct UdpSockets {
|
||||||
Udp(UdpStreamTransport), // the ...Transport wrapper struct keeps ...Context and the sockets.
|
rtp: UdpSocket,
|
||||||
Tcp(TcpStreamContext), // no sockets; ...Context suffices.
|
rtcp: UdpSocket,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for StreamTransport {
|
/// Placeholder `Debug` impl to allow `UdpSockets` to be a field within a `#[derive(Debug)]` struct.
|
||||||
|
impl std::fmt::Debug for UdpSockets {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
std::fmt::Debug::fmt(&self.ctx(), f)
|
f.debug_struct("UdpSockets").finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StreamTransport {
|
|
||||||
fn ctx(&self) -> StreamContextRef {
|
|
||||||
StreamContextRef(match self {
|
|
||||||
StreamTransport::Tcp(tcp) => StreamContextRefInner::Tcp(*tcp),
|
|
||||||
StreamTransport::Udp(udp) => StreamContextRefInner::Udp(&udp.ctx),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct UdpStreamTransport {
|
|
||||||
ctx: UdpStreamContext,
|
|
||||||
rtp_socket: UdpSocket,
|
|
||||||
rtcp_socket: UdpSocket,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Stream {
|
impl Stream {
|
||||||
/// Returns codec-specified parameters for this stream, if available.
|
/// Returns codec-specified parameters for this stream, if available.
|
||||||
///
|
///
|
||||||
@ -834,11 +819,11 @@ impl Stream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a context for this stream, if it has been set up.
|
/// Returns a context for this stream, if it has been set up.
|
||||||
pub fn ctx(&self) -> Option<StreamContextRef> {
|
pub fn ctx(&self) -> Option<&StreamContext> {
|
||||||
match &self.state {
|
match &self.state {
|
||||||
StreamState::Uninit => None,
|
StreamState::Uninit => None,
|
||||||
StreamState::Init(init) => Some(init.transport.ctx()),
|
StreamState::Init(init) => Some(&init.ctx),
|
||||||
StreamState::Playing { transport, .. } => Some(transport.ctx()),
|
StreamState::Playing { ctx, .. } => Some(ctx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -855,7 +840,8 @@ enum StreamState {
|
|||||||
Playing {
|
Playing {
|
||||||
timeline: Timeline,
|
timeline: Timeline,
|
||||||
rtp_handler: rtp::InorderParser,
|
rtp_handler: rtp::InorderParser,
|
||||||
transport: StreamTransport,
|
ctx: StreamContext,
|
||||||
|
udp_sockets: Option<UdpSockets>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -877,7 +863,8 @@ struct StreamStateInit {
|
|||||||
/// itself; by the time it returns, the stream will be in state `Playing`.
|
/// itself; by the time it returns, the stream will be in state `Playing`.
|
||||||
initial_rtptime: Option<u32>,
|
initial_rtptime: Option<u32>,
|
||||||
|
|
||||||
transport: StreamTransport,
|
ctx: StreamContext,
|
||||||
|
udp_sockets: Option<UdpSockets>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Username and password authentication credentials.
|
/// Username and password authentication credentials.
|
||||||
@ -1426,16 +1413,18 @@ impl Session<Described> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
*inner.flags |= SessionFlag::UdpStreams as u8;
|
*inner.flags |= SessionFlag::UdpStreams as u8;
|
||||||
Some(UdpStreamTransport {
|
Some((
|
||||||
ctx: UdpStreamContext {
|
UdpStreamContext {
|
||||||
local_ip,
|
local_ip,
|
||||||
peer_ip: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
peer_ip: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
||||||
local_rtp_port: pair.rtp_port,
|
local_rtp_port: pair.rtp_port,
|
||||||
peer_rtp_port: 0,
|
peer_rtp_port: 0,
|
||||||
},
|
},
|
||||||
rtp_socket: pair.rtp_socket,
|
UdpSockets {
|
||||||
rtcp_socket: pair.rtcp_socket,
|
rtp: pair.rtp_socket,
|
||||||
})
|
rtcp: pair.rtcp_socket,
|
||||||
|
},
|
||||||
|
))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(ref s) = inner.session {
|
if let Some(ref s) = inner.session {
|
||||||
@ -1481,7 +1470,8 @@ impl Session<Described> {
|
|||||||
None => *inner.session = Some(response.session),
|
None => *inner.session = Some(response.session),
|
||||||
};
|
};
|
||||||
let conn_ctx = conn.inner.ctx();
|
let conn_ctx = conn.inner.ctx();
|
||||||
let transport = match udp {
|
let (stream_ctx, udp_sockets);
|
||||||
|
match udp {
|
||||||
None => {
|
None => {
|
||||||
let channel_id = match response.channel_id {
|
let channel_id = match response.channel_id {
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
@ -1506,11 +1496,12 @@ impl Session<Described> {
|
|||||||
description,
|
description,
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
StreamTransport::Tcp(TcpStreamContext {
|
stream_ctx = StreamContext(StreamContextInner::Tcp(TcpStreamContext {
|
||||||
rtp_channel_id: channel_id,
|
rtp_channel_id: channel_id,
|
||||||
})
|
}));
|
||||||
|
udp_sockets = None;
|
||||||
}
|
}
|
||||||
Some(mut udp) => {
|
Some((mut ctx, sockets)) => {
|
||||||
// TODO: RFC 2326 section 12.39 says "If the source address for
|
// TODO: RFC 2326 section 12.39 says "If the source address for
|
||||||
// the stream is different than can be derived from the RTSP
|
// the stream is different than can be derived from the RTSP
|
||||||
// endpoint address (the server in playback or the client in
|
// endpoint address (the server in playback or the client in
|
||||||
@ -1531,27 +1522,31 @@ impl Session<Described> {
|
|||||||
description: "Transport header is missing server_port parameter".to_owned(),
|
description: "Transport header is missing server_port parameter".to_owned(),
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
udp.ctx.peer_ip = source;
|
ctx.peer_ip = source;
|
||||||
udp.ctx.peer_rtp_port = server_port;
|
ctx.peer_rtp_port = server_port;
|
||||||
udp.rtp_socket
|
sockets
|
||||||
|
.rtp
|
||||||
.connect(SocketAddr::new(source, server_port))
|
.connect(SocketAddr::new(source, server_port))
|
||||||
.await
|
.await
|
||||||
.map_err(|e| wrap!(ErrorInt::ConnectError(e)))?;
|
.map_err(|e| wrap!(ErrorInt::ConnectError(e)))?;
|
||||||
udp.rtcp_socket
|
sockets
|
||||||
|
.rtcp
|
||||||
.connect(SocketAddr::new(source, server_port + 1))
|
.connect(SocketAddr::new(source, server_port + 1))
|
||||||
.await
|
.await
|
||||||
.map_err(|e| wrap!(ErrorInt::ConnectError(e)))?;
|
.map_err(|e| wrap!(ErrorInt::ConnectError(e)))?;
|
||||||
punch_firewall_hole(&udp.rtp_socket, &udp.rtcp_socket)
|
punch_firewall_hole(&sockets)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| wrap!(ErrorInt::ConnectError(e)))?;
|
.map_err(|e| wrap!(ErrorInt::ConnectError(e)))?;
|
||||||
StreamTransport::Udp(udp)
|
stream_ctx = StreamContext(StreamContextInner::Udp(ctx));
|
||||||
|
udp_sockets = Some(sockets);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
stream.state = StreamState::Init(StreamStateInit {
|
stream.state = StreamState::Init(StreamStateInit {
|
||||||
ssrc: response.ssrc,
|
ssrc: response.ssrc,
|
||||||
initial_seq: None,
|
initial_seq: None,
|
||||||
initial_rtptime: None,
|
initial_rtptime: None,
|
||||||
transport,
|
ctx: stream_ctx,
|
||||||
|
udp_sockets,
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1631,7 +1626,8 @@ impl Session<Described> {
|
|||||||
initial_rtptime,
|
initial_rtptime,
|
||||||
initial_seq,
|
initial_seq,
|
||||||
ssrc,
|
ssrc,
|
||||||
transport,
|
ctx,
|
||||||
|
udp_sockets,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
let initial_rtptime = match policy.initial_timestamp {
|
let initial_rtptime = match policy.initial_timestamp {
|
||||||
@ -1687,7 +1683,8 @@ impl Session<Described> {
|
|||||||
})
|
})
|
||||||
})?,
|
})?,
|
||||||
rtp_handler: rtp::InorderParser::new(ssrc, initial_seq),
|
rtp_handler: rtp::InorderParser::new(ssrc, initial_seq),
|
||||||
transport,
|
ctx,
|
||||||
|
udp_sockets,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
StreamState::Uninit => {}
|
StreamState::Uninit => {}
|
||||||
@ -1800,10 +1797,7 @@ fn note_stale_live555_data(tool: Option<&Tool>, options: &SessionOptions) {
|
|||||||
///
|
///
|
||||||
/// Note this is insufficient for NAT traversal; the NAT firewall must be
|
/// Note this is insufficient for NAT traversal; the NAT firewall must be
|
||||||
/// RTSP-aware to rewrite the Transport header's client_ports.
|
/// RTSP-aware to rewrite the Transport header's client_ports.
|
||||||
async fn punch_firewall_hole(
|
async fn punch_firewall_hole(sockets: &UdpSockets) -> Result<(), std::io::Error> {
|
||||||
rtp_socket: &UdpSocket,
|
|
||||||
rtcp_socket: &UdpSocket,
|
|
||||||
) -> Result<(), std::io::Error> {
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
const DUMMY_RTP: [u8; 12] = [
|
const DUMMY_RTP: [u8; 12] = [
|
||||||
2 << 6, // version=2 + p=0 + x=0 + cc=0
|
2 << 6, // version=2 + p=0 + x=0 + cc=0
|
||||||
@ -1819,8 +1813,8 @@ async fn punch_firewall_hole(
|
|||||||
0, 1, // length=1 (in 4-byte words minus 1)
|
0, 1, // length=1 (in 4-byte words minus 1)
|
||||||
0, 0, 0, 0, // ssrc=0 (bogus but we don't know the ssrc reliably yet)
|
0, 0, 0, 0, // ssrc=0 (bogus but we don't know the ssrc reliably yet)
|
||||||
];
|
];
|
||||||
rtp_socket.send(&DUMMY_RTP[..]).await?;
|
sockets.rtp.send(&DUMMY_RTP[..]).await?;
|
||||||
rtcp_socket.send(&DUMMY_RTCP[..]).await?;
|
sockets.rtcp.send(&DUMMY_RTCP[..]).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1988,8 +1982,9 @@ impl Session<Playing> {
|
|||||||
StreamState::Playing {
|
StreamState::Playing {
|
||||||
timeline,
|
timeline,
|
||||||
rtp_handler,
|
rtp_handler,
|
||||||
transport,
|
ctx,
|
||||||
} => (timeline, rtp_handler, transport.ctx()),
|
..
|
||||||
|
} => (timeline, rtp_handler, ctx),
|
||||||
_ => unreachable!(
|
_ => unreachable!(
|
||||||
"Session<Playing>'s {}->{:?} not in Playing state",
|
"Session<Playing>'s {}->{:?} not in Playing state",
|
||||||
channel_id, m
|
channel_id, m
|
||||||
@ -2043,12 +2038,14 @@ impl Session<Playing> {
|
|||||||
debug_assert!(buf.filled().is_empty());
|
debug_assert!(buf.filled().is_empty());
|
||||||
let inner = self.0.as_mut().project();
|
let inner = self.0.as_mut().project();
|
||||||
let s = &mut inner.presentation.streams[i];
|
let s = &mut inner.presentation.streams[i];
|
||||||
let (timeline, rtp_handler, udp) = match &mut s.state {
|
let (timeline, rtp_handler, stream_ctx, udp_sockets) = match &mut s.state {
|
||||||
StreamState::Playing {
|
StreamState::Playing {
|
||||||
timeline,
|
timeline,
|
||||||
rtp_handler,
|
rtp_handler,
|
||||||
transport: StreamTransport::Udp(udp),
|
ctx,
|
||||||
} => (timeline, rtp_handler, udp),
|
udp_sockets: Some(udp_sockets),
|
||||||
|
..
|
||||||
|
} => (timeline, rtp_handler, ctx, udp_sockets),
|
||||||
_ => return Poll::Pending,
|
_ => return Poll::Pending,
|
||||||
};
|
};
|
||||||
let conn_ctx = inner
|
let conn_ctx = inner
|
||||||
@ -2057,10 +2054,9 @@ impl Session<Playing> {
|
|||||||
.ok_or_else(|| wrap!(ErrorInt::FailedPrecondition("no connection".into())))?
|
.ok_or_else(|| wrap!(ErrorInt::FailedPrecondition("no connection".into())))?
|
||||||
.inner
|
.inner
|
||||||
.ctx();
|
.ctx();
|
||||||
let stream_ctx = StreamContextRef(StreamContextRefInner::Udp(&udp.ctx));
|
|
||||||
|
|
||||||
// Prioritize RTCP over RTP within a stream.
|
// Prioritize RTCP over RTP within a stream.
|
||||||
while let Poll::Ready(r) = udp.rtcp_socket.poll_recv(cx, buf) {
|
while let Poll::Ready(r) = udp_sockets.rtcp.poll_recv(cx, buf) {
|
||||||
let when = crate::WallTime::now();
|
let when = crate::WallTime::now();
|
||||||
match r {
|
match r {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
@ -2100,9 +2096,8 @@ impl Session<Playing> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while let Poll::Ready(r) = udp.rtp_socket.poll_recv(cx, buf) {
|
while let Poll::Ready(r) = udp_sockets.rtp.poll_recv(cx, buf) {
|
||||||
let when = crate::WallTime::now();
|
let when = crate::WallTime::now();
|
||||||
let stream_ctx = StreamContextRef(StreamContextRefInner::Udp(&udp.ctx));
|
|
||||||
match r {
|
match r {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let msg = Bytes::copy_from_slice(buf.filled());
|
let msg = Bytes::copy_from_slice(buf.filled());
|
||||||
@ -2358,7 +2353,7 @@ impl futures::Stream for Demuxed {
|
|||||||
let inner = self.session.0.as_mut().project();
|
let inner = self.session.0.as_mut().project();
|
||||||
let stream = &mut inner.presentation.streams[stream_id];
|
let stream = &mut inner.presentation.streams[stream_id];
|
||||||
let stream_ctx = match stream.state {
|
let stream_ctx = match stream.state {
|
||||||
StreamState::Playing { ref transport, .. } => transport.ctx(),
|
StreamState::Playing { ref ctx, .. } => ctx,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let depacketizer = match &mut stream.depacketizer {
|
let depacketizer = match &mut stream.depacketizer {
|
||||||
|
@ -669,9 +669,8 @@ mod tests {
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::client::StreamTransport;
|
|
||||||
use crate::TcpStreamContext;
|
|
||||||
use crate::{client::StreamStateInit, codec::Parameters};
|
use crate::{client::StreamStateInit, codec::Parameters};
|
||||||
|
use crate::{StreamContext, StreamContextInner, TcpStreamContext};
|
||||||
|
|
||||||
use super::super::StreamState;
|
use super::super::StreamState;
|
||||||
use super::SessionHeader;
|
use super::SessionHeader;
|
||||||
@ -690,7 +689,10 @@ mod tests {
|
|||||||
ssrc,
|
ssrc,
|
||||||
initial_seq: None,
|
initial_seq: None,
|
||||||
initial_rtptime: None,
|
initial_rtptime: None,
|
||||||
transport: StreamTransport::Tcp(TcpStreamContext { rtp_channel_id: 0 }),
|
ctx: StreamContext(StreamContextInner::Tcp(TcpStreamContext {
|
||||||
|
rtp_channel_id: 0,
|
||||||
|
})),
|
||||||
|
udp_sockets: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,9 +9,7 @@ use log::debug;
|
|||||||
use crate::client::PacketItem;
|
use crate::client::PacketItem;
|
||||||
use crate::rtcp::ReceivedCompoundPacket;
|
use crate::rtcp::ReceivedCompoundPacket;
|
||||||
use crate::rtp::{RawPacket, ReceivedPacket};
|
use crate::rtp::{RawPacket, ReceivedPacket};
|
||||||
use crate::{
|
use crate::{ConnectionContext, Error, ErrorInt, PacketContext, StreamContext, StreamContextInner};
|
||||||
ConnectionContext, Error, ErrorInt, PacketContext, StreamContextRef, StreamContextRefInner,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{SessionOptions, Timeline};
|
use super::{SessionOptions, Timeline};
|
||||||
|
|
||||||
@ -69,7 +67,7 @@ impl InorderParser {
|
|||||||
pub fn rtp(
|
pub fn rtp(
|
||||||
&mut self,
|
&mut self,
|
||||||
session_options: &SessionOptions,
|
session_options: &SessionOptions,
|
||||||
stream_ctx: StreamContextRef,
|
stream_ctx: &StreamContext,
|
||||||
tool: Option<&super::Tool>,
|
tool: Option<&super::Tool>,
|
||||||
conn_ctx: &ConnectionContext,
|
conn_ctx: &ConnectionContext,
|
||||||
pkt_ctx: &PacketContext,
|
pkt_ctx: &PacketContext,
|
||||||
@ -107,7 +105,7 @@ impl InorderParser {
|
|||||||
let ssrc = raw.ssrc();
|
let ssrc = raw.ssrc();
|
||||||
let loss = sequence_number.wrapping_sub(self.next_seq.unwrap_or(sequence_number));
|
let loss = sequence_number.wrapping_sub(self.next_seq.unwrap_or(sequence_number));
|
||||||
if matches!(self.ssrc, Some(s) if s != ssrc) {
|
if matches!(self.ssrc, Some(s) if s != ssrc) {
|
||||||
if matches!(stream_ctx.0, StreamContextRefInner::Udp(_)) {
|
if matches!(stream_ctx.0, StreamContextInner::Udp(_)) {
|
||||||
super::note_stale_live555_data(tool, session_options);
|
super::note_stale_live555_data(tool, session_options);
|
||||||
}
|
}
|
||||||
bail!(ErrorInt::RtpPacketError {
|
bail!(ErrorInt::RtpPacketError {
|
||||||
@ -125,7 +123,7 @@ impl InorderParser {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if loss > 0x80_00 {
|
if loss > 0x80_00 {
|
||||||
if matches!(stream_ctx.0, StreamContextRefInner::Tcp { .. }) {
|
if matches!(stream_ctx.0, StreamContextInner::Tcp { .. }) {
|
||||||
bail!(ErrorInt::RtpPacketError {
|
bail!(ErrorInt::RtpPacketError {
|
||||||
conn_ctx: *conn_ctx,
|
conn_ctx: *conn_ctx,
|
||||||
pkt_ctx: *pkt_ctx,
|
pkt_ctx: *pkt_ctx,
|
||||||
@ -177,7 +175,7 @@ impl InorderParser {
|
|||||||
pub fn rtcp(
|
pub fn rtcp(
|
||||||
&mut self,
|
&mut self,
|
||||||
session_options: &SessionOptions,
|
session_options: &SessionOptions,
|
||||||
stream_ctx: StreamContextRef,
|
stream_ctx: &StreamContext,
|
||||||
tool: Option<&super::Tool>,
|
tool: Option<&super::Tool>,
|
||||||
pkt_ctx: &PacketContext,
|
pkt_ctx: &PacketContext,
|
||||||
timeline: &mut Timeline,
|
timeline: &mut Timeline,
|
||||||
@ -196,7 +194,7 @@ impl InorderParser {
|
|||||||
|
|
||||||
let ssrc = sr.ssrc();
|
let ssrc = sr.ssrc();
|
||||||
if matches!(self.ssrc, Some(s) if s != ssrc) {
|
if matches!(self.ssrc, Some(s) if s != ssrc) {
|
||||||
if matches!(stream_ctx.0, StreamContextRefInner::Tcp { .. }) {
|
if matches!(stream_ctx.0, StreamContextInner::Tcp { .. }) {
|
||||||
super::note_stale_live555_data(tool, session_options);
|
super::note_stale_live555_data(tool, session_options);
|
||||||
}
|
}
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
@ -231,7 +229,7 @@ mod tests {
|
|||||||
fn geovision_pt50_packet() {
|
fn geovision_pt50_packet() {
|
||||||
let mut timeline = Timeline::new(None, 90_000, None).unwrap();
|
let mut timeline = Timeline::new(None, 90_000, None).unwrap();
|
||||||
let mut parser = InorderParser::new(Some(0xd25614e), None);
|
let mut parser = InorderParser::new(Some(0xd25614e), None);
|
||||||
let stream_ctx = StreamContextRef::dummy();
|
let stream_ctx = StreamContext::dummy();
|
||||||
|
|
||||||
// Normal packet.
|
// Normal packet.
|
||||||
let (pkt, _payload_range) = crate::rtp::RawPacketBuilder {
|
let (pkt, _payload_range) = crate::rtp::RawPacketBuilder {
|
||||||
@ -245,7 +243,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
match parser.rtp(
|
match parser.rtp(
|
||||||
&SessionOptions::default(),
|
&SessionOptions::default(),
|
||||||
stream_ctx,
|
&stream_ctx,
|
||||||
None,
|
None,
|
||||||
&ConnectionContext::dummy(),
|
&ConnectionContext::dummy(),
|
||||||
&PacketContext::dummy(),
|
&PacketContext::dummy(),
|
||||||
@ -269,7 +267,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
match parser.rtp(
|
match parser.rtp(
|
||||||
&SessionOptions::default(),
|
&SessionOptions::default(),
|
||||||
stream_ctx,
|
&stream_ctx,
|
||||||
None,
|
None,
|
||||||
&ConnectionContext::dummy(),
|
&ConnectionContext::dummy(),
|
||||||
&PacketContext::dummy(),
|
&PacketContext::dummy(),
|
||||||
@ -286,13 +284,12 @@ mod tests {
|
|||||||
fn out_of_order() {
|
fn out_of_order() {
|
||||||
let mut timeline = Timeline::new(None, 90_000, None).unwrap();
|
let mut timeline = Timeline::new(None, 90_000, None).unwrap();
|
||||||
let mut parser = InorderParser::new(Some(0xd25614e), None);
|
let mut parser = InorderParser::new(Some(0xd25614e), None);
|
||||||
let udp = UdpStreamContext {
|
let stream_ctx = StreamContext(StreamContextInner::Udp(UdpStreamContext {
|
||||||
local_ip: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
local_ip: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
||||||
peer_ip: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
peer_ip: IpAddr::V4(Ipv4Addr::UNSPECIFIED),
|
||||||
local_rtp_port: 0,
|
local_rtp_port: 0,
|
||||||
peer_rtp_port: 0,
|
peer_rtp_port: 0,
|
||||||
};
|
}));
|
||||||
let stream_ctx = StreamContextRef(StreamContextRefInner::Udp(&udp));
|
|
||||||
let session_options = SessionOptions::default();
|
let session_options = SessionOptions::default();
|
||||||
let (pkt, _payload_range) = crate::rtp::RawPacketBuilder {
|
let (pkt, _payload_range) = crate::rtp::RawPacketBuilder {
|
||||||
sequence_number: 2,
|
sequence_number: 2,
|
||||||
@ -305,7 +302,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
match parser.rtp(
|
match parser.rtp(
|
||||||
&session_options,
|
&session_options,
|
||||||
stream_ctx,
|
&stream_ctx,
|
||||||
None,
|
None,
|
||||||
&ConnectionContext::dummy(),
|
&ConnectionContext::dummy(),
|
||||||
&PacketContext::dummy(),
|
&PacketContext::dummy(),
|
||||||
@ -330,7 +327,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
match parser.rtp(
|
match parser.rtp(
|
||||||
&session_options,
|
&session_options,
|
||||||
stream_ctx,
|
&stream_ctx,
|
||||||
None,
|
None,
|
||||||
&ConnectionContext::dummy(),
|
&ConnectionContext::dummy(),
|
||||||
&PacketContext::dummy(),
|
&PacketContext::dummy(),
|
||||||
@ -353,7 +350,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
match parser.rtp(
|
match parser.rtp(
|
||||||
&session_options,
|
&session_options,
|
||||||
stream_ctx,
|
&stream_ctx,
|
||||||
None,
|
None,
|
||||||
&ConnectionContext::dummy(),
|
&ConnectionContext::dummy(),
|
||||||
&PacketContext::dummy(),
|
&PacketContext::dummy(),
|
||||||
|
@ -21,7 +21,7 @@ use std::{
|
|||||||
num::{NonZeroU16, NonZeroU32},
|
num::{NonZeroU16, NonZeroU32},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{error::ErrorInt, rtp::ReceivedPacket, ConnectionContext, Error, StreamContextRef};
|
use crate::{error::ErrorInt, rtp::ReceivedPacket, ConnectionContext, Error, StreamContext};
|
||||||
|
|
||||||
use super::CodecItem;
|
use super::CodecItem;
|
||||||
|
|
||||||
@ -652,7 +652,7 @@ impl Depacketizer {
|
|||||||
pub(super) fn pull(
|
pub(super) fn pull(
|
||||||
&mut self,
|
&mut self,
|
||||||
conn_ctx: &ConnectionContext,
|
conn_ctx: &ConnectionContext,
|
||||||
stream_ctx: StreamContextRef,
|
stream_ctx: &StreamContext,
|
||||||
) -> Result<Option<super::CodecItem>, Error> {
|
) -> Result<Option<super::CodecItem>, Error> {
|
||||||
match std::mem::take(&mut self.state) {
|
match std::mem::take(&mut self.state) {
|
||||||
s @ DepacketizerState::Idle { .. } | s @ DepacketizerState::Fragmented(..) => {
|
s @ DepacketizerState::Idle { .. } | s @ DepacketizerState::Fragmented(..) => {
|
||||||
@ -770,13 +770,13 @@ impl Depacketizer {
|
|||||||
|
|
||||||
fn error(
|
fn error(
|
||||||
conn_ctx: ConnectionContext,
|
conn_ctx: ConnectionContext,
|
||||||
stream_ctx: StreamContextRef,
|
stream_ctx: &StreamContext,
|
||||||
agg: Aggregate,
|
agg: Aggregate,
|
||||||
description: String,
|
description: String,
|
||||||
) -> Error {
|
) -> Error {
|
||||||
Error(std::sync::Arc::new(ErrorInt::RtpPacketError {
|
Error(std::sync::Arc::new(ErrorInt::RtpPacketError {
|
||||||
conn_ctx,
|
conn_ctx,
|
||||||
stream_ctx: stream_ctx.to_owned(),
|
stream_ctx: *stream_ctx,
|
||||||
pkt_ctx: *agg.pkt.ctx(),
|
pkt_ctx: *agg.pkt.ctx(),
|
||||||
stream_id: agg.pkt.stream_id(),
|
stream_id: agg.pkt.stream_id(),
|
||||||
ssrc: agg.pkt.ssrc(),
|
ssrc: agg.pkt.ssrc(),
|
||||||
@ -842,7 +842,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let a = match d
|
let a = match d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
Some(CodecItem::AudioFrame(a)) => a,
|
Some(CodecItem::AudioFrame(a)) => a,
|
||||||
@ -851,7 +851,7 @@ mod tests {
|
|||||||
assert_eq!(a.timestamp, timestamp);
|
assert_eq!(a.timestamp, timestamp);
|
||||||
assert_eq!(&a.data[..], b"asdf");
|
assert_eq!(&a.data[..], b"asdf");
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
|
|
||||||
@ -880,7 +880,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let a = match d
|
let a = match d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
Some(CodecItem::AudioFrame(a)) => a,
|
Some(CodecItem::AudioFrame(a)) => a,
|
||||||
@ -889,7 +889,7 @@ mod tests {
|
|||||||
assert_eq!(a.timestamp, timestamp);
|
assert_eq!(a.timestamp, timestamp);
|
||||||
assert_eq!(&a.data[..], b"foo");
|
assert_eq!(&a.data[..], b"foo");
|
||||||
let a = match d
|
let a = match d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
Some(CodecItem::AudioFrame(a)) => a,
|
Some(CodecItem::AudioFrame(a)) => a,
|
||||||
@ -898,7 +898,7 @@ mod tests {
|
|||||||
assert_eq!(a.timestamp, timestamp.try_add(1_024).unwrap());
|
assert_eq!(a.timestamp, timestamp.try_add(1_024).unwrap());
|
||||||
assert_eq!(&a.data[..], b"bar");
|
assert_eq!(&a.data[..], b"bar");
|
||||||
let a = match d
|
let a = match d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
Some(CodecItem::AudioFrame(a)) => a,
|
Some(CodecItem::AudioFrame(a)) => a,
|
||||||
@ -907,7 +907,7 @@ mod tests {
|
|||||||
assert_eq!(a.timestamp, timestamp.try_add(2_048).unwrap());
|
assert_eq!(a.timestamp, timestamp.try_add(2_048).unwrap());
|
||||||
assert_eq!(&a.data[..], b"baz");
|
assert_eq!(&a.data[..], b"baz");
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
|
|
||||||
@ -935,7 +935,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
d.push(
|
d.push(
|
||||||
@ -961,7 +961,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
d.push(
|
d.push(
|
||||||
@ -987,7 +987,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let a = match d
|
let a = match d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
Some(CodecItem::AudioFrame(a)) => a,
|
Some(CodecItem::AudioFrame(a)) => a,
|
||||||
@ -996,7 +996,7 @@ mod tests {
|
|||||||
assert_eq!(a.timestamp, timestamp);
|
assert_eq!(a.timestamp, timestamp);
|
||||||
assert_eq!(&a.data[..], b"foobarbaz");
|
assert_eq!(&a.data[..], b"foobarbaz");
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
}
|
}
|
||||||
@ -1038,7 +1038,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
d.push(
|
d.push(
|
||||||
@ -1063,7 +1063,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
|
|
||||||
@ -1091,7 +1091,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let a = match d
|
let a = match d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
Some(CodecItem::AudioFrame(a)) => a,
|
Some(CodecItem::AudioFrame(a)) => a,
|
||||||
@ -1100,7 +1100,7 @@ mod tests {
|
|||||||
assert_eq!(a.loss, 1);
|
assert_eq!(a.loss, 1);
|
||||||
assert_eq!(&a.data[..], b"asdf");
|
assert_eq!(&a.data[..], b"asdf");
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
}
|
}
|
||||||
@ -1142,7 +1142,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
// Fragment 2/3 is lost
|
// Fragment 2/3 is lost
|
||||||
@ -1169,7 +1169,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
|
|
||||||
@ -1197,7 +1197,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let a = match d
|
let a = match d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
Some(CodecItem::AudioFrame(a)) => a,
|
Some(CodecItem::AudioFrame(a)) => a,
|
||||||
@ -1206,7 +1206,7 @@ mod tests {
|
|||||||
assert_eq!(a.loss, 1);
|
assert_eq!(a.loss, 1);
|
||||||
assert_eq!(&a.data[..], b"asdf");
|
assert_eq!(&a.data[..], b"asdf");
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
}
|
}
|
||||||
@ -1248,7 +1248,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
// Fragment 2/3 is lost
|
// Fragment 2/3 is lost
|
||||||
@ -1275,7 +1275,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
|
|
||||||
@ -1303,7 +1303,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let a = match d
|
let a = match d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
Some(CodecItem::AudioFrame(a)) => a,
|
Some(CodecItem::AudioFrame(a)) => a,
|
||||||
@ -1312,7 +1312,7 @@ mod tests {
|
|||||||
assert_eq!(a.loss, 1);
|
assert_eq!(a.loss, 1);
|
||||||
assert_eq!(&a.data[..], b"asdf");
|
assert_eq!(&a.data[..], b"asdf");
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
}
|
}
|
||||||
@ -1357,7 +1357,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(d
|
assert!(d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none());
|
.is_none());
|
||||||
|
|
||||||
@ -1385,7 +1385,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let e = d
|
let e = d
|
||||||
.pull(&ConnectionContext::dummy(), StreamContextRef::dummy())
|
.pull(&ConnectionContext::dummy(), &StreamContext::dummy())
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
let e_str = e.to_string();
|
let e_str = e.to_string();
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -12,7 +12,7 @@ use std::num::{NonZeroU16, NonZeroU32};
|
|||||||
use crate::rtp::ReceivedPacket;
|
use crate::rtp::ReceivedPacket;
|
||||||
use crate::ConnectionContext;
|
use crate::ConnectionContext;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use crate::StreamContextRef;
|
use crate::StreamContext;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
|
||||||
pub(crate) mod aac;
|
pub(crate) mod aac;
|
||||||
@ -555,7 +555,7 @@ impl Depacketizer {
|
|||||||
pub fn pull(
|
pub fn pull(
|
||||||
&mut self,
|
&mut self,
|
||||||
conn_ctx: &ConnectionContext,
|
conn_ctx: &ConnectionContext,
|
||||||
stream_ctx: StreamContextRef,
|
stream_ctx: &StreamContext,
|
||||||
) -> Result<Option<CodecItem>, Error> {
|
) -> Result<Option<CodecItem>, Error> {
|
||||||
match &mut self.0 {
|
match &mut self.0 {
|
||||||
DepacketizerInner::Aac(d) => d.pull(conn_ctx, stream_ctx),
|
DepacketizerInner::Aac(d) => d.pull(conn_ctx, stream_ctx),
|
||||||
|
28
src/lib.rs
28
src/lib.rs
@ -367,34 +367,6 @@ enum StreamContextInner {
|
|||||||
Dummy,
|
Dummy,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Context for an active stream (RTP+RTCP session), either TCP or UDP. Reference version.
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub struct StreamContextRef<'a>(StreamContextRefInner<'a>);
|
|
||||||
|
|
||||||
impl StreamContextRef<'_> {
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn dummy() -> Self {
|
|
||||||
StreamContextRef(StreamContextRefInner::Dummy)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
enum StreamContextRefInner<'a> {
|
|
||||||
Tcp(TcpStreamContext), // this one is by value because TcpStreamContext is small.
|
|
||||||
Udp(&'a UdpStreamContext),
|
|
||||||
Dummy,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StreamContextRef<'_> {
|
|
||||||
fn to_owned(self) -> StreamContext {
|
|
||||||
StreamContext(match self.0 {
|
|
||||||
StreamContextRefInner::Tcp(tcp) => StreamContextInner::Tcp(tcp),
|
|
||||||
StreamContextRefInner::Udp(udp) => StreamContextInner::Udp(*udp),
|
|
||||||
StreamContextRefInner::Dummy => StreamContextInner::Dummy,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Context for a UDP stream (aka UDP-based RTP transport). Unstable/internal. Exposed for benchmarks.
|
/// Context for a UDP stream (aka UDP-based RTP transport). Unstable/internal. Exposed for benchmarks.
|
||||||
///
|
///
|
||||||
/// This stores only the RTP addresses; the RTCP addresses are assumed to use
|
/// This stores only the RTP addresses; the RTCP addresses are assumed to use
|
||||||
|
Loading…
Reference in New Issue
Block a user