Skip to content

Commit b8872bf

Browse files
committed
Add pad lifecycle
1 parent 6807a34 commit b8872bf

File tree

2 files changed

+51
-14
lines changed

2 files changed

+51
-14
lines changed

guides/useful_concepts/pads.md

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
# Everything about pads
22

33
When developing intuition about the structure of pipelines pads are
4-
something that can't be ignored. If you think about elements and bins as some
4+
something that can't be ignored. If you think about elements and bins (from now
5+
on referred to as components) as some
56
sort of containers or boxes in which processing happens, then pads are the parts
67
that with these containers are connected with. There are some constraints
78
regarding pads:
89

9-
* A pad of one element can only connect to a single pad of other element and
10+
* A pad of one component can only connect to a single pad of other component and
1011
only once two pads are linked communication through them can happen.
1112
* One pad needs to be an input pad, and the other an output pad.
1213
* The accepted stream formats of the pads need to match.
1314

14-
There are three types of information that can be exchanged between elements
15+
There are three types of information that can be exchanged between components
1516
through pads - [stream formats](`t:Membrane.StreamFormat.t/0`),
1617
[events](`t:Membrane.Event.t/0`) and [buffers](`t:Membrane.Buffer.t/0`)
1718

18-
When looking at the insides of elements, the pads are their main way to
19-
communicate with other elements in the pipeline. There are three types
20-
of informations that can be exchanged between elements through pads -
19+
When looking at the insides of components, the pads are their main way to
20+
communicate with other components in the pipeline. There are three types
21+
of informations that can be exchanged between components through pads -
2122
[stream formats](`t:Membrane.StreamFormat.t/0`),
2223
[events](`t:Membrane.Event.t/0`) and [buffers](`t:Membrane.Buffer.t/0`).
23-
When an element receives one of these informations from another one, it receives
24+
When an component receives one of these informations from another one, it receives
2425
it on a pad. The reference to this pad is then also available as an argument
2526
of the callback that handles the received information. For example an invocation
2627
of a [`handle_buffer/4`](`c:Membrane.Element.WithInputPads.handle_buffer/4`)
@@ -33,8 +34,8 @@ def handle_buffer(some_pad, buffer, context, state) do
3334
end
3435
```
3536

36-
When an element wants to send an stream format, event or buffer to another
37-
element in the pipeline, it should send it on a pad that's linked to it. It
37+
When an component wants to send an stream format, event or buffer to another
38+
component in the pipeline, it should send it on a pad that's linked to it. It
3839
can do that by using the pad reference in actions that send these types of
3940
information, for example returning a
4041
[`:buffer`](`t:Membrane.Element.Action.buffer/0`) action
@@ -50,7 +51,7 @@ end ^^^^^^^^
5051

5152
## Defining pads
5253

53-
To define what pads an element will have and how they'll behave we use
54+
To define what pads an component will have and how they'll behave we use
5455
[`def_input_pad/2`](`Membrane.Element.WithInputPads.def_input_pad/2`)
5556
and [`def_output_pad/2`](`Membrane.Element.WithOutputPads.def_output_pad/2`) macros.
5657
Input pads can only be defined for Sinks, Filters and Endpoints, and output
@@ -75,7 +76,7 @@ output pad. The content of the buffers sent by this element is unknown - the fil
7576
that's being read can contain anything - so this pad has `:accepted_format` set to
7677
`%RemoteStream{type: :bytestream}`. That means that any stream format that
7778
matches on this struct can be sent on the output pad and this fact has to be
78-
accounted for when linking an element after the source.
79+
accounted for when linking a component after the source.
7980

8081
A pipeline spec with a file source passing buffers to a MP4 demuxer could look
8182
like this:
@@ -115,9 +116,9 @@ end
115116

116117
Dynamic pads are a bit more complex. They're used when the amount of pads of
117118
given type is variable - dependent on the processed stream or external factors.
118-
The creation of these pads is controlled by the parent of the element - if a
119+
The creation of these pads is controlled by the parent of the component - if a
119120
[`:spec`](`t:Membrane.Pipeline.Action.spec/0`) action linking the dynamic pad is
120-
being executed, then the pad is created dynamically and the element needs to
121+
being executed, then the pad is created dynamically and the component needs to
121122
handle this, in most cases with
122123
[`handle_pad_added/3`](`c:Membrane.Element.Base.handle_pad_added/3`).
123124

@@ -230,3 +231,39 @@ If a link has dynamic pads on both sides, the parent could also return a
230231
which would only remove the link, resulting in
231232
[`handle_pad_removed/3`](`c:Membrane.Element.Base.handle_pad_removed/3`)
232233
being called in children on both sides of it.
234+
235+
## Life cycle of a pad
236+
237+
Life cycle of components is explored more broadly in this
238+
[guide](components_lifecycle.md). Here, we'll take a closer look at a life
239+
cycle of a pad, mostly focusing on elements.
240+
241+
### Creation
242+
243+
Static pad are essentially created and linked at the same time as the whole
244+
component and exist alongside it for it's entire lifespan - they have to be
245+
linked at the same time the component is created.
246+
247+
Dynamic pads can be linked and unlinked throughout their components lifespan.
248+
There can also be multiple instances of a dynamic pad.
249+
Because of this, each creation can be handled separately in
250+
[`handle_pad_added/3`](`c:Membrane.Element.Base.handle_pad_added/3`) callback,
251+
that's being called every time a new dynamic pad is linked, and therefore
252+
created.
253+
254+
### Playback
255+
256+
When an element is in `:stopped`
257+
[playback](`t:Membrane.Playback.t/0`), nothing can be sent on it's pads - the
258+
pipeline is not ready. Only once an element enters `:playing` playback and
259+
[`handle_playing/2`](`c:Membrane.Element.Base.handle_playing/2`) callback is
260+
called, then it can assume that the pipeline is ready for communication and can
261+
send on and receive information from it's pads.
262+
263+
### Removal
264+
265+
Static pads are removed and unlinked once their component is terminated.
266+
267+
Dynamic pads can be removed during the lifespan of their component. For each removal
268+
a [`handle_pad_removed/3`](`c:Membrane.Element.Base.handle_pad_removed/3`)
269+
callback is called.

mix.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"bunch": {:hex, :bunch, "1.6.1", "5393d827a64d5f846092703441ea50e65bc09f37fd8e320878f13e63d410aec7", [:mix], [], "hexpm", "286cc3add551628b30605efbe2fca4e38cc1bea89bcd0a1a7226920b3364fe4a"},
33
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
44
"coerce": {:hex, :coerce, "1.0.2", "5ef791040c92baaa5dd344887563faaeac6e6742573a167493294f8af3672bbe", [:mix], [], "hexpm", "0b3451c729571234fdac478636c298e71d1f2ce1243abed5fa43fa3181b980eb"},
5-
"credo": {:hex, :credo, "1.7.14", "c7e75216cea8d978ba8c60ed9dede4cc79a1c99a266c34b3600dd2c33b96bc92", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "12a97d6bb98c277e4fb1dff45aaf5c137287416009d214fb46e68147bd9e0203"},
5+
"credo": {:hex, :credo, "1.7.10", "6e64fe59be8da5e30a1b96273b247b5cf1cc9e336b5fd66302a64b25749ad44d", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "71fbc9a6b8be21d993deca85bf151df023a3097b01e09a2809d460348561d8cd"},
66
"dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"},
77
"earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"},
88
"erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"},

0 commit comments

Comments
 (0)