@@ -61,12 +61,11 @@ func OfferCodecsWith(s *media.CodecSet) []CodecInfo {
6161 codecs := s .ListEnabled ()
6262 slices .SortFunc (codecs , func (a , b media.Codec ) int {
6363 ai , bi := a .Info (), b .Info ()
64- if ai .RTPIsStatic != bi .RTPIsStatic {
65- if ai .RTPIsStatic {
66- return - 1
67- } else if bi .RTPIsStatic {
68- return 1
64+ if ai .Priority == bi .Priority {
65+ if ai .SampleRate != bi .SampleRate {
66+ return bi .SampleRate - ai .SampleRate
6967 }
68+ return strings .Compare (ai .SDPName , bi .SDPName )
7069 }
7170 return bi .Priority - ai .Priority
7271 })
@@ -128,15 +127,22 @@ func OfferMediaWith(s *media.CodecSet, rtpListenerPort int, encrypted Encryption
128127 formats := make ([]string , 0 , len (codecs ))
129128 dtmfType := byte (0 )
130129 for _ , codec := range codecs {
131- if codec .Codec .Info ().SDPName == dtmf .SDPNameAndRate {
130+ ci := codec .Codec .Info ()
131+ if ci .SDPName == dtmf .SDPNameAndRate {
132132 dtmfType = codec .Type
133133 }
134134 styp := strconv .Itoa (int (codec .Type ))
135135 formats = append (formats , styp )
136136 attrs = append (attrs , sdp.Attribute {
137137 Key : "rtpmap" ,
138- Value : styp + " " + codec . Codec . Info () .SDPName ,
138+ Value : styp + " " + ci .SDPName ,
139139 })
140+ if len (ci .ReqParams ) != 0 {
141+ attrs = append (attrs , sdp.Attribute {
142+ Key : "fmtp" ,
143+ Value : styp + " " + ci .ReqParams .String (),
144+ })
145+ }
140146 }
141147 if dtmfType > 0 {
142148 attrs = append (attrs , sdp.Attribute {
@@ -190,10 +196,16 @@ func AnswerMedia(rtpListenerPort int, audio *AudioConfig, crypt *srtp.Profile) *
190196 // Static compiler check for frame duration hardcoded below.
191197 var _ = [1 ]struct {}{}[20 * time .Millisecond - rtp .DefFrameDur ]
192198
193- attrs := make ([]sdp.Attribute , 0 , 6 )
199+ attrs := make ([]sdp.Attribute , 0 , 7 )
200+ ac := audio .Codec .Info ()
194201 attrs = append (attrs , sdp.Attribute {
195- Key : "rtpmap" , Value : fmt .Sprintf ("%d %s" , audio .Type , audio . Codec . Info () .SDPName ),
202+ Key : "rtpmap" , Value : fmt .Sprintf ("%d %s" , audio .Type , ac .SDPName ),
196203 })
204+ if len (ac .ReqParams ) != 0 {
205+ attrs = append (attrs , sdp.Attribute {
206+ Key : "fmtp" , Value : fmt .Sprintf ("%d %s" , audio .Type , ac .ReqParams .String ()),
207+ })
208+ }
197209 formats := make ([]string , 0 , 2 )
198210 formats = append (formats , strconv .Itoa (int (audio .Type )))
199211 if audio .DTMFType != 0 {
@@ -642,7 +654,25 @@ func parseSRTPProfile(val string) (*srtp.Profile, error) {
642654
643655// ParseMediaWith parses SDP media description based on the given codec set.
644656func ParseMediaWith (s * media.CodecSet , d * sdp.MediaDescription ) (* MediaDesc , error ) {
645- var out MediaDesc
657+ type codecInfo struct {
658+ Type int
659+ Name string
660+ Params media.CodecParams
661+ }
662+ var (
663+ out MediaDesc
664+ codecs []* codecInfo
665+ )
666+ getCodec := func (typ int ) * codecInfo {
667+ for _ , c := range codecs {
668+ if c .Type == typ {
669+ return c
670+ }
671+ }
672+ c := & codecInfo {Type : typ }
673+ codecs = append (codecs , c )
674+ return c
675+ }
646676 for _ , m := range d .Attributes {
647677 switch m .Key {
648678 case "rtpmap" :
@@ -659,11 +689,26 @@ func ParseMediaWith(s *media.CodecSet, d *sdp.MediaDescription) (*MediaDesc, err
659689 out .DTMFType = byte (typ )
660690 continue
661691 }
662- codec , _ := CodecByNameWith (s , name ).(media.AudioCodec )
663- out .Codecs = append (out .Codecs , CodecInfo {
664- Type : byte (typ ),
665- Codec : codec ,
666- })
692+ c := getCodec (typ )
693+ c .Name = name
694+ case "fmtp" :
695+ sub := strings .SplitN (m .Value , " " , 2 )
696+ if len (sub ) != 2 {
697+ continue
698+ }
699+ typ , err := strconv .Atoi (sub [0 ])
700+ if err != nil {
701+ continue
702+ }
703+ c := getCodec (typ )
704+ for _ , par := range strings .Split (sub [1 ], ";" ) {
705+ p := media.CodecParam {Key : par }
706+ if i := strings .IndexByte (par , '=' ); i >= 0 {
707+ p .Key = par [:i ]
708+ p .Val = par [i + 1 :]
709+ }
710+ c .Params = append (c .Params , p )
711+ }
667712 case "crypto" :
668713 p , err := parseSRTPProfile (m .Value )
669714 if err != nil {
@@ -685,12 +730,21 @@ func ParseMediaWith(s *media.CodecSet, d *sdp.MediaDescription) (*MediaDesc, err
685730 if err != nil {
686731 continue
687732 }
688- codec , _ := rtp .CodecByPayloadType (byte (typ )).(media.AudioCodec )
689- if ! s .IsEnabled (codec ) {
690- codec = nil
733+ c := getCodec (typ )
734+ _ = c // just add
735+ }
736+ for _ , ci := range codecs {
737+ var codec media.AudioCodec
738+ if ci .Name != "" {
739+ codec , _ = CodecByNameWith (s , ci .Name , ci .Params ).(media.AudioCodec )
740+ } else {
741+ codec , _ = rtp .CodecByPayloadType (byte (ci .Type )).(media.AudioCodec )
742+ if ! s .IsEnabled (codec ) {
743+ codec = nil
744+ }
691745 }
692746 out .Codecs = append (out .Codecs , CodecInfo {
693- Type : byte (typ ),
747+ Type : byte (ci . Type ),
694748 Codec : codec ,
695749 })
696750 }
0 commit comments