@@ -16,11 +16,14 @@ defmodule Membrane.WebRTC.Sink do
1616 the track received in `t:new_tracks/0` notification.
1717 """
1818 use Membrane.Bin
19+ require Membrane.Logger
1920
2021 alias Membrane.H264
2122 alias Membrane.RemoteStream
2223 alias Membrane.VP8
23- alias Membrane.WebRTC . { ExWebRTCSink , ForwardingFilter , SignalingChannel , SimpleWebSocketServer }
24+ alias Membrane.WebRTC . { ExWebRTCSink , ExWebRTCUtils , ForwardingFilter , SignalingChannel , SimpleWebSocketServer }
25+
26+ # alias __MODULE__.PayloadTypeSetter
2427
2528 @ typedoc """
2629 Notification that should be sent to the bin to negotiate new tracks.
@@ -132,7 +135,7 @@ defmodule Membrane.WebRTC.Sink do
132135 end
133136
134137 @ impl true
135- def handle_pad_added ( Pad . ref ( :input , pid ) = pad_ref , % { pad_options: % { kind: kind } } , state ) do
138+ def handle_pad_added ( Pad . ref ( :input , id ) = pad_ref , % { pad_options: % { kind: kind } } , state ) do
136139 spec =
137140 cond do
138141 not state . payload_rtp ->
@@ -141,9 +144,11 @@ defmodule Membrane.WebRTC.Sink do
141144 |> get_child ( :webrtc )
142145
143146 kind == :audio ->
147+ payload_type = ExWebRTCUtils . codec_payload_type ( :opus )
148+
144149 bin_input ( pad_ref )
145- |> child ( { :rtp_opus_payloader , pid } , Membrane.RTP.Opus.Payloader )
146- |> via_in ( pad_ref , options: [ kind: :audio ] )
150+ |> child ( { :rtp_opus_payloader , id } , Membrane.RTP.Opus.Payloader )
151+ |> via_in ( pad_ref , options: [ kind: :audio , payload_type: payload_type ] )
147152 |> get_child ( :webrtc )
148153
149154 kind == :video ->
@@ -161,17 +166,19 @@ defmodule Membrane.WebRTC.Sink do
161166 _ctx ,
162167 state
163168 ) do
164- payoader =
169+ { payloader , codec } =
165170 case stream_format do
166- % H264 { } -> % Membrane.RTP.H264.Payloader { max_payload_size: 1000 }
167- % VP8 { } -> Membrane.RTP.VP8.Payloader
168- % RemoteStream { content_format: VP8 } -> Membrane.RTP.VP8.Payloader
171+ % H264 { } -> { % Membrane.RTP.H264.Payloader { max_payload_size: 1000 } , :h264 }
172+ % VP8 { } -> { Membrane.RTP.VP8.Payloader , :vp8 }
173+ % RemoteStream { content_format: VP8 } -> { Membrane.RTP.VP8.Payloader , :vp8 }
169174 end
170175
176+ payload_type = ExWebRTCUtils . codec_payload_type ( codec )
177+
171178 spec =
172179 get_child ( { :forwarding_filter , pad_ref } )
173- |> child ( { :rtp_payloader , pad_ref } , payoader )
174- |> via_in ( pad_ref , options: [ kind: :video ] )
180+ |> child ( { :rtp_payloader , pad_ref } , payloader )
181+ |> via_in ( pad_ref , options: [ kind: :video , payload_type: payload_type ] )
175182 |> get_child ( :webrtc )
176183
177184 { [ spec: spec ] , state }
@@ -183,9 +190,24 @@ defmodule Membrane.WebRTC.Sink do
183190 end
184191
185192 @ impl true
186- def handle_child_notification ( { type , _content } = notification , :webrtc , _ctx , state )
187- when type in [ :new_tracks , :negotiated_video_codecs ] do
188- { [ notify_parent: notification ] , state }
193+ def handle_child_notification ( { :negotiated_video_codecs , codecs } , :webrtc , _ctx , state ) do
194+ if length ( codecs ) > 2 and state . payload_rtp do
195+ Membrane.Logger . warning ( """
196+ Negotiated more then one video codec (#{ inspect ( codecs ) } ), while this bin will receive `Membrane.RTP` \
197+ packets on the input, with no information about codecs used to encode video streams. \
198+ Lack of this information might lead to setting inapropriate payload type of RTP packets and further \
199+ errors.
200+
201+ You can fix this problem by setting `:video_codec` option to `:vp8` or to `:h264`.
202+ """ )
203+ end
204+
205+ { [ notify_parent: { :negotiated_video_codecs , codecs } ] , state }
206+ end
207+
208+ @ impl true
209+ def handle_child_notification ( { :new_tracks , new_tracks } , :webrtc , _ctx , state ) do
210+ { [ notify_parent: { :new_tracks , new_tracks } ] , state }
189211 end
190212
191213 @ impl true
0 commit comments