Releases: membraneframework/membrane_core
v0.11.0
Membrane Core v0.11.0 is now available!
This release includes mostly API improvements. For some of them, breaking changes were necessary. To facilitate migration, we prepared the updating guide that should help adjust your code to the changes.
Breaking changes
Actions
The following actions have changed:
Membrane.Element.Action.caps_t->Membrane.Element.Action.stream_format_t(#468)Membrane.Bin.Action.notify_t->Membrane.Bin.Action.notify_parent_t(#415)Membrane.Element.Action.notify_t->Membrane.Element.Action.notify_parent_t(#415)Membrane.Pipeline.Action.forward_t->Membrane.Pipeline.Action.notify_child_t(#415)Membrane.Bin.Action.forward_t->Membrane.Bin.Action.notify_child_t(#415)
Callbacks
From now on, the callbacks should return an {actions, state} tuple. Returning errors is no longer supported - if a component can't recover from an error, it should raise (#471)
Furthermore, the following callbacks have changed:
handle_stopped_to_prepared/2->handle_setup/2in all components (#432)Membrane.Element.Base.handle_caps/4->Membrane.Element.Base.handle_stream_format/4(#432)handle_element_start_of_stream/3->handle_element_start_of_stream/4andhandle_element_end_of_stream/3->handle_element_end_of_stream/4in pipelines and bins (#417)handle_init/1->handle_init/2in all components (#432)handle_other/3->handle_info/3in all components (#415)handle_notification/4->handle_child_notification/4in pipelines and bins (#415)
The following callbacks have been removed:
Instead, Membrane.ResourceGuard, Membrane.UtilitySupervisor or handle_terminate_request/2 should be used.
What is more, messages sent with the :notify_parent action (former :notify action), are handled in a separate handle_parent_notification/3 callback instead of being handled in handle_other/3, along with messages sent from any other processes. (#415)
Pads definitions
In v0.11 :caps option passed to def_input_pad/2 or def_output_pad/2 has been deleted. Instead of it, we have added a new option - :accepted_format. The main principle of these two options is the same - validation of value passed to :caps or :stream_format action. While :caps required a module name or specific tuple format as argument, :accepted_format requires following types of terms:
-
Elixir pattern - eg.
accepted_format: %My.Custom.Format{field: value} when value in [:some, :enumeration]The value passed to
:stream_formataction has to match the provided pattern. In this case, the requirement above would
be satisfied by eg.stream_format: %My.Custom.Format{field: :some} -
Module name - eg.
accepted_format: My.Custom.Format
This would be equal to the match on the struct of the passed module, in this caseaccepted_format: %My.Custom.Format{} -
Call to
any_offunction - you can pass as many arguments to it, as you want. Each argument should be an Elixir pattern
or a module name, eg.stream_format: any_of(My.Custom.Format, %My.Another.Custom.Format{field: :value})If you use
any_of, the value passed to:stream_formatwill have to match at least one of the passed
arguments. In this case,stream_format: %My.Custom.Format{frequency: 1}would be ok, but
stream_format: %My.Another.Custom.Format{field: :not_allowed_value}would fail
Option :accepted_format is required. If you don't want to perform any check on stream_format, you can always write accepted_format: _any, but it is not suggested.
Checks on stream_format will be performed on both, intput and output pads, just as caps were checked in those places.
New way to define children
Membrane.Bin.spec_tandMembrane.Pipeline.spec_tactions no more acceptMembrane.ParentSpecstructure.
Instead, a tuple with the children structure and options needs to be passed. (#458)- Functions used to spawn children and create links between them, available in the former
Membrane.ParentSpecmodule, have been changed - till now on, the children structure needs to be defined with the use ofchild/3,child/4,get_child/2andget_child/3functions from theMembrane.ChildrenSpec. (#458) Membrane.ParentSpec.link_bin_input/1has been renamed toMembrane.ChildrenSpec.bin_input/1(#458)Membrane.ParentSpec.link_bin_output/2has been renamed toMembrane.ChildrenSpec.bin_output/2(#458)
Changes in Membrane.Time module
Membrane.Time.to_<unit name>/1has been renamed toMembrane.Time.round_to_<unit name>/1in order to indicate that the result will be rounded. (#435)
Changes with def_options macro
- A
:typefield from thedef_optionskeyword list has been removed, and the type specification of the option defined within the macro is determined by the:specfield (#466)
New way to spawn pipeline
Membrane.Pipeline.start/3andMembrane.Pipeline.start_link/3now return{:ok, pipeline_supervisor, pipeline}.(#432)
Changes in Membrane.Testing
Membrane.Testing.Pipeline.start_link/1has been changed toMembrane.Testing.Pipeline.start_link_supervised!/1(#432)- The
Membrane.Testing.Pipeline.options()now have a single:structurefield allowing to specify the test pipeline's children structure, in place of the former:linksand:childrenfields.
Other changes:
handle_call/3callback in the pipeline and areplyand:reply_toactions. (#334)- Improvements in documentation - till now on, in the documentation page for each of the following modules:
Membrane.Source,Membrane.Filter,Membrane.EndpointandMembrane.Sinkthere is a list of all the callbacks available to be implemented for these modules. Membrane.Time.<plural unit name>/1now acceptsRatiostructure as an argument. (#435)Membrane.Time.round_to_timebase/2function has been added. (#435)Membrane.FilterAggregatorthat allows running multiple filters sequentially within one process has been added (still experimental) (#355)- Information about the element's playback change is logged as debug, not as debug_verbose. (#430)
Membrane.Testing.MockResourceGuardhas been added, to help write tests with the new way of handling resources. (#478)
Release v0.10.2
What's changed?
Changes that do not affect API
- A bug with the distributed pipeline crashing has been fixed. The pipeline which elements were put on different nodes used to crash due to the fact, that the toilet between the elements was designed to be used by elements running on the same node.
Release v0.10.1
What's changed?
The changes that do not affect API:
- improvements in documentation and exemplary code snippets, concerning the latest changes in API
- the errors in Membrane's core are now raised as exceptions as low as they occur, instead of being propagated up with
{:error, ...}monads - mechanism for checking if the static pads are unlinked only when the element dies, has been turned off for the further investigation since it's not working properly
- bug fix:
Membrane.Testing.Pipelinewith a custom module injected behaves in a desired way onceMembrane.Testing.Pipeline.execute_actions/2function is called (the custom module does not need to implementhandle_other({:execute_actions, actions}, ...)anymore)
Full changelog: v0.10.0 ... v0.10.1
v0.10.0
Release includes:
- removing deprecated stuff #399:
- Support for returning bare
Membrane.ParentSpec{}fromhandle_init/1 - Support for callbacks without
contextargument inPipelineandBin Membrane.Element.WithInputPads.def_input_pads/1Membrane.Element.WithOutputPads.def_output_pads/1Membrane.Log.*Membrane.ParentSpec.link_bin_input/2Membrane.ParentSpec.to_bin_output/2- Following functions in
Membrane.Time:is_t/1,system_time/0,native_unit/1,day/1,hour/1,minute/1,second/1,millisecond/1,microsecond/1,nanosecond/1
- Support for returning bare
- making
Membrane.Pipeline.{prepare, play, stop}deprecated and adding:playbackaction instead - making
Membrane.Pipeline.stop_and_terminate/2deprecated and addingMembrane.Pipeline.terminate/2instead - adding the
Membrane.RemoteControlled.Pipeline- a basic implementation of aMembrane.Pipelinethat
can be spawned and controlled by an external process #366 - disallowing sending buffers through pads without sending the caps first, by raising an
Membrane.ElementErrorexception if such a situation occurs #341 - refining the
Membrane.Testing.PipelineAPI - deprecating theMembrane.Testing.Pipeline.Optionsusage, allowing to usepipeline_keyword_list_tas options inMembrane.Testing.Pipeline.start/1andMembrane.Testing.Pipeline.start_link/1
Full changelog: v0.9.0 ... v0.10.0
v0.9.0 - Automatic demands
Automatic demands
The Membrane Core can now handle the demands in filters for you! 🎉
To enable this, use demand_mode: :auto in your pad's definition:
def_input_pad :input,
demand_mode: :auto,
caps: :anyThis will make the Core send a demand automatically, no need to use :demand action anymore.
By adding the same option to the output pad, the Core will also handle any incoming demands and demands on all input pads, so it is suitable for cases when a filter consumes data from all inputs uniformly.
See how automatic demands are used in funnel
What's Changed
- Automatic demands #313
- Stop forwarding notifications by default in bins #358
- More fine-grained control over emitted metrics #365
- Added log metadata when reporting init in telemetry #376
- Fix generation of pad documentation inside an element #377
- Leaving static pads unlinked and transiting to a playback state other than
:stoppedwill result
in runtime error (previously only a warning was printed out). #389 - It is possible now to assert on crash group down when using Testing.Pipeline. #391
Full Changelog: v0.8.2...v0.9.0
v0.8.2
v0.8.0
Release includes:
- Adds the possibility to specify
Membrane.Loggermetadata in theMembrane.ParentSpec. All children spawned from thatMembrane.ParentSpecwill receive specified metadata. - PTS and DTS timestamps were added to
Membrane.Bufferstructure explicitly. Timestamps should no longer live in Membrane.Buffer.metadata field #335. - Less warnings on shutdown when parent or other element crashed #322
- Added more telemetry events: #317
- Description of Element's options can now use interpolation and function calls #328
v0.7.0 - Crash Groups
Crash Groups
From v0.7.0 of membrane_core it's possible to group elements and bins into crash groups.
Crash group is a logical entity that prevents the whole pipeline from crashing when one of its children crashes.
Adding children to the Crash Group
children = %{
{:endpoint_bin, endpoint_id} => %EndpointBin{
# ...
}
}
spec = %ParentSpec{children: children, crash_group: {endpoint_id, :temporary}}In this case we create a new children - EndpointBin and we add it to crash group with id endpoint_id. When EndpointBin crashes the whole pipeline will still be alive.
Handling crash of Crash Group
When some child in a crash group crashes the callback handle_crash_group_down/3 is called.
@impl true
def handle_crash_group_down(crash_group_id, ctx, state) do
Membrane.Logger.info("Crash group: #{inspect(crash_group_id)} is down.")
# do some stuff
endLimitations
At this moment Crash Groups are only useful for elements with dynamic pads.
Condidional Linking
In this version we also introduce an enhancement in linking elements.
Sometimes there is a situation you want to link or create an element only when some requirements are met.
To make it easier we introduce a new syntax that looks like below
encoding_specific_links =
case encoding do
# when encoding is :H264 we want to add one additional element -- H264 parser.
:H264 -> &to(&1, {:h264_parser, ssrc}, %Membrane.H264.FFmpeg.Parser{alignment: :nal})
# when encoding is :OPUS we just passes what we got
:OPUS -> & &1
end
links = [
link_bin_input(pad)
|> pipe_fun(encoding_specific_links)
|> to({:track_filter, track_id}, %Membrane.WebRTC.TrackFilter{enabled: track_enabled})
# ...
]
defp pipe_fun(term, fun), do: fun.(term)Breaking changes
From now Testing.Source sends a new type of caps - RemoteStream. This can break some of your already existing tests.