@@ -4,6 +4,7 @@ defmodule ExWebRTC.RTPSender do
4
4
"""
5
5
require Logger
6
6
7
+ alias ExWebRTC.PeerConnection.Configuration
7
8
alias ExRTCP.Packet . { TransportFeedback.NACK , PayloadFeedback.PLI }
8
9
alias ExWebRTC . { MediaStreamTrack , RTPCodecParameters , Utils }
9
10
alias ExSDP.Attribute.Extmap
@@ -22,8 +23,6 @@ defmodule ExWebRTC.RTPSender do
22
23
codecs: [ RTPCodecParameters . t ( ) ] ,
23
24
rtp_hdr_exts: % { Extmap . extension_id ( ) => Extmap . t ( ) } ,
24
25
mid: String . t ( ) | nil ,
25
- pt: non_neg_integer ( ) | nil ,
26
- rtx_pt: non_neg_integer ( ) | nil ,
27
26
# ssrc and rtx_ssrc are always present, even if there is no track,
28
27
# or transceiver direction is recvonly.
29
28
# We preallocate them so they can be included in SDP when needed.
@@ -81,15 +80,8 @@ defmodule ExWebRTC.RTPSender do
81
80
# convert to a map to be able to find extension id using extension uri
82
81
rtp_hdr_exts = Map . new ( rtp_hdr_exts , fn extmap -> { extmap . uri , extmap } end )
83
82
84
- # We always only take one codec to avoid ambiguity when assigning payload type for RTP packets.
85
- # In other case, if PeerConnection negotiated multiple codecs,
86
- # user would have to pass RTP codec when sending RTP packets,
87
- # or assign payload type on their own.
88
- { codec , rtx_codec } = get_default_codec ( codecs )
89
-
90
83
# TODO: handle cases when codec == nil (no valid codecs after negotiation)
91
- pt = if codec != nil , do: codec . payload_type , else: nil
92
- rtx_pt = if rtx_codec != nil , do: rtx_codec . payload_type , else: nil
84
+ { codec , rtx_codec } = get_default_codec ( codecs )
93
85
94
86
% {
95
87
id: Utils . generate_id ( ) ,
@@ -98,8 +90,6 @@ defmodule ExWebRTC.RTPSender do
98
90
rtx_codec: rtx_codec ,
99
91
codecs: codecs ,
100
92
rtp_hdr_exts: rtp_hdr_exts ,
101
- pt: pt ,
102
- rtx_pt: rtx_pt ,
103
93
ssrc: ssrc ,
104
94
rtx_ssrc: rtx_ssrc ,
105
95
mid: mid ,
@@ -126,42 +116,37 @@ defmodule ExWebRTC.RTPSender do
126
116
127
117
# Keep already selected codec if it is still supported.
128
118
# Otherwise, clear it and wait until user sets it again.
129
- codec = if sender . codec in codecs , do: sender . codec , else: nil
119
+ # TODO: handle cases when codec == nil (no valid codecs after negotiation)
120
+ codec = if supported? ( codecs , sender . codec ) , do: sender . codec , else: nil
130
121
rtx_codec = codec && find_associated_rtx_codec ( codecs , codec )
131
122
132
123
log_codec_change ( sender , codec , codecs )
133
124
log_rtx_codec_change ( sender , rtx_codec , codecs )
134
125
135
- # TODO: handle cases when codec == nil (no valid codecs after negotiation)
136
- pt = if codec != nil , do: codec . payload_type , else: nil
137
- rtx_pt = if rtx_codec != nil , do: rtx_codec . payload_type , else: nil
138
-
139
126
% {
140
127
sender
141
128
| mid: mid ,
142
129
codec: codec ,
143
130
rtx_codec: rtx_codec ,
144
131
codecs: codecs ,
145
- rtp_hdr_exts: rtp_hdr_exts ,
146
- pt: pt ,
147
- rtx_pt: rtx_pt
132
+ rtp_hdr_exts: rtp_hdr_exts
148
133
}
149
134
end
150
135
151
136
defp log_codec_change ( % { codec: codec } = sender , nil , neg_codecs ) when codec != nil do
152
- Logger . debug ( """
137
+ Logger . warning ( """
153
138
Unselecting RTP sender codec as it is no longer supported by the remote side.
154
139
Call set_sender_codec again passing supported codec.
155
- Codec: #{ inspect ( sender . codec ) }
156
- Currently negotiated codecs: #{ inspect ( neg_codecs ) }
140
+ Codec: #{ inspect ( sender . codec , pretty: true ) }
141
+ Currently negotiated codecs: #{ inspect ( neg_codecs , pretty: true ) }
157
142
""" )
158
143
end
159
144
160
145
defp log_codec_change ( _sender , _codec , _neg_codecs ) , do: :ok
161
146
162
147
defp log_rtx_codec_change ( % { rtx_codec: rtx_codec } = sender , nil , neg_codecs )
163
148
when rtx_codec != nil do
164
- Logger . debug ( """
149
+ Logger . warning ( """
165
150
Unselecting RTP sender codec as it is no longer supported by the remote side.
166
151
Call set_sender_codec again passing supported codec.
167
152
Codec: #{ inspect ( sender . codec ) }
@@ -186,18 +171,18 @@ defmodule ExWebRTC.RTPSender do
186
171
end
187
172
188
173
ssrc_attrs =
189
- get_ssrc_attrs ( sender . pt , sender . rtx_pt , sender . ssrc , sender . rtx_ssrc , sender . track )
174
+ get_ssrc_attrs ( sender . codec , sender . rtx_codec , sender . ssrc , sender . rtx_ssrc , sender . track )
190
175
191
176
msid_attrs ++ ssrc_attrs
192
177
end
193
178
194
179
# we didn't manage to negotiate any codec
195
- defp get_ssrc_attrs ( nil , _rtx_pt , _ssrc , _rtx_ssrc , _track ) do
180
+ defp get_ssrc_attrs ( nil , _rtx_codec , _ssrc , _rtx_ssrc , _track ) do
196
181
[ ]
197
182
end
198
183
199
- # we have a codec but not rtx
200
- defp get_ssrc_attrs ( _pt , nil , ssrc , _rtx_ssrc , track ) do
184
+ # we have a codec but not rtx codec
185
+ defp get_ssrc_attrs ( _codec , nil , ssrc , _rtx_ssrc , track ) do
201
186
streams = ( track && track . streams ) || [ ]
202
187
203
188
case streams do
@@ -211,8 +196,8 @@ defmodule ExWebRTC.RTPSender do
211
196
end
212
197
end
213
198
214
- # we have both codec and rtx
215
- defp get_ssrc_attrs ( _pt , _rtx_pt , ssrc , rtx_ssrc , track ) do
199
+ # we have both codec and rtx codec
200
+ defp get_ssrc_attrs ( _codec , _rtx_codec , ssrc , rtx_ssrc , track ) do
216
201
streams = ( track && track . streams ) || [ ]
217
202
218
203
fid = % ExSDP.Attribute.SSRCGroup { semantics: "FID" , ssrcs: [ ssrc , rtx_ssrc ] }
@@ -251,7 +236,7 @@ defmodule ExWebRTC.RTPSender do
251
236
@ doc false
252
237
@ spec set_codec ( sender ( ) , RTPCodecParameters . t ( ) ) :: { :ok , sender ( ) } | { :error , term ( ) }
253
238
def set_codec ( sender , codec ) do
254
- if not rtx? ( codec ) and supported? ( sender , codec ) and same_clock_rate? ( sender , codec ) do
239
+ if not rtx? ( codec ) and supported? ( sender . codecs , codec ) and same_clock_rate? ( sender , codec ) do
255
240
rtx_codec = find_associated_rtx_codec ( sender . codecs , codec )
256
241
sender = % { sender | codec: codec , rtx_codec: rtx_codec }
257
242
{ :ok , sender }
@@ -261,7 +246,13 @@ defmodule ExWebRTC.RTPSender do
261
246
end
262
247
263
248
defp rtx? ( codec ) , do: String . ends_with? ( codec . mime_type , "rtx" )
264
- defp supported? ( sender , codec ) , do: codec in sender . codecs
249
+
250
+ defp supported? ( neg_codecs , codec ) do
251
+ Enum . find ( neg_codecs , fn s_codec ->
252
+ Configuration . codec_equal? ( s_codec , codec ) and
253
+ MapSet . new ( s_codec . rtcp_fbs ) == MapSet . new ( codec . rtcp_fbs )
254
+ end ) != nil
255
+ end
265
256
266
257
# As long as report recorder is not initialized i.e. we have not sent any RTP packet,
267
258
# allow for codec changes. Once we start sending RTP packets, require the same clock rate.
@@ -271,12 +262,10 @@ defmodule ExWebRTC.RTPSender do
271
262
@ doc false
272
263
@ spec send_packet ( sender ( ) , ExRTP.Packet . t ( ) , boolean ( ) ) :: { binary ( ) , sender ( ) }
273
264
def send_packet ( % { rtx_codec: nil } = sender , _packet , true ) do
274
- Logger . warning ( "Tried to retransmit packet but there is no selected RTX codec. Ignoring." )
275
265
{ << >> , sender }
276
266
end
277
267
278
268
def send_packet ( % { codec: nil } = sender , _packet , false ) do
279
- Logger . warning ( "Tried to send packet but there is no selected codec. Ignoring." )
280
269
{ << >> , sender }
281
270
end
282
271
@@ -297,9 +286,9 @@ defmodule ExWebRTC.RTPSender do
297
286
def do_send_packet ( sender , packet , rtx? ) do
298
287
{ pt , ssrc } =
299
288
if rtx? do
300
- { sender . rtx_pt , sender . rtx_ssrc }
289
+ { sender . rtx_codec . payload_type , sender . rtx_ssrc }
301
290
else
302
- { sender . pt , sender . ssrc }
291
+ { sender . codec . payload_type , sender . ssrc }
303
292
end
304
293
305
294
packet = % { packet | payload_type: pt , ssrc: ssrc }
0 commit comments