Membrane.ParentSpec (Membrane Core v0.7.0) View Source
Structure representing the topology of a pipeline/bin.
It can be incorporated into a pipeline or a bin by returning
Membrane.Pipeline.Action.spec_t/0
or Membrane.Bin.Action.spec_t/0
action, respectively. This commonly happens within Membrane.Pipeline.handle_init/1
and Membrane.Bin.handle_init/1
, but can be done in any other callback also.
Children
Children that should be spawned when the pipeline/bin starts can be defined
with the :children
field.
You have to set it to a map, where keys are valid children names (Membrane.Child.name_t/0
)
that are unique within this pipeline/bin and values are either child's module or
struct of that module.
Sample definitions:
%{
first_element: %Element.With.Options.Struct{option_a: 42},
some_element: Element.Without.Options,
some_bin: Bin.Using.Default.Options
}
Links
Links that should be made when the children are spawned can be defined with the
:links
field. Links can be defined with the use of link/1
and to/2
functions
that allow specifying elements linked, and via_in/2
and via_out/2
that allow
specifying pads' names and parameters. If pads are not specified, name :input
is assumed for inputs and :output
for outputs.
Sample definition:
[
link(:source_a)
|> to(:converter)
|> via_in(:input_a, buffer: [preferred_size: 20_000])
|> to(:mixer),
link(:source_b)
|> via_out(:custom_output)
|> via_in(:input_b, pad: [mute: true])
|> to(:mixer)
|> via_in(:input, [warn_size: 264_000, fail_size: 300_000])
|> to(:sink)
]
Links can also contain children definitions, for example:
[
link(:first_element, %Element.With.Options.Struct{option_a: 42})
|> to(:some_element, Element.Without.Options)
|> to(:element_specified_in_children)
]
Which is particularly convenient for creating links conditionally:
maybe_link = &to(&1, :some_element, Some.Element)
[
link(:first_element)
|> then(if condition?, do: maybe_link, else: & &1)
|> to(:another_element)
]
Bins
For bins boundaries, there are special links allowed. The user should define links
between the bin's input and the first child's input (input-input type) and last
child's output and bin output (output-output type). In this case, link_bin_input/2
and to_bin_output/3
should be used.
Sample definition:
[
link_bin_input() |> to(:filter1) |> to(:filter2) |> to_bin_output(:custom_output)
]
Dynamic pads
In most cases, dynamic pads can be linked the same way as static ones, although in the following situations, exact pad reference must be passed instead of a name:
When that reference is needed later, for example, to handle a notification related to that particular pad instance
pad = Pad.ref(:output, make_ref()) [ link(:tee) |> via_out(pad) |> to(:sink) ]
When linking dynamic pads of a bin with its children, for example in
Membrane.Bin.handle_pad_added/3
@impl true def handle_pad_added(Pad.ref(:input, _) = pad, _ctx, state) do links = [link_bin_input(pad) |> to(:mixer)] {{:ok, spec: %ParentSpec{links: links}}, state} end
Stream sync
:stream_sync
field can be used for specifying elements that should start playing
at the same moment. An example can be audio and video player sinks. This option
accepts either :sinks
atom or a list of groups (lists) of elements. Passing :sinks
results in synchronizing all sinks in the pipeline, while passing a list of groups
of elements synchronizes all elements in each group. It is worth mentioning
that to keep the stream synchronized all involved elements need to rely on
the same clock.
By default, no elements are synchronized.
Sample definitions:
%ParentSpec{stream_sync: [[:element1, :element2], [:element3, :element4]]}
%ParentSpec{stream_sync: :sinks}
Clock provider
A clock provider is an element that exports a clock that should be used as the pipeline
clock. The pipeline clock is the default clock used by elements' timers.
For more information see Membrane.Element.Base.def_clock/1
.
Crash groups
A crash group is a logical entity that prevents the whole pipeline from crashing when one of its children crash.
Adding children to a crash group
children = %{
:some_element_1 => %SomeElement{
# ...
},
:some_element_2 => %SomeElement{
# ...
}
}
spec = %ParentSpec{children: children, crash_group: {group_id, :temporary}}
The crash group is defined by a two-element tuple, first element is an ID which is of type
Membrane.CrashGroup.name_t()
, and the second is a mode. Currently, we support only
:temporary
mode which means that Membrane will not make any attempts to restart crashed child.
In the above snippet, we create new children - :some_element_1
and :some_element_2
, we add it
to the crash group with id group_id
. Crash of :some_element_1
or :some_element_2
propagates
only to the rest of the members of the crash group and the pipeline stays alive.
Currently, crash group covers all children within one or more ParentSpec
s.
Handling crash of a crash group
When any of the members of the crash group goes down, the callback:
handle_crash_group_down/3
is called.
@impl true
def handle_crash_group_down(crash_group_id, ctx, state) do
# do some stuff in reaction to crash of group with id crash_group_id
end
Limitations
At this moment crash groups are only useful for elements with dynamic pads. Crash groups work only in pipelines and are not supported in bins.
Link to this section Summary
Types
Options passed to the child when linking its pad with a different one.
Struct used when starting and linking children within a pipeline or a bin.
Functions
Begins a link.
Defines a child and begins a link with it.
Begins a link with a bin's pad.
Continues or ends a link.
Defines a child and continues or ends a link with it.
Ends a link with a bin's output.
Specifies input pad name and properties of the subsequent child.
Specifies output pad name and properties of the preceding child.
Link to this section Types
Specs
Specs
children_spec_t() :: [{Membrane.Child.name_t(), child_spec_t()}] | %{required(Membrane.Child.name_t()) => child_spec_t()}
Specs
crash_group_spec_t() :: {any(), :temporary} | nil
Specs
link_builder_t()
Specs
links_spec_t() :: [link_builder_t() | links_spec_t()]
Specs
pad_props_t() :: [ buffer: Membrane.Core.InputBuffer.props_t(), options: Keyword.t() ]
Options passed to the child when linking its pad with a different one.
The allowed options are:
:buffer
- keyword allowing to configureMembrane.Core.InputBuffer
between elements. Valid only for input pads. SeeMembrane.Core.InputBuffer.props_t/0
for configurable properties.:options
- any child-specific options that will be available inMembrane.Pad.Data
struct.
Specs
t() :: %Membrane.ParentSpec{ children: children_spec_t(), clock_provider: Membrane.Child.name_t(), crash_group: crash_group_spec_t(), links: links_spec_t(), stream_sync: :sinks | [[Membrane.Child.name_t()]] }
Struct used when starting and linking children within a pipeline or a bin.
Link to this section Functions
Specs
link(Membrane.Child.name_t()) :: link_builder_t()
Begins a link.
See the links section of the moduledoc for more information.
Specs
link(Membrane.Child.name_t(), child_spec_t()) :: link_builder_t()
Defines a child and begins a link with it.
See the links section of the moduledoc for more information.
Specs
link_bin_input(Membrane.Pad.name_t() | Membrane.Pad.ref_t(), pad_props_t()) :: link_builder_t() | no_return()
Begins a link with a bin's pad.
See the links section of the moduledoc for more information.
Specs
to(link_builder_t(), Membrane.Child.name_t()) :: link_builder_t() | no_return()
Continues or ends a link.
See the links section of the moduledoc for more information.
Specs
to(link_builder_t(), Membrane.Child.name_t(), child_spec_t()) :: link_builder_t() | no_return()
Defines a child and continues or ends a link with it.
See the links section of the moduledoc for more information.
Specs
to_bin_output( link_builder_t(), Membrane.Pad.name_t() | Membrane.Pad.ref_t(), pad_props_t() ) :: link_builder_t() | no_return()
Ends a link with a bin's output.
See the links section of the moduledoc for more information.
Specs
via_in( link_builder_t(), Membrane.Pad.name_t() | Membrane.Pad.ref_t(), pad_props_t() ) :: link_builder_t() | no_return()
Specifies input pad name and properties of the subsequent child.
See the links section of the moduledoc for more information.
Specs
via_out( link_builder_t(), Membrane.Pad.name_t() | Membrane.Pad.ref_t(), pad_props_t() ) :: link_builder_t() | no_return()
Specifies output pad name and properties of the preceding child.
See the links section of the moduledoc for more information.