@@ -19,6 +19,7 @@ defmodule ExWebRTC.RTPSender do
19
19
track: MediaStreamTrack . t ( ) | nil ,
20
20
codec: RTPCodecParameters . t ( ) | nil ,
21
21
rtx_codec: RTPCodecParameters . t ( ) | nil ,
22
+ selected_codec: RTPCodecParameters . t ( ) | nil ,
22
23
codecs: [ RTPCodecParameters . t ( ) ] ,
23
24
rtp_hdr_exts: % { Extmap . extension_id ( ) => Extmap . t ( ) } ,
24
25
mid: String . t ( ) | nil ,
@@ -66,32 +67,20 @@ defmodule ExWebRTC.RTPSender do
66
67
end
67
68
68
69
@ doc false
69
- @ spec new (
70
- MediaStreamTrack . t ( ) | nil ,
71
- [ RTPCodecParameters . t ( ) ] ,
72
- [ Extmap . t ( ) ] ,
73
- String . t ( ) | nil ,
74
- non_neg_integer ( ) ,
75
- non_neg_integer ( ) ,
76
- [ atom ( ) ]
77
- ) :: sender ( )
78
- def new ( track , codecs , rtp_hdr_exts , mid , ssrc , rtx_ssrc , features ) do
79
- # convert to a map to be able to find extension id using extension uri
80
- rtp_hdr_exts = Map . new ( rtp_hdr_exts , fn extmap -> { extmap . uri , extmap } end )
81
-
82
- # TODO: handle cases when codec == nil (no valid codecs after negotiation)
83
- { codec , rtx_codec } = get_default_codec ( codecs )
84
-
70
+ @ spec new ( MediaStreamTrack . t ( ) | nil , non_neg_integer ( ) , non_neg_integer ( ) , [ atom ( ) ] ) ::
71
+ sender ( )
72
+ def new ( track , ssrc , rtx_ssrc , features ) do
85
73
% {
86
74
id: Utils . generate_id ( ) ,
87
75
track: track ,
88
- codec: codec ,
89
- rtx_codec: rtx_codec ,
90
- codecs: codecs ,
91
- rtp_hdr_exts: rtp_hdr_exts ,
76
+ codec: nil ,
77
+ rtx_codec: nil ,
78
+ selected_codec: nil ,
79
+ codecs: [ ] ,
80
+ rtp_hdr_exts: % { } ,
92
81
ssrc: ssrc ,
93
82
rtx_ssrc: rtx_ssrc ,
94
- mid: mid ,
83
+ mid: nil ,
95
84
packets_sent: 0 ,
96
85
bytes_sent: 0 ,
97
86
retransmitted_packets_sent: 0 ,
@@ -113,11 +102,16 @@ defmodule ExWebRTC.RTPSender do
113
102
# convert to a map to be able to find extension id using extension uri
114
103
rtp_hdr_exts = Map . new ( rtp_hdr_exts , fn extmap -> { extmap . uri , extmap } end )
115
104
116
- # Keep already selected codec if it is still supported.
117
- # Otherwise, clear it and wait until user sets it again.
118
- # TODO: handle cases when codec == nil (no valid codecs after negotiation)
119
- codec = if supported? ( codecs , sender . codec ) , do: sender . codec , else: nil
120
- rtx_codec = codec && find_associated_rtx_codec ( codecs , codec )
105
+ { codec , rtx_codec } =
106
+ if sender . codec == nil and sender . selected_codec == nil do
107
+ get_default_codec ( codecs )
108
+ else
109
+ # Keep already selected codec if it is still supported.
110
+ # Otherwise, clear it and wait until user sets it again.
111
+ codec = if supported? ( codecs , sender . selected_codec ) , do: sender . selected_codec , else: nil
112
+ rtx_codec = codec && find_associated_rtx_codec ( codecs , codec )
113
+ { codec , rtx_codec }
114
+ end
121
115
122
116
log_codec_change ( sender , codec , codecs )
123
117
log_rtx_codec_change ( sender , rtx_codec , codecs )
@@ -127,6 +121,7 @@ defmodule ExWebRTC.RTPSender do
127
121
| mid: mid ,
128
122
codec: codec ,
129
123
rtx_codec: rtx_codec ,
124
+ selected_codec: codec || sender . selected_codec ,
130
125
codecs: codecs ,
131
126
rtp_hdr_exts: rtp_hdr_exts
132
127
}
@@ -135,7 +130,7 @@ defmodule ExWebRTC.RTPSender do
135
130
defp log_codec_change ( % { codec: codec } = sender , nil , neg_codecs ) when codec != nil do
136
131
Logger . warning ( """
137
132
Unselecting RTP sender codec as it is no longer supported by the remote side.
138
- Call set_sender_codec again passing supported codec.
133
+ Call set_sender_codec passing supported codec.
139
134
Codec: #{ inspect ( sender . codec ) }
140
135
Currently negotiated codecs: #{ inspect ( neg_codecs ) }
141
136
""" )
@@ -147,97 +142,20 @@ defmodule ExWebRTC.RTPSender do
147
142
when rtx_codec != nil do
148
143
Logger . warning ( """
149
144
Unselecting RTP sender RTX codec as it is no longer supported by the remote side.
150
- Call set_sender_codec again passing supported codec.
145
+ Call set_sender_codec passing supported codec.
151
146
Codec: #{ inspect ( sender . rtx_codec ) }
152
147
Currently negotiated codecs: #{ inspect ( neg_codecs ) }
153
148
""" )
154
149
end
155
150
156
151
defp log_rtx_codec_change ( _sender , _rtx_codec , _neg_codecs ) , do: :ok
157
152
158
- @ spec get_mline_attrs ( sender ( ) ) :: [ ExSDP.Attribute . t ( ) ]
159
- def get_mline_attrs ( sender ) do
160
- # Don't include track id. See RFC 8829 sec. 5.2.1
161
- msid_attrs =
162
- case sender . track do
163
- % MediaStreamTrack { streams: streams } when streams != [ ] ->
164
- Enum . map ( streams , & ExSDP.Attribute.MSID . new ( & 1 , nil ) )
165
-
166
- _other ->
167
- # In theory, we should do this "for each MediaStream that was associated with the transceiver",
168
- # but web browsers (chrome, ff) include MSID even when there aren't any MediaStreams
169
- [ ExSDP.Attribute.MSID . new ( "-" , nil ) ]
170
- end
171
-
172
- ssrc_attrs =
173
- get_ssrc_attrs ( sender . codec , sender . rtx_codec , sender . ssrc , sender . rtx_ssrc , sender . track )
174
-
175
- msid_attrs ++ ssrc_attrs
176
- end
177
-
178
- # we didn't manage to negotiate any codec
179
- defp get_ssrc_attrs ( nil , _rtx_codec , _ssrc , _rtx_ssrc , _track ) do
180
- [ ]
181
- end
182
-
183
- # we have a codec but not rtx codec
184
- defp get_ssrc_attrs ( _codec , nil , ssrc , _rtx_ssrc , track ) do
185
- streams = ( track && track . streams ) || [ ]
186
-
187
- case streams do
188
- [ ] ->
189
- [ % ExSDP.Attribute.SSRC { id: ssrc , attribute: "msid" , value: "-" } ]
190
-
191
- streams ->
192
- Enum . map ( streams , fn stream ->
193
- % ExSDP.Attribute.SSRC { id: ssrc , attribute: "msid" , value: stream }
194
- end )
195
- end
196
- end
197
-
198
- # we have both codec and rtx codec
199
- defp get_ssrc_attrs ( _codec , _rtx_codec , ssrc , rtx_ssrc , track ) do
200
- streams = ( track && track . streams ) || [ ]
201
-
202
- fid = % ExSDP.Attribute.SSRCGroup { semantics: "FID" , ssrcs: [ ssrc , rtx_ssrc ] }
203
-
204
- ssrc_attrs =
205
- case streams do
206
- [ ] ->
207
- [
208
- % ExSDP.Attribute.SSRC { id: ssrc , attribute: "msid" , value: "-" } ,
209
- % ExSDP.Attribute.SSRC { id: rtx_ssrc , attribute: "msid" , value: "-" }
210
- ]
211
-
212
- streams ->
213
- { ssrc_attrs , rtx_ssrc_attrs } =
214
- Enum . reduce ( streams , { [ ] , [ ] } , fn stream , { ssrc_attrs , rtx_ssrc_attrs } ->
215
- ssrc_attr = % ExSDP.Attribute.SSRC { id: ssrc , attribute: "msid" , value: stream }
216
- ssrc_attrs = [ ssrc_attr | ssrc_attrs ]
217
-
218
- rtx_ssrc_attr = % ExSDP.Attribute.SSRC {
219
- id: rtx_ssrc ,
220
- attribute: "msid" ,
221
- value: stream
222
- }
223
-
224
- rtx_ssrc_attrs = [ rtx_ssrc_attr | rtx_ssrc_attrs ]
225
-
226
- { ssrc_attrs , rtx_ssrc_attrs }
227
- end )
228
-
229
- Enum . reverse ( ssrc_attrs ) ++ Enum . reverse ( rtx_ssrc_attrs )
230
- end
231
-
232
- [ fid | ssrc_attrs ]
233
- end
234
-
235
153
@ doc false
236
154
@ spec set_codec ( sender ( ) , RTPCodecParameters . t ( ) ) :: { :ok , sender ( ) } | { :error , term ( ) }
237
155
def set_codec ( sender , codec ) do
238
156
if not rtx? ( codec ) and supported? ( sender . codecs , codec ) and same_clock_rate? ( sender , codec ) do
239
157
rtx_codec = find_associated_rtx_codec ( sender . codecs , codec )
240
- sender = % { sender | codec: codec , rtx_codec: rtx_codec }
158
+ sender = % { sender | codec: codec , rtx_codec: rtx_codec , selected_codec: codec }
241
159
{ :ok , sender }
242
160
else
243
161
{ :error , :invalid_codec }
0 commit comments