@@ -15,8 +15,48 @@ type ccfbAttributesKeyType uint32
1515
1616const CCFBAttributesKey ccfbAttributesKeyType = iota
1717
18+ type history interface {
19+ add (seqNr uint16 , size uint16 , departure time.Time ) error
20+ getReportForAck (al acknowledgementList ) PacketReportList
21+ }
22+
1823type Option func (* Interceptor ) error
1924
25+ func HistorySize (size int ) Option {
26+ return func (i * Interceptor ) error {
27+ i .historySize = size
28+ return nil
29+ }
30+ }
31+
32+ func timeFactory (f func () time.Time ) Option {
33+ return func (i * Interceptor ) error {
34+ i .timestamp = f
35+ return nil
36+ }
37+ }
38+
39+ func historyFactory (f func (int ) history ) Option {
40+ return func (i * Interceptor ) error {
41+ i .historyFactory = f
42+ return nil
43+ }
44+ }
45+
46+ func ccfbConverterFactory (f func (ts time.Time , feedback * rtcp.CCFeedbackReport ) (time.Time , map [uint32 ]acknowledgementList )) Option {
47+ return func (i * Interceptor ) error {
48+ i .convertCCFB = f
49+ return nil
50+ }
51+ }
52+
53+ func twccConverterFactory (f func (ts time.Time , feedback * rtcp.TransportLayerCC ) (time.Time , map [uint32 ]acknowledgementList )) Option {
54+ return func (i * Interceptor ) error {
55+ i .convertTWCC = f
56+ return nil
57+ }
58+ }
59+
2060type InterceptorFactory struct {
2161 opts []Option
2262}
@@ -30,8 +70,15 @@ func NewInterceptor(opts ...Option) (*InterceptorFactory, error) {
3070func (f * InterceptorFactory ) NewInterceptor (_ string ) (interceptor.Interceptor , error ) {
3171 i := & Interceptor {
3272 NoOp : interceptor.NoOp {},
73+ lock : sync.Mutex {},
3374 timestamp : time .Now ,
34- ssrcToHistory : make (map [uint32 ]* history ),
75+ convertCCFB : convertCCFB ,
76+ convertTWCC : convertTWCC ,
77+ ssrcToHistory : make (map [uint32 ]history ),
78+ historySize : 200 ,
79+ historyFactory : func (size int ) history {
80+ return newHistoryList (size )
81+ },
3582 }
3683 for _ , opt := range f .opts {
3784 if err := opt (i ); err != nil {
@@ -43,9 +90,13 @@ func (f *InterceptorFactory) NewInterceptor(_ string) (interceptor.Interceptor,
4390
4491type Interceptor struct {
4592 interceptor.NoOp
46- lock sync.Mutex
47- timestamp func () time.Time
48- ssrcToHistory map [uint32 ]* history
93+ lock sync.Mutex
94+ timestamp func () time.Time
95+ convertCCFB func (ts time.Time , feedback * rtcp.CCFeedbackReport ) (time.Time , map [uint32 ]acknowledgementList )
96+ convertTWCC func (ts time.Time , feedback * rtcp.TransportLayerCC ) (time.Time , map [uint32 ]acknowledgementList )
97+ ssrcToHistory map [uint32 ]history
98+ historySize int
99+ historyFactory func (int ) history
49100}
50101
51102// BindLocalStream implements interceptor.Interceptor.
@@ -67,7 +118,7 @@ func (i *Interceptor) BindLocalStream(info *interceptor.StreamInfo, writer inter
67118 if useTWCC {
68119 ssrc = 0
69120 }
70- i .ssrcToHistory [ssrc ] = newHistory ( 200 )
121+ i .ssrcToHistory [ssrc ] = i . historyFactory ( i . historySize )
71122
72123 return interceptor .RTPWriterFunc (func (header * rtp.Header , payload []byte , attributes interceptor.Attributes ) (int , error ) {
73124 i .lock .Lock ()
@@ -109,14 +160,18 @@ func (i *Interceptor) BindRTCPReader(reader interceptor.RTCPReader) interceptor.
109160 pktReportLists := map [uint32 ]* PacketReportList {}
110161
111162 pkts , err := attr .GetRTCPPackets (buf )
163+ if err != nil {
164+ return n , attr , err
165+ }
112166 for _ , pkt := range pkts {
113167 var reportLists map [uint32 ]acknowledgementList
114168 var reportDeparture time.Time
115169 switch fb := pkt .(type ) {
116170 case * rtcp.CCFeedbackReport :
117- reportDeparture , reportLists = convertCCFB (now , fb )
171+ reportDeparture , reportLists = i . convertCCFB (now , fb )
118172 case * rtcp.TransportLayerCC :
119- reportDeparture , reportLists = convertTWCC (now , fb )
173+ reportDeparture , reportLists = i .convertTWCC (now , fb )
174+ default :
120175 }
121176 for ssrc , reportList := range reportLists {
122177 prl := i .ssrcToHistory [ssrc ].getReportForAck (reportList )
0 commit comments