| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
- // SPDX-License-Identifier: MIT
- //go:build !js
- // +build !js
- package webrtc
- import (
- "sync/atomic"
- "github.com/pion/interceptor"
- "github.com/pion/interceptor/pkg/nack"
- "github.com/pion/interceptor/pkg/report"
- "github.com/pion/interceptor/pkg/twcc"
- "github.com/pion/rtp"
- "github.com/pion/sdp/v3"
- )
- // RegisterDefaultInterceptors will register some useful interceptors.
- // If you want to customize which interceptors are loaded, you should copy the
- // code from this method and remove unwanted interceptors.
- 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
- }
- return ConfigureTWCCSender(mediaEngine, interceptorRegistry)
- }
- // ConfigureRTCPReports will setup everything necessary for generating Sender and Receiver Reports
- 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
- }
- // ConfigureNack will setup everything necessary for handling generating/responding to nack messages.
- 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
- }
- // ConfigureTWCCHeaderExtensionSender will setup everything necessary for adding
- // a TWCC header extension to outgoing RTP packets. This will allow the remote peer to generate TWCC reports.
- 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
- }
- // ConfigureTWCCSender will setup everything necessary for generating TWCC reports.
- 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
- }
- type interceptorToTrackLocalWriter struct{ interceptor atomic.Value } // interceptor.RTPWriter }
- 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 SSRC, payloadType 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),
- PayloadType: uint8(payloadType),
- RTPHeaderExtensions: headerExtensions,
- MimeType: codec.MimeType,
- ClockRate: codec.ClockRate,
- Channels: codec.Channels,
- SDPFmtpLine: codec.SDPFmtpLine,
- RTCPFeedback: feedbacks,
- }
- }
|