github.com/pion/webrtc/v4@v4.0.1/rtpcodec.go (about) 1 // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly> 2 // SPDX-License-Identifier: MIT 3 4 package webrtc 5 6 import ( 7 "fmt" 8 "strings" 9 10 "github.com/pion/webrtc/v4/internal/fmtp" 11 ) 12 13 // RTPCodecType determines the type of a codec 14 type RTPCodecType int 15 16 const ( 17 // RTPCodecTypeUnknown is the enum's zero-value 18 RTPCodecTypeUnknown RTPCodecType = iota 19 20 // RTPCodecTypeAudio indicates this is an audio codec 21 RTPCodecTypeAudio 22 23 // RTPCodecTypeVideo indicates this is a video codec 24 RTPCodecTypeVideo 25 ) 26 27 func (t RTPCodecType) String() string { 28 switch t { 29 case RTPCodecTypeAudio: 30 return "audio" //nolint: goconst 31 case RTPCodecTypeVideo: 32 return "video" //nolint: goconst 33 default: 34 return ErrUnknownType.Error() 35 } 36 } 37 38 // NewRTPCodecType creates a RTPCodecType from a string 39 func NewRTPCodecType(r string) RTPCodecType { 40 switch { 41 case strings.EqualFold(r, RTPCodecTypeAudio.String()): 42 return RTPCodecTypeAudio 43 case strings.EqualFold(r, RTPCodecTypeVideo.String()): 44 return RTPCodecTypeVideo 45 default: 46 return RTPCodecType(0) 47 } 48 } 49 50 // RTPCodecCapability provides information about codec capabilities. 51 // 52 // https://w3c.github.io/webrtc-pc/#dictionary-rtcrtpcodeccapability-members 53 type RTPCodecCapability struct { 54 MimeType string 55 ClockRate uint32 56 Channels uint16 57 SDPFmtpLine string 58 RTCPFeedback []RTCPFeedback 59 } 60 61 // RTPHeaderExtensionCapability is used to define a RFC5285 RTP header extension supported by the codec. 62 // 63 // https://w3c.github.io/webrtc-pc/#dom-rtcrtpcapabilities-headerextensions 64 type RTPHeaderExtensionCapability struct { 65 URI string 66 } 67 68 // RTPHeaderExtensionParameter represents a negotiated RFC5285 RTP header extension. 69 // 70 // https://w3c.github.io/webrtc-pc/#dictionary-rtcrtpheaderextensionparameters-members 71 type RTPHeaderExtensionParameter struct { 72 URI string 73 ID int 74 } 75 76 // RTPCodecParameters is a sequence containing the media codecs that an RtpSender 77 // will choose from, as well as entries for RTX, RED and FEC mechanisms. This also 78 // includes the PayloadType that has been negotiated 79 // 80 // https://w3c.github.io/webrtc-pc/#rtcrtpcodecparameters 81 type RTPCodecParameters struct { 82 RTPCodecCapability 83 PayloadType PayloadType 84 85 statsID string 86 } 87 88 // RTPParameters is a list of negotiated codecs and header extensions 89 // 90 // https://w3c.github.io/webrtc-pc/#dictionary-rtcrtpparameters-members 91 type RTPParameters struct { 92 HeaderExtensions []RTPHeaderExtensionParameter 93 Codecs []RTPCodecParameters 94 } 95 96 type codecMatchType int 97 98 const ( 99 codecMatchNone codecMatchType = 0 100 codecMatchPartial codecMatchType = 1 101 codecMatchExact codecMatchType = 2 102 ) 103 104 // Do a fuzzy find for a codec in the list of codecs 105 // Used for lookup up a codec in an existing list to find a match 106 // Returns codecMatchExact, codecMatchPartial, or codecMatchNone 107 func codecParametersFuzzySearch(needle RTPCodecParameters, haystack []RTPCodecParameters) (RTPCodecParameters, codecMatchType) { 108 needleFmtp := fmtp.Parse(needle.RTPCodecCapability.MimeType, needle.RTPCodecCapability.SDPFmtpLine) 109 110 // First attempt to match on MimeType + SDPFmtpLine 111 for _, c := range haystack { 112 cfmtp := fmtp.Parse(c.RTPCodecCapability.MimeType, c.RTPCodecCapability.SDPFmtpLine) 113 if needleFmtp.Match(cfmtp) { 114 return c, codecMatchExact 115 } 116 } 117 118 // Fallback to just MimeType 119 for _, c := range haystack { 120 if strings.EqualFold(c.RTPCodecCapability.MimeType, needle.RTPCodecCapability.MimeType) { 121 return c, codecMatchPartial 122 } 123 } 124 125 return RTPCodecParameters{}, codecMatchNone 126 } 127 128 // Given a CodecParameters find the RTX CodecParameters if one exists 129 func findRTXPayloadType(needle PayloadType, haystack []RTPCodecParameters) PayloadType { 130 aptStr := fmt.Sprintf("apt=%d", needle) 131 for _, c := range haystack { 132 if aptStr == c.SDPFmtpLine { 133 return c.PayloadType 134 } 135 } 136 137 return PayloadType(0) 138 }