Releases: membraneframework/membrane_core
Release list
v0.12.1
Membrane Core v0.12.1 is now available!
This release includes most of the changes in membrane_core private modules, that will be introduced in v1.0.0-rc1. The main purpose of publishing this release, was to have a release with changes from v1.0.0-rc1, but with as little API changes as possible. To facilitate migration, we prepared the updating guide that should help adjust your code to the changes.
Handling a scenario when a child removes it's pad
In v0.12 parent can handle a scenario when a child removes it's own pad, by implementing new callback, handle_child_pad_removed/4.
@impl true
def handle_child_pad_removed(:rtp, Pad.ref(:rtp_output, ssrc), _ctx, state) do
...
endImprovements in toilets and automatic demands mechanism.
v0.12 introduces a lot of changes, in the way, how automatic demands work under the hood. Moreover, :auto demand unit is now supported in sinks and endpoints input pads.
Until now, toilet were always set up between :push output pad and :pull input pad. In v0.12 places, where we should set up a toilet are dynamically resolved and their number has decreased.
Rest of the changes
- Introduce
:remove_linkaction in pipelines and bins. - Add children groups - a mechanism that allows refering to multiple children with a single identifier.
- Add an ability to spawn anonymous children.
- Remove
:playbackaction. Introduce:setupaction. #496 - Add
Membrane.Testing.Pipeline.get_child_pid/2. #497 - Make callback contexts to be maps. #504
- All Membrane Elements can be compatible till now on - pads working in
:pullmode, handling differentdemand_units, can be now linked. - Output pads working in
:pullmode should have theirdemand_unitspecified. If case it's not available, it's assumed that the pad handles demands in both:bytesand:buffersunits. - Remove _t suffix from types #509
- Introduce support for crash groups in Bins. #521
- Make sure enumerable with all elements being
Membrane.Buffer.t(), passed as:outputparameter forMembrane.Testing.Sourcewon't get rewrapped inMembrane.Buffer.t()struct. - Implement
Membrane.Debug.FilterandMembrane.Debug.Sink. #552
New Contributors
Full Changelog: v0.11.3...v0.12.1
v0.12.0
Membrane Core v0.12.0
Release v0.12.0 has been retired, use v0.12.1 instead of it.
v0.11.4
v0.11.3
v1.0.0-rc0
Here comes the first release candidate for Membrane Core 1.0! 🎉 This release contains the final API polishing before making it stable and brings a couple of new features. The migration guide, which will help you seamlessly upgrade from 0.11, is available here. We also started the process of migrating all the plugins. Now, let's have a look at the most important changes brought by this release:
Children groups & anonymous children
Let's consider an example when there are a couple of streams and you need to spawn some elements to process each of them, and then put them all into a common sink:
def handle_info({:new_stream, stream_id}, _ctx, state) do
spec =
child({:source, stream_id}, MySource)
|> child({:parser, stream_id}, MyParser)
|> child({:depayloader, stream_id}, MyDepayloader)
|> get_child(:sink)
{[spec: spec], state}
endNow it's more concise with children groups:
def handle_info({:new_stream, stream_id}, _ctx, state) do
spec =
child(:source, MySource)
|> child(:parser, MyParser)
|> child(:depayloader, MyDepayloader)
|> get_child(:sink)
spec = {spec, group: {:stream, stream_id}}
{[spec: spec], state}
endAnd even more concise with anonymous children - from now on, you only have to name a child when you refer to it:
def handle_info({:new_stream, stream_id}, _ctx, state) do
spec = {
child(MySource) |> child(MyParser) |> child(MyDepayloader) |> get_child(:sink),
group: {:stream, stream_id}
}
{[spec: spec], state}
endMoreover, you can remove the whole group by its name when the stream is no longer available:
def handle_info({:stream_finished, stream_id}, _ctx, state) do
{[remove_children: {:stream, stream_id}], state}
endCheck the docs for details.
Deferring component setup
Sometimes setting up a component requires a lot of work, possibly done asynchronously. Now, you can prevent a component setup from finishing before such asynchronous work is done, without blocking in handle_setup. It's as simple as marking it as incomplete:
def handle_setup(_ctx, state) do
request_some_async_work(...)
{[setup: :incomplete], state}
endWhen the work is finished, just let Membrane know it can proceed:
def handle_info(:done_setup, _ctx, state) do
{[setup: :complete], state}
endThis mechanism works for all components, including pipelines. Therefore, pipelines now automatically switch to playing after they are set up, which is usually desired. If you don't want this to happen, just complete the setup whenever everything is ready. Here are the docs.
Demand units on outputs
From now on, you can specify demand units on both inputs and outputs. If the demand unit on the output doesn't match the one on the linked input, Membrane will take care of recalculating it for you. Thanks to that, all Membrane elements are now compatible and can be linked together, regardless of the demands unit they support! This applies to auto demands as well. Therefore, there's no need to provide demand units in bins anymore.
API improvements
handle_processandhandle_writeare replaced withhandle_bufferfor better consistency:modeand:demand_modeoptions in pad definition are replaced with:flow_control, which may be:push,:autoor:manualand defaults to:autowhenever available (currently in filters, soon in sinks as well)- Callback contexts are now maps instead of structs and they're documented in a single module per component, so it's more straightforward to figure out what they contain
All changes
Breaking changes
- Replace the
playbackaction with deferring setup by @FelonEkonom in #496 - Rename handle_write and handle_process to handle_buffer by @FelonEkonom in #506
- Refactor callback contexts by @FelonEkonom in #504
- Unify mode and demand_mode options of pads by @varsill in #508
- Demand units conversion by @varsill in #498
- Rename
Membrane.RemoteControlled.PipelinetoMembrane.RCPipelineby @mat-hek in #505 - Update Membrane.Time API by @FelonEkonom in #494
- remove _t suffix from types by @mat-hek in #509
Non-breaking changes
- Children groups and anonymous children by @varsill in #461
- Implement
:remove_linkaction by @FelonEkonom in #487 - Add
Membrane.ResourceGuard.cleanup/1by @FelonEkonom in #477 - Add
Membrane.Testing.Pipeline.get_child_pid/2@FelonEkonom in #497 - Bump Ratio to 3.0 by @varsill in #438
Bug fixes
- Stop all timers when a component enters zombie mode by @FelonEkonom in #485
- Fix a deadlock when the pipeline spawns a spec entailing two dependent specs in a bin by @mat-hek in #484
- Fix pad docs generation by @mat-hek in #490
- fix subprocess supervisor crash when a child fails in handle_init by @mat-hek in #488
- Docs formatting fixes in children_spec.ex by @bblaszkow06 in #492
- Unlink only existing children on crash group down by @FelonEkonom in #499
- Add
timer_interval_ttoElement.Action.tby @balins in #502 - Fix RC during unlinking by @FelonEkonom in #500
Full Changelog: v0.11.0...v1.0.0-rc0
v0.11.2
What's Changed
Full Changelog: v0.11.1...v0.11.2
v0.11.1
What's Changed
- add playback related changes to the release guide by @mat-hek in #472
- Put in guide info about updating tuples returned from callbacks by @FelonEkonom in #475
- Implement running all cleanup functions in ResourceGuard by @FelonEkonom in #477
- Updating guide - parent/children communication and childrenspecs by @varsill in #474
- Fix typo by @daniel-jodlos in #481
- Bump Ratio to 3.0 by @varsill in #438
- Stop all timers, when componenet enters zombie mode by @FelonEkonom in #485
- [MC-106] Fix a deadlock when pipeline spawns a spec entailing two dependent specs in a bin by @mat-hek in #484
- Fix pad docs generation by @mat-hek in #490
- fix subprocess supervisor crash when a child fails in handle_init by @mat-hek in #488
Full Changelog: v0.11.0...v0.11.1
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