@@ -8,6 +8,30 @@ import (
8
8
"strings"
9
9
)
10
10
11
+ var defaultClockRates = map [string ]uint32 {
12
+ "audio/opus" : 48000 ,
13
+ "audio/pcmu" : 8000 ,
14
+ "audio/pcma" : 8000 ,
15
+ }
16
+
17
+ var defaultChannelCounts = map [string ]uint16 {
18
+ "audio/opus" : 2 ,
19
+ }
20
+
21
+ func defaultClockRate (mimeType string ) uint32 {
22
+ if def , ok := defaultClockRates [strings .ToLower (mimeType )]; ok {
23
+ return def
24
+ }
25
+ return 90000
26
+ }
27
+
28
+ func defaultChannelCount (mimeType string ) uint16 {
29
+ if def , ok := defaultChannelCounts [strings .ToLower (mimeType )]; ok {
30
+ return def
31
+ }
32
+ return 0
33
+ }
34
+
11
35
func parseParameters (line string ) map [string ]string {
12
36
parameters := make (map [string ]string )
13
37
@@ -24,6 +48,61 @@ func parseParameters(line string) map[string]string {
24
48
return parameters
25
49
}
26
50
51
+ // ClockRateEqual checks whether two clock rates are equal.
52
+ func ClockRateEqual (mimeType string , valA , valB uint32 ) bool {
53
+ // Lots of users use formats without setting clock rate or channels.
54
+ // In this case, use default values.
55
+ // It would be better to remove this exception in a future major release.
56
+ if valA == 0 {
57
+ valA = defaultClockRate (mimeType )
58
+ }
59
+ if valB == 0 {
60
+ valB = defaultClockRate (mimeType )
61
+ }
62
+
63
+ return valA == valB
64
+ }
65
+
66
+ // ChannelsEqual checks whether two channels are equal.
67
+ func ChannelsEqual (mimeType string , valA , valB uint16 ) bool {
68
+ // Lots of users use formats without setting clock rate or channels.
69
+ // In this case, use default values.
70
+ // It would be better to remove this exception in a future major release.
71
+ if valA == 0 {
72
+ valA = defaultChannelCount (mimeType )
73
+ }
74
+ if valB == 0 {
75
+ valB = defaultChannelCount (mimeType )
76
+ }
77
+
78
+ // RFC8866: channel count "is OPTIONAL and may be omitted
79
+ // if the number of channels is one".
80
+ if valA == 0 {
81
+ valA = 1
82
+ }
83
+ if valB == 0 {
84
+ valB = 1
85
+ }
86
+
87
+ return valA == valB
88
+ }
89
+
90
+ func paramsEqual (valA , valB map [string ]string ) bool {
91
+ for k , v := range valA {
92
+ if vb , ok := valB [k ]; ok && ! strings .EqualFold (vb , v ) {
93
+ return false
94
+ }
95
+ }
96
+
97
+ for k , v := range valB {
98
+ if va , ok := valA [k ]; ok && ! strings .EqualFold (va , v ) {
99
+ return false
100
+ }
101
+ }
102
+
103
+ return true
104
+ }
105
+
27
106
// FMTP interface for implementing custom
28
107
// FMTP parsers based on MimeType.
29
108
type FMTP interface {
@@ -39,7 +118,7 @@ type FMTP interface {
39
118
}
40
119
41
120
// Parse parses an fmtp string based on the MimeType.
42
- func Parse (mimeType , line string ) FMTP {
121
+ func Parse (mimeType string , clockRate uint32 , channels uint16 , line string ) FMTP {
43
122
var fmtp FMTP
44
123
45
124
parameters := parseParameters (line )
@@ -63,6 +142,8 @@ func Parse(mimeType, line string) FMTP {
63
142
default :
64
143
fmtp = & genericFMTP {
65
144
mimeType : mimeType ,
145
+ clockRate : clockRate ,
146
+ channels : channels ,
66
147
parameters : parameters ,
67
148
}
68
149
}
@@ -72,6 +153,8 @@ func Parse(mimeType, line string) FMTP {
72
153
73
154
type genericFMTP struct {
74
155
mimeType string
156
+ clockRate uint32
157
+ channels uint16
75
158
parameters map [string ]string
76
159
}
77
160
@@ -87,23 +170,10 @@ func (g *genericFMTP) Match(b FMTP) bool {
87
170
return false
88
171
}
89
172
90
- if ! strings .EqualFold (g .mimeType , fmtp .MimeType ()) {
91
- return false
92
- }
93
-
94
- for k , v := range g .parameters {
95
- if vb , ok := fmtp .parameters [k ]; ok && ! strings .EqualFold (vb , v ) {
96
- return false
97
- }
98
- }
99
-
100
- for k , v := range fmtp .parameters {
101
- if va , ok := g .parameters [k ]; ok && ! strings .EqualFold (va , v ) {
102
- return false
103
- }
104
- }
105
-
106
- return true
173
+ return strings .EqualFold (g .mimeType , fmtp .MimeType ()) &&
174
+ ClockRateEqual (g .mimeType , g .clockRate , fmtp .clockRate ) &&
175
+ ChannelsEqual (g .mimeType , g .channels , fmtp .channels ) &&
176
+ paramsEqual (g .parameters , fmtp .parameters )
107
177
}
108
178
109
179
func (g * genericFMTP ) Parameter (key string ) (string , bool ) {
0 commit comments