Skip to content

Releases: membraneframework/membrane_core

v1.0.0-rc0

13 Jan 16:11
0ec6fac
Compare
Choose a tag to compare

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}
end

Now 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}
end

And 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}
end

Moreover, 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}
end

Check 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}
end

When the work is finished, just let Membrane know it can proceed:

def handle_info(:done_setup, _ctx, state) do
  {[setup: :complete], state}
end

This 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_process and handle_write are replaced with handle_buffer for better consistency
  • :mode and :demand_mode options in pad definition are replaced with :flow_control, which may be :push, :auto or :manual and defaults to :auto whenever 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

Non-breaking changes

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_t to Element.Action.t by @balins in #502
  • Fix RC during unlinking by @FelonEkonom in #500

Full Changelog: v0.11.0...v1.0.0-rc0

v0.11.2

08 Dec 13:41
e50ada5
Compare
Choose a tag to compare

v0.11.1

07 Dec 15:42
Compare
Choose a tag to compare

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

17 Nov 18:58
c38ad9c
Compare
Choose a tag to compare

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/2 in 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/4 and handle_element_end_of_stream/3 -> handle_element_end_of_stream/4 in pipelines and bins (#417)
  • handle_init/1 -> handle_init/2 in all components (#432)
  • handle_other/3 -> handle_info/3 in all components (#415)
  • handle_notification/4 -> handle_child_notification/4 in pipelines and bins (#415)

The following callbacks have been removed:

  • handle_playing_to_prepared/2 (#432)
  • handle_prepared_to_stopped/2 (#432)
  • handle_shutdown/2(#432)

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_format action 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 case accepted_format: %My.Custom.Format{}

  • Call to any_of function - 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_format will 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_t and Membrane.Pipeline.spec_t actions no more accept Membrane.ParentSpec structure.
    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.ParentSpec module, have been changed - till now on, the children structure needs to be defined with the use of child/3, child/4, get_child/2 and get_child/3 functions from the Membrane.ChildrenSpec. (#458)
  • Membrane.ParentSpec.link_bin_input/1 has been renamed to Membrane.ChildrenSpec.bin_input/1 (#458)
  • Membrane.ParentSpec.link_bin_output/2 has been renamed to Membrane.ChildrenSpec.bin_output/2 (#458)

Changes in Membrane.Time module

  • Membrane.Time.to_<unit name>/1 has been renamed to Membrane.Time.round_to_<unit name>/1 in order to indicate that the result will be rounded. (#435)

Changes with def_options macro

  • A :type field from the def_options keyword list has been removed, and the type specification of the option defined within the macro is determined by the :spec field (#466)

New way to spawn pipeline

  • Membrane.Pipeline.start/3 and Membrane.Pipeline.start_link/3 now return {:ok, pipeline_supervisor, pipeline}.(#432)

Changes in Membrane.Testing

  • Membrane.Testing.Pipeline.start_link/1 has been changed to Membrane.Testing.Pipeline.start_link_supervised!/1 (#432)
  • The Membrane.Testing.Pipeline.options() now have a single :structure field allowing to specify the test pipeline's children structure, in place of the former :links and :children fields.

Other changes:

  • handle_call/3 callback in the pipeline and areply and :reply_to actions. (#334)
  • Improvements in documentation - till now on, in the documentation page for each of the following modules: Membrane.Source, Membrane.Filter, Membrane.Endpoint and Membrane.Sink there is a list of all the callbacks available to be implemented for these modules.
  • Membrane.Time.<plural unit name>/1 now accepts Ratio structure as an argument. (#435)
  • Membrane.Time.round_to_timebase/2 function has been added. (#435)
  • Membrane.FilterAggregator that 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.MockResourceGuard has been added, to help write tests with the new way of handling resources. (#478)

Release v0.10.2

26 Jul 09:42
Compare
Choose a tag to compare

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

16 May 12:44
bdaefef
Compare
Choose a tag to compare

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.Pipeline with a custom module injected behaves in a desired way once Membrane.Testing.Pipeline.execute_actions/2 function is called (the custom module does not need to implement handle_other({:execute_actions, actions}, ...) anymore)

Full changelog: v0.10.0 ... v0.10.1

v0.10.0

28 Apr 09:06
72c86ba
Compare
Choose a tag to compare

Release includes:

  • removing deprecated stuff #399:
    • Support for returning bare Membrane.ParentSpec{} from handle_init/1
    • Support for callbacks without context argument in Pipeline and Bin
    • Membrane.Element.WithInputPads.def_input_pads/1
    • Membrane.Element.WithOutputPads.def_output_pads/1
    • Membrane.Log.*
    • Membrane.ParentSpec.link_bin_input/2
    • Membrane.ParentSpec.to_bin_output/2
    • Following functions inMembrane.Time: is_t/1, system_time/0, native_unit/1, day/1, hour/1, minute/1, second/1, millisecond/1, microsecond/1, nanosecond/1
  • making Membrane.Pipeline.{prepare, play, stop} deprecated and adding :playback action instead
  • making Membrane.Pipeline.stop_and_terminate/2 deprecated and adding Membrane.Pipeline.terminate/2 instead
  • adding the Membrane.RemoteControlled.Pipeline - a basic implementation of a Membrane.Pipeline that
    can be spawned and controlled by an external process #366
  • disallowing sending buffers through pads without sending the caps first, by raising an Membrane.ElementError exception if such a situation occurs #341
  • refining the Membrane.Testing.Pipeline API - deprecating the Membrane.Testing.Pipeline.Options usage, allowing to use pipeline_keyword_list_t as options in Membrane.Testing.Pipeline.start/1 and Membrane.Testing.Pipeline.start_link/1

Full changelog: v0.9.0 ... v0.10.0

v0.9.0 - Automatic demands

15 Feb 13:25
c51556f
Compare
Choose a tag to compare

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: :any

This 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 :stopped will 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

28 Dec 15:54
Compare
Choose a tag to compare

Release includes:

  • Fixed PadAdded spec #359
  • Prevent internal testing notifications from reaching pipeline module #350
  • Fix unknown node error on distribution changes #352

v0.8.0

02 Nov 14:55
498a455
Compare
Choose a tag to compare

Release includes:

  • Adds the possibility to specify Membrane.Logger metadata in the Membrane.ParentSpec. All children spawned from that Membrane.ParentSpec will receive specified metadata.
  • PTS and DTS timestamps were added to Membrane.Buffer structure 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