xref: /webrtc/interceptor/src/chain.rs (revision ffe74184)
1 use crate::error::*;
2 use crate::stream_info::StreamInfo;
3 use crate::*;
4 
5 use std::sync::Arc;
6 
7 /// Chain is an interceptor that runs all child interceptors in order.
8 #[derive(Default)]
9 pub struct Chain {
10     interceptors: Vec<Arc<dyn Interceptor + Send + Sync>>,
11 }
12 
13 impl Chain {
14     /// new returns a new Chain interceptor.
new(interceptors: Vec<Arc<dyn Interceptor + Send + Sync>>) -> Self15     pub fn new(interceptors: Vec<Arc<dyn Interceptor + Send + Sync>>) -> Self {
16         Chain { interceptors }
17     }
18 
add(&mut self, icpr: Arc<dyn Interceptor + Send + Sync>)19     pub fn add(&mut self, icpr: Arc<dyn Interceptor + Send + Sync>) {
20         self.interceptors.push(icpr);
21     }
22 }
23 
24 #[async_trait]
25 impl Interceptor for Chain {
26     /// bind_rtcp_reader lets you modify any incoming RTCP packets. It is called once per sender/receiver, however this might
27     /// change in the future. The returned method will be called once per packet batch.
bind_rtcp_reader( &self, mut reader: Arc<dyn RTCPReader + Send + Sync>, ) -> Arc<dyn RTCPReader + Send + Sync>28     async fn bind_rtcp_reader(
29         &self,
30         mut reader: Arc<dyn RTCPReader + Send + Sync>,
31     ) -> Arc<dyn RTCPReader + Send + Sync> {
32         for icpr in &self.interceptors {
33             reader = icpr.bind_rtcp_reader(reader).await;
34         }
35         reader
36     }
37 
38     /// bind_rtcp_writer lets you modify any outgoing RTCP packets. It is called once per PeerConnection. The returned method
39     /// will be called once per packet batch.
bind_rtcp_writer( &self, mut writer: Arc<dyn RTCPWriter + Send + Sync>, ) -> Arc<dyn RTCPWriter + Send + Sync>40     async fn bind_rtcp_writer(
41         &self,
42         mut writer: Arc<dyn RTCPWriter + Send + Sync>,
43     ) -> Arc<dyn RTCPWriter + Send + Sync> {
44         for icpr in &self.interceptors {
45             writer = icpr.bind_rtcp_writer(writer).await;
46         }
47         writer
48     }
49 
50     /// bind_local_stream lets you modify any outgoing RTP packets. It is called once for per LocalStream. The returned method
51     /// will be called once per rtp packet.
bind_local_stream( &self, info: &StreamInfo, mut writer: Arc<dyn RTPWriter + Send + Sync>, ) -> Arc<dyn RTPWriter + Send + Sync>52     async fn bind_local_stream(
53         &self,
54         info: &StreamInfo,
55         mut writer: Arc<dyn RTPWriter + Send + Sync>,
56     ) -> Arc<dyn RTPWriter + Send + Sync> {
57         for icpr in &self.interceptors {
58             writer = icpr.bind_local_stream(info, writer).await;
59         }
60         writer
61     }
62 
63     /// unbind_local_stream is called when the Stream is removed. It can be used to clean up any data related to that track.
unbind_local_stream(&self, info: &StreamInfo)64     async fn unbind_local_stream(&self, info: &StreamInfo) {
65         for icpr in &self.interceptors {
66             icpr.unbind_local_stream(info).await;
67         }
68     }
69 
70     /// bind_remote_stream lets you modify any incoming RTP packets. It is called once for per RemoteStream. The returned method
71     /// will be called once per rtp packet.
bind_remote_stream( &self, info: &StreamInfo, mut reader: Arc<dyn RTPReader + Send + Sync>, ) -> Arc<dyn RTPReader + Send + Sync>72     async fn bind_remote_stream(
73         &self,
74         info: &StreamInfo,
75         mut reader: Arc<dyn RTPReader + Send + Sync>,
76     ) -> Arc<dyn RTPReader + Send + Sync> {
77         for icpr in &self.interceptors {
78             reader = icpr.bind_remote_stream(info, reader).await;
79         }
80         reader
81     }
82 
83     /// unbind_remote_stream is called when the Stream is removed. It can be used to clean up any data related to that track.
unbind_remote_stream(&self, info: &StreamInfo)84     async fn unbind_remote_stream(&self, info: &StreamInfo) {
85         for icpr in &self.interceptors {
86             icpr.unbind_remote_stream(info).await;
87         }
88     }
89 
90     /// close closes the Interceptor, cleaning up any data if necessary.
close(&self) -> Result<()>91     async fn close(&self) -> Result<()> {
92         let mut errs = vec![];
93         for icpr in &self.interceptors {
94             if let Err(err) = icpr.close().await {
95                 errs.push(err);
96             }
97         }
98         flatten_errs(errs)
99     }
100 }
101