View Source Upgrading to v1.0.0
Comparing to v0.12, v1.0.0 introduces some minor changes in the public API of the framework. This guide was created to help you migrate to v1.0.0 of membrane_core
.
Deps
Update membrane_core
to v1.0.0
defp deps do
[
{:membrane_core, "~> 1.0.0"},
...
]
end
Rename handle_process/4
and handle_write/4
into handle_buffer/4
Names of the callbacks that are used to process buffers have been unified. This applies to:
- Membrane.Filter.handle_process/4
- Membrane.Endpoint.handle_write/4
- Membrane.Sink.handle_write/4
and they became Membrane.Element.WithInputPads.handle_buffer/4
@impl true
- def handle_process(pad, buffer, ctx, state) do
+ def handle_buffer(pad, buffer, ctx, state) do
...
end
Remove handle_process_list/4
and handle_write_list/4
callback
Since v1.0.0
, you have to handle every single buffer separately in handle_buffer/4
callback, instead of handling whole list of buffers in this in handle_process_list/4
or handle_write_list/4
.
@impl true
- def handle_process_list(pad_ref, buffers_list, ctx, state) do
+ def handle_buffer(pad_ref, buffer, ctx, state) do
...
end
@impl true
- def handle_write_list(pad_ref, buffers_list, ctx, state) do
+ def handle_buffer(pad_ref, buffer, ctx, state) do
...
end
Change mode
and demand_mode
options to flow_control
in pads' definitions in elements
For input pads, change:
use Membrane.Filter
# or Sink or Endpoint
- def_input_pad :input, mode: :push, ...
+ def_input_pad :input, flow_control: :push, ...
- def_input_pad :input, mode: :pull, demand_mode: :auto, demand_unit: :buffers, ...
+ def_input_pad :input, ...
# (because `flow_control: :auto` is the default whenever available - currently in Filters)
# Note that having `flow_control: :auto` doesn't allow to pass `demand_unit`,
# as it's determined automatically
- def_input_pad :input, mode: :pull, demand_unit: :buffers, ...
+ def_input_pad :input, flow_control: :manual, demand_unit: :buffers, ...
Same goes for output pads:
use Membrane.Filter
# or Source or Endpoint
- def_output_pad :output, mode: :push, ...
+ def_output_pad :output, flow_control: :push, ...
- def_output_pad :output, mode: :pull, demand_mode: :auto, ...
+ def_output_pad :output, ...
- def_output_pad :output, mode: :pull, ...
+ def_output_pad :output, flow_control: :manual, ...
Check Membrane.Pad.element_spec/0
for details.
Adjust to change in default flow_control
(aka. mode
/demand_mode
) value.
Now, if definition of pad in element does specify type of
Now, the default value of flow_control
option in def_input_pad
and def_output_pad
in Elements is :auto
. Until v0.12.9
, pads that sepcified neither flow_control
, mode
nor demand_mode
explicitly would have :manual
flow_control
. Therefore, :manual
pads that haven't specified flow_control
value, now have to do it explicitly.
- def_output_pad :output, accepted_format: %MyStruct{field: :value}
+ def_output_pad :output, accepted_format: %MyStruct{field: :value}, flow_control: :manual
- def_input_pad :input, accepted_format: %MyStruct{field: :value}, demand_unit: :buffers
+ def_input_pad :input, accepted_format: %MyStruct{field: :value}, demand_unit: :buffers, flow_control: :manual
Moreover, you can remove flow_control: :auto
from the pad definitions, if you want to.
- def_input_pad :input, accepted_format: %MyStruct{field: :value}, flow_control: :auto
+ def_input_pad :input, accepted_format: %MyStruct{field: :value}
Remove mode
and demand_unit
from pads definitions in bins
use Membrane.Bin
- def_input_pad :input, mode: :pull, demand_unit: :buffers, ...
+ def_input_pad :input, ...
- def_output_pad :output, mode: :push, ...
+ def_output_pad :output, ...
Check Membrane.Pad.bin_spec/0
for details.
Don't refer to callback contexts as to structs
Callback contexts are now plain maps instead of structs. So, for example, if you happen to have a match like below, convert it to a match on a map:
@impl true
- def handle_info(message, %Membrane.Element.CallbackContext.Info{pads: pads}, state) do
+ def handle_info(message, %{pads: pads}, state) do
...
end
Additionally, there's no direction
field anymore in the callback context for handle_pad_added
and handle_pad_removed
- the direction can be determined by the pad name. All other fields remain the same.
@impl true
- def handle_pad_added(_pad, %{direction: :input}, state) do
+ def handle_pad_added(Pad.ref(:input, _id), _ctx, state) do
...
end
Check Membrane.Element.CallbackContext.t/0
, Membrane.Bin.CallbackContext.t/0
and Membrane.Pipeline.CallbackContext.t/0
for outline of what can be found in the contexts. Additionally, each callback that provides extra fields in the context, has them mentioned in its docs.
Use Membrane.RCPipeline
instead of Membrane.RemoteControlled.Pipeline
- pipeline = Membrane.RemoteControlled.Pipeline.start_link!()
+ pipeline = Membrane.RCPipeline.start_link!()
Same goes for Membrane.RemoteControlled.Message
-> Membrane.RCMessage
receive do
- %Membrane.RemoteControlled.Message.Notification{data: data} -> data
+ %Membrane.RCMessage.Notification{data: data} -> data
end
Use Membrane.Time.as_<unit>(time, :round)
instead of Membrane.Time.round_to_<unit>(time)
- Membrane.Time.round_to_milliseconds(time)
+ Membrane.Time.as_milliseconds(time, :round)
There is one exception for round_to_timebase
, which changed to divide_by_timebase
:
- Membrane.Time.round_to_timebase(time, timebase)
+ Membrane.Time.divide_by_timebase(time, timebase)
Check Membrane.Time
for details.
Implement you own start/*
, start_link/*
or terminate/1
function (if you want to)
Until v1.0.0-rc0
and v0.12
, Membrane has generated start/2
, start_link/2
, and terminate/1
functions in modules using Membrane.Pipeline
, if code developer hadn't done it explicitly. Since v1.0.0
, if you want to have these functions implemented in your pipeline module, you have to implement them on your own. Alternatively, you can always call Membrane.Pipeline.start(YourPipelineModule, init_arg, opts)
, Membrane.Pipeline.start_link(YourPipelineModule, init_arg, opts)
, and Membrane.Pipeline.terminate(pipeline_pid)
from beyond YourPipelineModule
without wrapping it into public functions.
Rename :structure
option passed to the Membrane.Testing.Pipeline
into :spec
import Membrane.ChildrenSpec
spec =
child(:source, %Membrane.Testing.Source{some_field: some_arg})
|> child(:sink), %Membrane.Testing.Sink{another_filed: another_arg}
- pipeline = Membrane.Testing.Pipeline.start_link_supervised(structure: spec)
+ pipeline = Membrane.Testing.Pipeline.start_link_supervised(spec: spec)
Adjust to possibility of receiving end of stream
on pads, that haven't received start of stream
yet.
Since v1.0.0
, Membrane will execute Membrane.Element.WithInputPads.handle_end_of_stream/3
for all pads, including these having start_of_stream?: false
.