Skip to content

Commit 26f929d

Browse files
authored
Allow passing names of default codecs (#204)
1 parent bdbd9bd commit 26f929d

File tree

2 files changed

+106
-31
lines changed

2 files changed

+106
-31
lines changed

lib/ex_webrtc/peer_connection/configuration.ex

Lines changed: 83 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,44 @@ defmodule ExWebRTC.PeerConnection.Configuration do
1414
@rid_uri "urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id"
1515
@rrid_uri "urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id"
1616

17-
@default_audio_codecs [
18-
%RTPCodecParameters{
19-
payload_type: 111,
20-
mime_type: "audio/opus",
21-
clock_rate: 48_000,
22-
channels: 2
17+
@default_codec_params_opus %RTPCodecParameters{
18+
payload_type: 111,
19+
mime_type: "audio/opus",
20+
clock_rate: 48_000,
21+
channels: 2
22+
}
23+
24+
@default_codec_params_vp8 %RTPCodecParameters{
25+
payload_type: 96,
26+
mime_type: "video/VP8",
27+
clock_rate: 90_000
28+
}
29+
30+
# Ensure we are using H264 with packetization_mode=1 by default
31+
# (packetization_mode=0 has issues when switching layers)
32+
@default_codec_params_h264 %RTPCodecParameters{
33+
payload_type: 99,
34+
mime_type: "video/H264",
35+
clock_rate: 90_000,
36+
sdp_fmtp_line: %FMTP{
37+
pt: 99,
38+
level_asymmetry_allowed: true,
39+
packetization_mode: 1,
40+
profile_level_id: 0x42E01F
2341
}
24-
]
42+
}
43+
44+
@default_codec_params_av1 %RTPCodecParameters{
45+
payload_type: 45,
46+
mime_type: "video/AV1",
47+
clock_rate: 90_000,
48+
sdp_fmtp_line: %FMTP{pt: 45, level_idx: 5, profile: 0, tier: 0}
49+
}
50+
51+
@default_audio_codecs [@default_codec_params_opus]
2552

2653
@default_video_codecs [
27-
%RTPCodecParameters{
28-
payload_type: 96,
29-
mime_type: "video/VP8",
30-
clock_rate: 90_000
31-
},
54+
@default_codec_params_vp8,
3255
%RTPCodecParameters{
3356
payload_type: 98,
3457
mime_type: "video/H264",
@@ -40,25 +63,20 @@ defmodule ExWebRTC.PeerConnection.Configuration do
4063
profile_level_id: 0x42E01F
4164
}
4265
},
43-
%RTPCodecParameters{
44-
payload_type: 99,
45-
mime_type: "video/H264",
46-
clock_rate: 90_000,
47-
sdp_fmtp_line: %FMTP{
48-
pt: 99,
49-
level_asymmetry_allowed: true,
50-
packetization_mode: 1,
51-
profile_level_id: 0x42E01F
52-
}
53-
},
54-
%RTPCodecParameters{
55-
payload_type: 45,
56-
mime_type: "video/AV1",
57-
clock_rate: 90_000,
58-
sdp_fmtp_line: %FMTP{pt: 45, level_idx: 5, profile: 0, tier: 0}
59-
}
66+
@default_codec_params_h264,
67+
@default_codec_params_av1
6068
]
6169

70+
@typedoc """
71+
Allowed audio codec names which will get expanded to the relevant default `t:ExWebRTC.RTPCodecParameters.t/0`
72+
"""
73+
@type audio_codec_name :: :opus
74+
75+
@typedoc """
76+
Allowed video codec names which will get expanded to the relevant default `t:ExWebRTC.RTPCodecParameters.t/0`
77+
"""
78+
@type video_codec_name :: :vp8 | :h264 | :av1
79+
6280
@typedoc """
6381
ICE (STUN and/or TURN) server used to create the ICE connection.
6482
"""
@@ -142,6 +160,7 @@ defmodule ExWebRTC.PeerConnection.Configuration do
142160
* `audio_codecs` and `video_codecs` - lists of audio and video codecs to negotiate. By default these are equal to
143161
`default_audio_codecs/0` and `default_video_codecs/0`. To extend the list with your own codecs, do
144162
`audio_codecs: Configuration.default_audio_codecs() ++ my_codecs`.
163+
To use a subset of the default codecs, you can pass the atoms defined in `t:audio_codec_name/0` and `t:video_codec_name/0`.
145164
* `features` - feature flags for some of the ExWebRTC functinalities. Refer to `t:feature/0` for more information.
146165
* `rtp_header_extensions` - list of RTP header extensions to negotiate. Refer to `t:rtp_header_extension/0` for more information.
147166
* `rtcp_feedbacks` - list of RTCP feedbacks to negotiate. Refer to `t:rtcp_feedback/0` for more information.
@@ -162,8 +181,8 @@ defmodule ExWebRTC.PeerConnection.Configuration do
162181
ice_transport_policy: :relay | :all,
163182
ice_ip_filter: ICEAgent.ip_filter(),
164183
ice_port_range: Enumerable.t(non_neg_integer()),
165-
audio_codecs: [RTPCodecParameters.t()],
166-
video_codecs: [RTPCodecParameters.t()],
184+
audio_codecs: [RTPCodecParameters.t()] | [audio_codec_name()],
185+
video_codecs: [RTPCodecParameters.t()] | [video_codec_name()],
167186
features: [feature()],
168187
rtp_header_extensions: [rtp_header_extension()],
169188
rtcp_feedbacks: [rtcp_feedback()]
@@ -262,6 +281,7 @@ defmodule ExWebRTC.PeerConnection.Configuration do
262281
options
263282
|> Keyword.put(:audio_extensions, Enum.map(audio_extensions, fn {_, ext} -> ext end))
264283
|> Keyword.put(:video_extensions, Enum.map(video_extensions, fn {_, ext} -> ext end))
284+
|> expand_default_codecs()
265285
|> then(&struct(__MODULE__, &1))
266286
|> ensure_unique_payload_types()
267287
|> populate_feedbacks(feedbacks)
@@ -671,4 +691,36 @@ defmodule ExWebRTC.PeerConnection.Configuration do
671691
end
672692
end)
673693
end
694+
695+
@doc false
696+
@spec expand_default_codecs(options()) :: options()
697+
def expand_default_codecs(options) do
698+
options
699+
|> expand_default_codecs(:audio_codecs)
700+
|> expand_default_codecs(:video_codecs)
701+
end
702+
703+
defp expand_default_codecs(options, key) do
704+
codecs = Keyword.get(options, key, [])
705+
706+
cond do
707+
Enum.all?(codecs, &is_struct(&1, RTPCodecParameters)) ->
708+
options
709+
710+
Enum.all?(codecs, &is_atom/1) ->
711+
expanded_codecs = Enum.map(codecs, &expand_default_codec/1)
712+
Keyword.put(options, key, expanded_codecs)
713+
714+
true ->
715+
raise """
716+
#{inspect(key)} passed to PeerConnection cannot be mixed: either use only atoms, or only RTPCodecParameters.
717+
"""
718+
end
719+
end
720+
721+
defp expand_default_codec(:opus), do: @default_codec_params_opus
722+
defp expand_default_codec(:vp8), do: @default_codec_params_vp8
723+
defp expand_default_codec(:h264), do: @default_codec_params_h264
724+
defp expand_default_codec(:av1), do: @default_codec_params_av1
725+
defp expand_default_codec(other), do: raise("Unknown codec name: #{inspect(other)}")
674726
end

test/ex_webrtc/peer_connection/configuration_test.exs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,4 +504,27 @@ defmodule ExWebRTC.PeerConnection.ConfigurationTest do
504504
assert [twcc] = Configuration.intersect_extensions(config, video_mline)
505505
assert %Extmap{id: 5, uri: @twcc_uri} = twcc
506506
end
507+
508+
test "expand_default_codecs/1" do
509+
assert Configuration.expand_default_codecs([]) == []
510+
511+
og_options = [
512+
video_codecs: [@vp8_codec],
513+
audio_codecs: [@opus_codec]
514+
]
515+
516+
assert Configuration.expand_default_codecs(og_options) == og_options
517+
518+
[video_codecs: [vp8_params, h264_params]] =
519+
Configuration.expand_default_codecs(video_codecs: [:vp8, :h264])
520+
521+
assert vp8_params.mime_type == "video/VP8"
522+
assert h264_params.mime_type == "video/H264"
523+
524+
assert_raise RuntimeError, fn -> Configuration.expand_default_codecs(video_codecs: [:av2]) end
525+
526+
assert_raise RuntimeError, fn ->
527+
Configuration.expand_default_codecs(video_codecs: [:h264, @vp8_codec])
528+
end
529+
end
507530
end

0 commit comments

Comments
 (0)