Packages
membrane_core
0.10.1
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.7
1.2.6
1.2.5
retired
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc1
1.1.2
1.1.1
1.1.0
1.1.0-rc1
1.1.0-rc0
1.0.1
1.0.0
1.0.0-rc1
1.0.0-rc0
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
retired
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.2
0.10.1
0.10.0
0.9.0
0.8.2
0.8.1
0.8.0
0.7.0
0.6.1
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0
Membrane Multimedia Framework (Core)
Current section
Files
Jump to
Current section
Files
lib/membrane/core/pipeline.ex
defmodule Membrane.Core.Pipeline do
@moduledoc false
use GenServer
alias __MODULE__.{ActionHandler, State}
alias Membrane.Clock
alias Membrane.Core.CallbackHandler
alias Membrane.Core.Parent.{ChildLifeController, LifecycleController}
alias Membrane.Core.TimerController
require Membrane.Core.Message, as: Message
require Membrane.Core.Telemetry, as: Telemetry
require Membrane.Logger
@impl GenServer
def init({module, pipeline_options}) do
pipeline_name = "pipeline@#{:erlang.pid_to_list(self())}"
:ok = Membrane.ComponentPath.set([pipeline_name])
:ok = Membrane.Logger.set_prefix(pipeline_name)
Telemetry.report_init(:pipeline)
{:ok, clock} = Clock.start_link(proxy: true)
state = %State{
module: module,
synchronization: %{
clock_proxy: clock,
clock_provider: %{clock: nil, provider: nil, choice: :auto},
timers: %{}
}
}
state =
CallbackHandler.exec_and_handle_callback(
:handle_init,
ActionHandler,
%{state: false},
[pipeline_options],
state
)
{:ok, state}
end
@impl GenServer
def handle_info(
Message.new(:playback_state_changed, [pid, new_playback_state]),
state
) do
state = ChildLifeController.child_playback_changed(pid, new_playback_state, state)
{:noreply, state}
end
@impl GenServer
def handle_info(Message.new(:change_playback_state, new_state), state) do
state = LifecycleController.change_playback_state(new_state, state)
{:noreply, state}
end
@impl GenServer
def handle_info(Message.new(:stream_management_event, [element_name, pad_ref, event]), state) do
state =
LifecycleController.handle_stream_management_event(event, element_name, pad_ref, state)
{:noreply, state}
end
@impl GenServer
def handle_info(Message.new(:notification, [from, notification]), state) do
state = LifecycleController.handle_notification(from, notification, state)
{:noreply, state}
end
@impl GenServer
def handle_info(Message.new(:timer_tick, timer_id), state) do
state = TimerController.handle_tick(timer_id, state)
{:noreply, state}
end
@impl GenServer
def handle_info(Message.new(:link_response, link_id), state) do
state = ChildLifeController.LinkHandler.handle_link_response(link_id, state)
{:noreply, state}
end
@impl GenServer
def handle_info(Message.new(:spec_linking_timeout, spec_ref), state) do
state = ChildLifeController.LinkHandler.handle_spec_timeout(spec_ref, state)
{:noreply, state}
end
@impl GenServer
def handle_info({:membrane_clock_ratio, clock, ratio}, state) do
state = TimerController.handle_clock_update(clock, ratio, state)
{:noreply, state}
end
@impl GenServer
def handle_info({:DOWN, _ref, :process, pid, reason} = message, state) do
if is_child_pid?(pid, state) do
state = ChildLifeController.handle_child_death(pid, reason, state)
{:noreply, state}
else
state = LifecycleController.handle_other(message, state)
{:noreply, state}
end
end
@impl GenServer
def handle_info(message, state) do
state = LifecycleController.handle_other(message, state)
{:noreply, state}
end
@impl GenServer
def terminate(reason, state) do
Telemetry.report_terminate(:pipeline)
:ok = state.module.handle_shutdown(reason, state.internal_state)
end
defp is_child_pid?(pid, state) do
Enum.any?(state.children, fn {_name, entry} -> entry.pid == pid end)
end
end