Skip to content
This repository was archived by the owner on Sep 19, 2024. It is now read-only.

Commit 4dda8fa

Browse files
committed
Refactor code
1 parent a43e56c commit 4dda8fa

File tree

3 files changed

+82
-91
lines changed

3 files changed

+82
-91
lines changed

lib/membrane_rtc_engine/endpoints/webrtc/simulcast_tee.ex

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ defmodule Membrane.RTC.Engine.Endpoint.WebRTC.SimulcastTee do
3030
spec: String.t() | nil,
3131
default: nil,
3232
description: """
33-
TODO
33+
Initial encoding that should be sent via this pad.
34+
`nil` means that the best possible encoding should be used.
3435
"""
3536
]
3637
]

lib/membrane_rtc_engine/engine.ex

+70-74
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,10 @@ defmodule Membrane.RTC.Engine do
165165
Where `caps` are `t:Membrane.Caps.t/0` or `:any`.
166166
167167
* publish for some tracks using actions `t:publish_action_t/0` and subscribe for some tracks using
168-
function `#{inspect(__MODULE__)}.subscribe/3`. The first will cause RTC Engine to send a message in
168+
function `#{inspect(__MODULE__)}.subscribe/5`. The first will cause RTC Engine to send a message in
169169
form of `{:new_tracks, tracks}` where `tracks` is a list of `t:#{inspect(__MODULE__)}.Track.t/0` to all other Endpoints.
170170
When an Endpoint receives such a message it can subscribe for new tracks by
171-
using `#{inspect(__MODULE__)}.subscribe/3` function. An Endpoint will be notified about track readiness
171+
using `#{inspect(__MODULE__)}.subscribe/5` function. An Endpoint will be notified about track readiness
172172
it subscribed for in `c:Membrane.Bin.handle_pad_added/3` callback. An example implementation of `handle_pad_added`
173173
callback can look like this
174174
@@ -240,6 +240,14 @@ defmodule Membrane.RTC.Engine do
240240
node: node()
241241
]
242242

243+
@typedoc """
244+
Subscription options.
245+
246+
* `default_simulcast_encoding` - initial encoding that
247+
endpoint making subscription wants to receive
248+
"""
249+
@type subscription_opts_t() :: [default_simulcast_encoding: String.t()]
250+
243251
@typedoc """
244252
Membrane action that will cause RTC Engine to publish some message to all other endpoints.
245253
"""
@@ -406,8 +414,6 @@ defmodule Membrane.RTC.Engine do
406414
:ok
407415
end
408416

409-
@type subscription_opts_t() :: [default_simulcast_encoding: String.t()]
410-
411417
@doc """
412418
Subscribes endpoint for tracks.
413419
@@ -588,14 +594,12 @@ defmodule Membrane.RTC.Engine do
588594
endpoint_id: endpoint_id,
589595
track_id: track_id,
590596
format: format,
591-
opts: opts,
592-
status: :created
597+
opts: opts
593598
}
594599

595600
case check_subscription(subscription, state) do
596601
:ok ->
597602
{links, state} = try_fulfill_subscription(subscription, ctx, state)
598-
599603
parent_spec = %ParentSpec{links: links, log_metadata: [rtc: state.id]}
600604
send(endpoint_pid, {ref, :ok})
601605
{{:ok, [spec: parent_spec]}, state}
@@ -639,34 +643,6 @@ defmodule Membrane.RTC.Engine do
639643
{:ok, state}
640644
end
641645

642-
defp check_subscription(subscription, state) do
643-
# checks whether subscription is proper
644-
track =
645-
state.endpoints
646-
|> Map.values()
647-
|> Enum.flat_map(&Endpoint.get_tracks/1)
648-
|> Map.new(&{&1.id, &1})
649-
|> Map.get(subscription.track_id)
650-
651-
default_simulcast_encoding = subscription.opts[:default_simulcast_encoding]
652-
653-
cond do
654-
track == nil ->
655-
{:error, :invalid_track_id}
656-
657-
subscription.format not in track.format ->
658-
{:error, :invalid_format}
659-
660-
# TODO maybe simulcast_encodings should be always a list
661-
default_simulcast_encoding != nil and track.simulcast_encodings != nil and
662-
default_simulcast_encoding not in track.simulcast_encodings ->
663-
{:error, :invalid_default_simulcast_encoding}
664-
665-
true ->
666-
:ok
667-
end
668-
end
669-
670646
defp handle_media_event(%{type: :join, data: data}, peer_id, _ctx, state) do
671647
peer = Peer.new(peer_id, data.metadata || %{})
672648
dispatch(%Message.NewPeer{rtc_engine: self(), peer: peer})
@@ -995,45 +971,61 @@ defmodule Membrane.RTC.Engine do
995971
{endpoint_to_tee_links ++ links, state}
996972
end
997973

974+
defp check_subscription(subscription, state) do
975+
# checks whether subscription is correct
976+
track = get_track(subscription.track_id, state.endpoints)
977+
default_simulcast_encoding = subscription.opts[:default_simulcast_encoding]
978+
979+
cond do
980+
track == nil ->
981+
{:error, :invalid_track_id}
982+
983+
subscription.format not in track.format ->
984+
{:error, :invalid_format}
985+
986+
# TODO maybe simulcast_encodings should be always a list
987+
default_simulcast_encoding != nil and track.simulcast_encodings != nil and
988+
default_simulcast_encoding not in track.simulcast_encodings ->
989+
{:error, :invalid_default_simulcast_encoding}
990+
991+
true ->
992+
:ok
993+
end
994+
end
995+
998996
defp try_fulfill_subscription(subscription, ctx, state) do
997+
# if tee for this track is already spawned, fulfill subscription
998+
# otherwise, save subscription as pending, we will fulfill it
999+
# when tee appears
9991000
if Map.has_key?(ctx.children, {:tee, subscription.track_id}) do
10001001
fulfill_subscription(subscription, ctx, state)
10011002
else
1002-
subscription = %Subscription{subscription | status: :pending}
10031003
state = update_in(state, [:pending_subscriptions], &[subscription | &1])
10041004
{[], state}
10051005
end
10061006
end
10071007

10081008
defp fulfill_subscription(%Subscription{format: :raw} = s, ctx, state) do
1009-
links =
1009+
raw_format_links =
10101010
if Map.has_key?(ctx.children, {:raw_format_tee, s.track_id}) do
10111011
[]
10121012
else
10131013
prepare_raw_format_links(s.track_id, state)
1014-
end ++
1015-
prepare_track_to_endpoint_links(s, :raw_format_tee, state)
1014+
end
10161015

1017-
state =
1018-
update_in(
1019-
state,
1020-
[:subscriptions, s.endpoint_id],
1021-
&Map.put(&1, s.track_id, %Subscription{s | status: :active})
1022-
)
1016+
{links, state} = do_fulfill_subscription(s, :raw_format_tee, state)
10231017

1024-
{links, state}
1018+
{raw_format_links ++ links, state}
10251019
end
10261020

1027-
defp fulfill_subscription(s, _ctx, state) do
1028-
links = prepare_track_to_endpoint_links(s, :tee, state)
1029-
1030-
state =
1031-
update_in(
1032-
state,
1033-
[:subscriptions, s.endpoint_id],
1034-
&Map.put(&1, s.track_id, %Subscription{s | status: :active})
1035-
)
1021+
defp fulfill_subscription(%Subscription{format: _remote_format} = s, _ctx, state) do
1022+
do_fulfill_subscription(s, :tee, state)
1023+
end
10361024

1025+
defp do_fulfill_subscription(s, tee_kind, state) do
1026+
links = prepare_track_to_endpoint_links(s, tee_kind, state)
1027+
s = %Subscription{s | status: :active}
1028+
state = update_in(state, [:subscriptions, s.endpoint_id], &Map.put(&1, s.track_id, s))
10371029
{links, state}
10381030
end
10391031

@@ -1046,12 +1038,9 @@ defmodule Membrane.RTC.Engine do
10461038
end
10471039

10481040
defp prepare_track_to_endpoint_links(subscription, :tee, state) do
1049-
track =
1050-
state.endpoints
1051-
|> Map.values()
1052-
|> Enum.flat_map(&Endpoint.get_tracks/1)
1053-
|> Map.new(&{&1.id, &1})
1054-
|> Map.get(subscription.track_id)
1041+
# if someone subscribed for simulcast track, prepare options
1042+
# for SimulcastTee
1043+
track = get_track(subscription.track_id, state.endpoints)
10551044

10561045
options =
10571046
if track.simulcast_encodings != nil do
@@ -1142,6 +1131,14 @@ defmodule Membrane.RTC.Engine do
11421131
defp get_outbound_tracks(endpoints),
11431132
do: Enum.flat_map(endpoints, fn {_id, endpoint} -> Endpoint.get_tracks(endpoint) end)
11441133

1134+
defp get_track(track_id, endpoints) do
1135+
endpoints
1136+
|> Map.values()
1137+
|> Enum.flat_map(&Endpoint.get_tracks/1)
1138+
|> Map.new(&{&1.id, &1})
1139+
|> Map.get(track_id)
1140+
end
1141+
11451142
defp handle_remove_peer(peer_id, reason, ctx, state) do
11461143
case do_remove_peer(peer_id, reason, ctx, state) do
11471144
{:absent, [], state} ->
@@ -1175,28 +1172,27 @@ defmodule Membrane.RTC.Engine do
11751172
end
11761173
end
11771174

1178-
# TODO `peer_id` -> `endpoint_id`
1179-
defp do_remove_endpoint(peer_id, ctx, state) do
1180-
if Map.has_key?(state.endpoints, peer_id) do
1181-
{endpoint, state} = pop_in(state, [:endpoints, peer_id])
1175+
defp do_remove_endpoint(endpoint_id, ctx, state) do
1176+
if Map.has_key?(state.endpoints, endpoint_id) do
1177+
{endpoint, state} = pop_in(state, [:endpoints, endpoint_id])
1178+
{_subscriptions, state} = pop_in(state, [:subscriptions, endpoint_id])
11821179

11831180
state =
1184-
update_in(state, [:waiting_subscriptions, peer_id], fn subscriptions ->
1185-
Enum.filter(subscriptions, fn s -> s.endpoint_id != peer_id end)
1181+
update_in(state, [:pending_subscriptions, endpoint_id], fn subscriptions ->
1182+
Enum.filter(subscriptions, fn s -> s.endpoint_id != endpoint_id end)
11861183
end)
11871184

1188-
{_subscriptions, state} = pop_in(state, [:subscriptions, peer_id])
11891185
tracks = Enum.map(Endpoint.get_tracks(endpoint), &%Track{&1 | active?: true})
11901186

1191-
tracks_msgs = do_publish({:remove_tracks, tracks}, {:endpoint, peer_id}, state)
1187+
tracks_msgs = do_publish({:remove_tracks, tracks}, {:endpoint, endpoint_id}, state)
11921188

1193-
endpoint_bin = ctx.children[{:endpoint, peer_id}]
1189+
endpoint_bin = ctx.children[{:endpoint, endpoint_id}]
11941190

11951191
actions =
11961192
if endpoint_bin == nil or endpoint_bin.terminating? do
11971193
[]
11981194
else
1199-
[remove_child: find_children_for_endpoint(endpoint, peer_id, ctx)]
1195+
[remove_child: find_children_for_endpoint(endpoint, endpoint_id, ctx)]
12001196
end
12011197

12021198
{:present, tracks_msgs ++ actions, state}
@@ -1205,13 +1201,13 @@ defmodule Membrane.RTC.Engine do
12051201
end
12061202
end
12071203

1208-
defp find_children_for_endpoint(endpoint, peer_id, ctx) do
1204+
defp find_children_for_endpoint(endpoint, endpoint_id, ctx) do
12091205
children =
12101206
endpoint
12111207
|> Endpoint.get_tracks()
1212-
|> Enum.flat_map(fn track -> get_track_elements(peer_id, track.id, ctx) end)
1208+
|> Enum.flat_map(fn track -> get_track_elements(endpoint_id, track.id, ctx) end)
12131209

1214-
[endpoint: peer_id] ++ children
1210+
[endpoint: endpoint_id] ++ children
12151211
end
12161212

12171213
defp get_track_elements(endpoint_id, track_id, ctx) do
+10-16
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,26 @@
11
defmodule Membrane.RTC.Engine.Subscription do
22
@moduledoc false
33
# Module representing subscription for track
4+
alias Membrane.RTC.Engine
45
alias Membrane.RTC.Engine.{Endpoint, Track}
56

67
@typedoc """
7-
Subscription options.
8-
9-
* `default_simulcast_encoding` - initial encoding that
10-
endpoint making subscription wants to receive
11-
"""
12-
@type opts_t :: [default_simulcast_encoding: String.t()]
13-
14-
@typedoc """
15-
* `endpoint_id` - id of endpoint making subscription for track
8+
* `endpoint_id` - id of endpoint making subscription
169
* `track_id` - id of track endpoint subscribes for
1710
* `format` - format of track endpoint subscribes for
18-
* `status` - status of subscription. Subscription is `active` when
19-
given track is linked to given endpoint and `pending` otherwise
11+
* `status` - status of subscription. Subscription is
12+
`active` when track some endpoint subscribed for is linked
13+
to this endpoint and `pending` otherwise
2014
* `opts` - additional options
2115
"""
22-
@type t() :: %___MODULE__{
16+
@type t() :: %__MODULE__{
2317
endpoint_id: Endpoint.id(),
2418
track_id: Track.id(),
2519
format: Track.format(),
26-
status: :created | :pending | :active,
27-
opts: opts_t()
20+
status: :pending | :active,
21+
opts: Engine.subscription_opts_t()
2822
}
2923

30-
@enforce_keys [:endpoint_id, :track_id, :format, :status, :opts]
31-
defstruct @enforce_keys
24+
@enforce_keys [:endpoint_id, :track_id, :format]
25+
defstruct @enforce_keys ++ [status: :pending, opts: []]
3226
end

0 commit comments

Comments
 (0)