#![warn(rust_2018_idioms)]
#![allow(dead_code)]
use std::collections::HashMap;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use async_trait::async_trait;
use error::Result;
use stream_info::StreamInfo;
pub mod chain;
mod error;
pub mod mock;
pub mod nack;
pub mod noop;
pub mod registry;
pub mod report;
pub mod stats;
pub mod stream_info;
pub mod stream_reader;
pub mod twcc;
pub use error::Error;
pub type Attributes = HashMap<usize, usize>;
pub trait InterceptorBuilder {
fn build(&self, id: &str) -> Result<Arc<dyn Interceptor + Send + Sync>>;
}
#[async_trait]
pub trait Interceptor {
async fn bind_rtcp_reader(
&self,
reader: Arc<dyn RTCPReader + Send + Sync>,
) -> Arc<dyn RTCPReader + Send + Sync>;
async fn bind_rtcp_writer(
&self,
writer: Arc<dyn RTCPWriter + Send + Sync>,
) -> Arc<dyn RTCPWriter + Send + Sync>;
async fn bind_local_stream(
&self,
info: &StreamInfo,
writer: Arc<dyn RTPWriter + Send + Sync>,
) -> Arc<dyn RTPWriter + Send + Sync>;
async fn unbind_local_stream(&self, info: &StreamInfo);
async fn bind_remote_stream(
&self,
info: &StreamInfo,
reader: Arc<dyn RTPReader + Send + Sync>,
) -> Arc<dyn RTPReader + Send + Sync>;
async fn unbind_remote_stream(&self, info: &StreamInfo);
async fn close(&self) -> Result<()>;
}
#[async_trait]
pub trait RTPWriter {
async fn write(&self, pkt: &rtp::packet::Packet, attributes: &Attributes) -> Result<usize>;
}
pub type RTPWriterBoxFn = Box<
dyn (Fn(
&rtp::packet::Packet,
&Attributes,
) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + Sync>>)
+ Send
+ Sync,
>;
pub struct RTPWriterFn(pub RTPWriterBoxFn);
#[async_trait]
impl RTPWriter for RTPWriterFn {
async fn write(&self, pkt: &rtp::packet::Packet, attributes: &Attributes) -> Result<usize> {
self.0(pkt, attributes).await
}
}
#[async_trait]
pub trait RTPReader {
async fn read(
&self,
buf: &mut [u8],
attributes: &Attributes,
) -> Result<(rtp::packet::Packet, Attributes)>;
}
pub type RTPReaderBoxFn = Box<
dyn (Fn(
&mut [u8],
&Attributes,
)
-> Pin<Box<dyn Future<Output = Result<(rtp::packet::Packet, Attributes)>> + Send + Sync>>)
+ Send
+ Sync,
>;
pub struct RTPReaderFn(pub RTPReaderBoxFn);
#[async_trait]
impl RTPReader for RTPReaderFn {
async fn read(
&self,
buf: &mut [u8],
attributes: &Attributes,
) -> Result<(rtp::packet::Packet, Attributes)> {
self.0(buf, attributes).await
}
}
#[async_trait]
pub trait RTCPWriter {
async fn write(
&self,
pkts: &[Box<dyn rtcp::packet::Packet + Send + Sync>],
attributes: &Attributes,
) -> Result<usize>;
}
pub type RTCPWriterBoxFn = Box<
dyn (Fn(
&[Box<dyn rtcp::packet::Packet + Send + Sync>],
&Attributes,
) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + Sync>>)
+ Send
+ Sync,
>;
pub struct RTCPWriterFn(pub RTCPWriterBoxFn);
#[async_trait]
impl RTCPWriter for RTCPWriterFn {
async fn write(
&self,
pkts: &[Box<dyn rtcp::packet::Packet + Send + Sync>],
attributes: &Attributes,
) -> Result<usize> {
self.0(pkts, attributes).await
}
}
#[async_trait]
pub trait RTCPReader {
async fn read(
&self,
buf: &mut [u8],
attributes: &Attributes,
) -> Result<(Vec<Box<dyn rtcp::packet::Packet + Send + Sync>>, Attributes)>;
}
pub type RTCPReaderBoxFn = Box<
dyn (Fn(
&mut [u8],
&Attributes,
) -> Pin<
Box<
dyn Future<
Output = Result<(
Vec<Box<dyn rtcp::packet::Packet + Send + Sync>>,
Attributes,
)>,
> + Send
+ Sync,
>,
>) + Send
+ Sync,
>;
pub struct RTCPReaderFn(pub RTCPReaderBoxFn);
#[async_trait]
impl RTCPReader for RTCPReaderFn {
async fn read(
&self,
buf: &mut [u8],
attributes: &Attributes,
) -> Result<(Vec<Box<dyn rtcp::packet::Packet + Send + Sync>>, Attributes)> {
self.0(buf, attributes).await
}
}
#[cfg(test)]
mod test {
use std::future::Future;
use std::time::Duration;
pub async fn timeout_or_fail<T>(duration: Duration, future: T) -> T::Output
where
T: Future,
{
tokio::time::timeout(duration, future)
.await
.expect("should not time out")
}
}