Membrane Core Versions Save

The core of the Membrane Framework, advanced multimedia processing framework

v0.11.0

1 year ago

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)

v0.10.2

1 year ago

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.

v0.10.1

2 years ago

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

2 years ago

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

2 years ago

Automatic demands

The Membrane Core can now handle the demands in filters for you! :tada: 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: https://github.com/membraneframework/membrane_core/compare/v0.8.2...v0.9.0

v0.8.2

2 years ago

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

2 years ago

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

v0.7.0

2 years ago

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 
end

Limitations

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.

v0.6.1

3 years ago

This release includes several bug fixes:

  • bin pad opts handling #282
  • docs generation #283
  • children playback state management #284

v0.6.0

3 years ago

Breaking changes

  • Callbacks in pipelines and bins now have the context argument #278
  • [Fix] Remove stale Membrane.Event.{StartOfStream, EndOfStream} events. Since v0.5.0 they're replaced with dedicated action and callbacks #280

Other changes

  • Bins and pipelines can now use timers #264
  • forward action in pipelines and bins now accepts list #279
  • Docs fixes #280
  • Started integration with telemetry #269