Skip to content

Commit

Permalink
Add tests, fix some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
LVala committed Nov 10, 2023
1 parent 867df70 commit 225a042
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 24 deletions.
2 changes: 1 addition & 1 deletion lib/ex_webrtc/peer_connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ defmodule ExWebRTC.PeerConnection do
demuxer = %{
state.demuxer
| extensions: SDPUtils.get_extensions(sdp),
payload_types: SDPUtils.get_payload_types(sdp)
pt_to_mid: SDPUtils.get_payload_types(sdp)
}

dtls =
Expand Down
35 changes: 13 additions & 22 deletions lib/ex_webrtc/peer_connection/demuxer.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule ExWebRTC.PeerConnection.Demuxer do
alias ExRTP.Packet.Extension
alias ExRTP.Packet.Extension.SourceDescription

defstruct ssrcs: %{}, extensions: %{}, payload_types: %{}
defstruct ssrc_to_mid: %{}, extensions: %{}, pt_to_mid: %{}

def process_data(demuxer, data) do
with {:ok, %Packet{} = packet} <- decode(data),
Expand All @@ -15,14 +15,12 @@ defmodule ExWebRTC.PeerConnection.Demuxer do
end

# RFC 8843, 9.2
defp match_to_mid(demuxer, packet) do
with demuxer <- update_mapping(demuxer, packet),
:error <- match_by_extension(demuxer, packet),
:error <- match_by_payload_type(demuxer, packet) do
{:error, :unmatched_stream}
else
{:ok, mid} -> {:ok, demuxer, mid}
{:ok, _demuxer, _mid} = res -> res
defp match_to_mid(demuxer, %Packet{ssrc: ssrc} = packet) do
demuxer = update_mapping(demuxer, packet)

case Map.get(demuxer.ssrc_to_mid, ssrc) do
{last_mid, _last_sn} -> {:ok, demuxer, last_mid}
nil -> match_by_payload_type(demuxer, packet)
end
end

Expand All @@ -40,29 +38,22 @@ defmodule ExWebRTC.PeerConnection.Demuxer do
end
end)

case Map.get(demuxer.ssrcs, ssrc) do
case Map.get(demuxer.ssrc_to_mid, ssrc) do
{_last_mid, last_sn} when mid != nil and sn > last_sn ->
put_in(demuxer.ssrcs[ssrc], {mid, sn})
put_in(demuxer.ssrc_to_mid[ssrc], {mid, sn})

nil when mid != nil ->
put_in(demuxer.ssrcs[ssrc], {mid, sn})
put_in(demuxer.ssrc_to_mid[ssrc], {mid, sn})

_other ->
demuxer
end
end

defp match_by_extension(demuxer, %Packet{ssrc: ssrc}) do
case Map.get(demuxer.ssrcs, ssrc) do
{last_mid, _last_sn} -> {:ok, last_mid}
nil -> :error
end
end

defp match_by_payload_type(demuxer, %Packet{ssrc: ssrc, payload_type: pt}) do
case Map.get(demuxer.payload_types, pt) do
defp match_by_payload_type(demuxer, %Packet{ssrc: ssrc, payload_type: pt, sequence_number: sn}) do
case Map.get(demuxer.pt_to_mid, pt) do
nil -> :error
mid -> {:ok, put_in(demuxer.ssrcs[ssrc], mid), mid}
mid -> {:ok, put_in(demuxer.ssrc_to_mid[ssrc], {mid, sn}), mid}
end
end

Expand Down
2 changes: 1 addition & 1 deletion test/configuration_test.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule ExWebRTC.PeerConnection.ConfigurationTest do
use ExUnit.Case
use ExUnit.Case, async: true

alias ExWebRTC.{PeerConnection, RTPCodecParameters, RTPTransceiver, SessionDescription}

Expand Down
76 changes: 76 additions & 0 deletions test/peer_connection/demuxer_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
defmodule ExWebRTC.PeerConnection.DemuxerTest do
use ExUnit.Case, async: true

alias ExRTP.Packet
alias ExRTP.Packet.Extension
alias ExWebRTC.PeerConnection.Demuxer

@mid "1"

@sequence_number 500
@payload_type 111
@ssrc 333_333
@raw_packet %Packet{
payload_type: @payload_type,
sequence_number: @sequence_number,
timestamp: 0,
ssrc: @ssrc,
payload: <<>>
}

@packet Packet.encode(@raw_packet)
@packet_mid Packet.encode(
Packet.set_extension(@raw_packet, :two_byte, [%Extension{id: 15, data: @mid}])
)
@demuxer %Demuxer{extensions: %{15 => {Extension.SourceDescription, :mid}}}

test "ssrc already mapped and, without extension" do
seq_num = 1
demuxer = %Demuxer{@demuxer | ssrc_to_mid: %{@ssrc => {@mid, seq_num}}}

assert {:ok, new_demuxer, @mid, _packet} = Demuxer.process_data(demuxer, @packet)
assert new_demuxer == %Demuxer{demuxer | ssrc_to_mid: %{@ssrc => {@mid, seq_num}}}
end

test "ssrc already mapped, with extension with the same mid and bigger sequence number" do
demuxer = %Demuxer{@demuxer | ssrc_to_mid: %{@ssrc => {@mid, 1}}}

assert {:ok, new_demuxer, @mid, _packet} = Demuxer.process_data(demuxer, @packet_mid)
assert new_demuxer == %Demuxer{demuxer | ssrc_to_mid: %{@ssrc => {@mid, @sequence_number}}}
end

test "ssrc already mapped, with extension with new mid and smaller sequence number" do
seq_num = 600
mid = "2"
demuxer = %Demuxer{@demuxer | ssrc_to_mid: %{@ssrc => {mid, seq_num}}}

assert {:ok, new_demuxer, ^mid, _packet} = Demuxer.process_data(demuxer, @packet_mid)
assert new_demuxer == %Demuxer{demuxer | ssrc_to_mid: %{@ssrc => {mid, seq_num}}}
end

test "ssrc already mapped, with extension with new mid and bigger sequence number" do
seq_num = 1
mid = "2"
demuxer = %Demuxer{@demuxer | ssrc_to_mid: %{@ssrc => {mid, seq_num}}}

assert {:ok, new_demuxer, @mid, _packet} = Demuxer.process_data(demuxer, @packet_mid)
assert new_demuxer == %Demuxer{demuxer | ssrc_to_mid: %{@ssrc => {@mid, @sequence_number}}}
end

test "ssrc not mapped, with extension" do
assert {:ok, new_demuxer, @mid, _packet} = Demuxer.process_data(@demuxer, @packet_mid)
assert new_demuxer == %Demuxer{@demuxer | ssrc_to_mid: %{@ssrc => {@mid, @sequence_number}}}
end

test "ssrc not mapped, without extension, with unique payload type" do
mid = "2"
demuxer = %Demuxer{@demuxer | pt_to_mid: %{@payload_type => mid}}

assert {:ok, new_demuxer, ^mid, _packet} = Demuxer.process_data(demuxer, @packet)
assert new_demuxer == %Demuxer{demuxer | ssrc_to_mid: %{@ssrc => {mid, @sequence_number}}}
end

test "unmatchable ssrc" do
assert :error = Demuxer.process_data(@demuxer, @packet)
end
end

0 comments on commit 225a042

Please sign in to comment.