package webrtc
import (
"sync/atomic"
"github.com/pion/interceptor"
"github.com/pion/interceptor/pkg/flexfec"
"github.com/pion/interceptor/pkg/nack"
"github.com/pion/interceptor/pkg/report"
"github.com/pion/interceptor/pkg/rfc8888"
"github.com/pion/interceptor/pkg/twcc"
"github.com/pion/rtp"
"github.com/pion/sdp/v3"
)
func RegisterDefaultInterceptors (mediaEngine *MediaEngine , interceptorRegistry *interceptor .Registry ) error {
if err := ConfigureNack (mediaEngine , interceptorRegistry ); err != nil {
return err
}
if err := ConfigureRTCPReports (interceptorRegistry ); err != nil {
return err
}
if err := ConfigureSimulcastExtensionHeaders (mediaEngine ); err != nil {
return err
}
return ConfigureTWCCSender (mediaEngine , interceptorRegistry )
}
func ConfigureRTCPReports (interceptorRegistry *interceptor .Registry ) error {
reciver , err := report .NewReceiverInterceptor ()
if err != nil {
return err
}
sender , err := report .NewSenderInterceptor ()
if err != nil {
return err
}
interceptorRegistry .Add (reciver )
interceptorRegistry .Add (sender )
return nil
}
func ConfigureNack (mediaEngine *MediaEngine , interceptorRegistry *interceptor .Registry ) error {
generator , err := nack .NewGeneratorInterceptor ()
if err != nil {
return err
}
responder , err := nack .NewResponderInterceptor ()
if err != nil {
return err
}
mediaEngine .RegisterFeedback (RTCPFeedback {Type : "nack" }, RTPCodecTypeVideo )
mediaEngine .RegisterFeedback (RTCPFeedback {Type : "nack" , Parameter : "pli" }, RTPCodecTypeVideo )
interceptorRegistry .Add (responder )
interceptorRegistry .Add (generator )
return nil
}
func ConfigureTWCCHeaderExtensionSender (mediaEngine *MediaEngine , interceptorRegistry *interceptor .Registry ) error {
if err := mediaEngine .RegisterHeaderExtension (
RTPHeaderExtensionCapability {URI : sdp .TransportCCURI }, RTPCodecTypeVideo ,
); err != nil {
return err
}
if err := mediaEngine .RegisterHeaderExtension (
RTPHeaderExtensionCapability {URI : sdp .TransportCCURI }, RTPCodecTypeAudio ,
); err != nil {
return err
}
i , err := twcc .NewHeaderExtensionInterceptor ()
if err != nil {
return err
}
interceptorRegistry .Add (i )
return nil
}
func ConfigureTWCCSender (mediaEngine *MediaEngine , interceptorRegistry *interceptor .Registry ) error {
mediaEngine .RegisterFeedback (RTCPFeedback {Type : TypeRTCPFBTransportCC }, RTPCodecTypeVideo )
if err := mediaEngine .RegisterHeaderExtension (
RTPHeaderExtensionCapability {URI : sdp .TransportCCURI }, RTPCodecTypeVideo ,
); err != nil {
return err
}
mediaEngine .RegisterFeedback (RTCPFeedback {Type : TypeRTCPFBTransportCC }, RTPCodecTypeAudio )
if err := mediaEngine .RegisterHeaderExtension (
RTPHeaderExtensionCapability {URI : sdp .TransportCCURI }, RTPCodecTypeAudio ,
); err != nil {
return err
}
generator , err := twcc .NewSenderInterceptor ()
if err != nil {
return err
}
interceptorRegistry .Add (generator )
return nil
}
func ConfigureCongestionControlFeedback (mediaEngine *MediaEngine , interceptorRegistry *interceptor .Registry ) error {
mediaEngine .RegisterFeedback (RTCPFeedback {Type : TypeRTCPFBACK , Parameter : "ccfb" }, RTPCodecTypeVideo )
mediaEngine .RegisterFeedback (RTCPFeedback {Type : TypeRTCPFBACK , Parameter : "ccfb" }, RTPCodecTypeAudio )
generator , err := rfc8888 .NewSenderInterceptor ()
if err != nil {
return err
}
interceptorRegistry .Add (generator )
return nil
}
func ConfigureSimulcastExtensionHeaders (mediaEngine *MediaEngine ) error {
if err := mediaEngine .RegisterHeaderExtension (
RTPHeaderExtensionCapability {URI : sdp .SDESMidURI }, RTPCodecTypeVideo ,
); err != nil {
return err
}
if err := mediaEngine .RegisterHeaderExtension (
RTPHeaderExtensionCapability {URI : sdp .SDESRTPStreamIDURI }, RTPCodecTypeVideo ,
); err != nil {
return err
}
return mediaEngine .RegisterHeaderExtension (
RTPHeaderExtensionCapability {URI : sdp .SDESRepairRTPStreamIDURI }, RTPCodecTypeVideo ,
)
}
func ConfigureFlexFEC03 (
payloadType PayloadType ,
mediaEngine *MediaEngine ,
interceptorRegistry *interceptor .Registry ,
options ...flexfec .FecOption ,
) error {
codecFEC := RTPCodecParameters {
RTPCodecCapability : RTPCodecCapability {
MimeType : MimeTypeFlexFEC03 ,
ClockRate : 90000 ,
SDPFmtpLine : "repair-window=10000000" ,
RTCPFeedback : nil ,
},
PayloadType : payloadType ,
}
if err := mediaEngine .RegisterCodec (codecFEC , RTPCodecTypeVideo ); err != nil {
return err
}
generator , err := flexfec .NewFecInterceptor (options ...)
if err != nil {
return err
}
interceptorRegistry .Add (generator )
return nil
}
type interceptorToTrackLocalWriter struct { interceptor atomic .Value }
func (i *interceptorToTrackLocalWriter ) WriteRTP (header *rtp .Header , payload []byte ) (int , error ) {
if writer , ok := i .interceptor .Load ().(interceptor .RTPWriter ); ok && writer != nil {
return writer .Write (header , payload , interceptor .Attributes {})
}
return 0 , nil
}
func (i *interceptorToTrackLocalWriter ) Write (b []byte ) (int , error ) {
packet := &rtp .Packet {}
if err := packet .Unmarshal (b ); err != nil {
return 0 , err
}
return i .WriteRTP (&packet .Header , packet .Payload )
}
func createStreamInfo(
id string ,
ssrc , ssrcRTX , ssrcFEC SSRC ,
payloadType , payloadTypeRTX , payloadTypeFEC PayloadType ,
codec RTPCodecCapability ,
webrtcHeaderExtensions []RTPHeaderExtensionParameter ,
) *interceptor .StreamInfo {
headerExtensions := make ([]interceptor .RTPHeaderExtension , 0 , len (webrtcHeaderExtensions ))
for _ , h := range webrtcHeaderExtensions {
headerExtensions = append (headerExtensions , interceptor .RTPHeaderExtension {ID : h .ID , URI : h .URI })
}
feedbacks := make ([]interceptor .RTCPFeedback , 0 , len (codec .RTCPFeedback ))
for _ , f := range codec .RTCPFeedback {
feedbacks = append (feedbacks , interceptor .RTCPFeedback {Type : f .Type , Parameter : f .Parameter })
}
return &interceptor .StreamInfo {
ID : id ,
Attributes : interceptor .Attributes {},
SSRC : uint32 (ssrc ),
SSRCRetransmission : uint32 (ssrcRTX ),
SSRCForwardErrorCorrection : uint32 (ssrcFEC ),
PayloadType : uint8 (payloadType ),
PayloadTypeRetransmission : uint8 (payloadTypeRTX ),
PayloadTypeForwardErrorCorrection : uint8 (payloadTypeFEC ),
RTPHeaderExtensions : headerExtensions ,
MimeType : codec .MimeType ,
ClockRate : codec .ClockRate ,
Channels : codec .Channels ,
SDPFmtpLine : codec .SDPFmtpLine ,
RTCPFeedback : feedbacks ,
}
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .