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