-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Queue buffers when auto demand is low enough #693
Changes from 25 commits
00794c3
9be7be2
4188729
e49d57e
0958822
b075c70
99396d4
6c1da19
b66662d
2430810
6d56f0c
e32c255
5e5f5b3
c65b2bb
242d25f
de2fc22
16f4d4b
2391f09
08a7f4d
3725afe
7a5c71a
b7e79b4
3b9fdcb
2cdd49e
379871c
9018e3c
e1aadcc
9e85059
12c1273
ca1b221
7032d9b
b471d29
01728df
4f02735
95b1848
6ca21dd
2720120
c929433
9313f2c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -24,11 +24,11 @@ defmodule Membrane.Core.Element.ActionHandler do | |||||||||||||||
alias Membrane.Core.Element.{ | ||||||||||||||||
DemandController, | ||||||||||||||||
DemandHandler, | ||||||||||||||||
PadController, | ||||||||||||||||
State, | ||||||||||||||||
StreamFormatController | ||||||||||||||||
} | ||||||||||||||||
|
||||||||||||||||
alias Membrane.Core.Element.DemandController.AutoFlowUtils | ||||||||||||||||
alias Membrane.Core.{Events, TimerController} | ||||||||||||||||
alias Membrane.Element.Action | ||||||||||||||||
|
||||||||||||||||
|
@@ -466,8 +466,9 @@ defmodule Membrane.Core.Element.ActionHandler do | |||||||||||||||
@spec handle_outgoing_event(Pad.ref(), Event.t(), State.t()) :: State.t() | ||||||||||||||||
defp handle_outgoing_event(pad_ref, %Events.EndOfStream{}, state) do | ||||||||||||||||
with %{direction: :output, end_of_stream?: false} <- PadModel.get_data!(state, pad_ref) do | ||||||||||||||||
state = PadController.remove_pad_associations(pad_ref, state) | ||||||||||||||||
PadModel.set_data!(state, pad_ref, :end_of_stream?, true) | ||||||||||||||||
Map.update!(state, :satisfied_auto_output_pads, &MapSet.delete(&1, pad_ref)) | ||||||||||||||||
|> PadModel.set_data!(pad_ref, :end_of_stream?, true) | ||||||||||||||||
|> AutoFlowUtils.pop_queues_and_bump_demand() | ||||||||||||||||
Comment on lines
+473
to
+475
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
else | ||||||||||||||||
%{direction: :input} -> | ||||||||||||||||
raise PadDirectionError, action: "end of stream", direction: :input, pad: pad_ref | ||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -139,14 +139,14 @@ defmodule Membrane.Core.Element.AtomicDemand do | |
:ok | ||
end | ||
|
||
@spec decrease(t, non_neg_integer()) :: t | ||
@spec decrease(t, non_neg_integer()) :: {{:decreased, integer()}, t} | {:unchanged, t} | ||
def decrease(%__MODULE__{} = atomic_demand, value) do | ||
atomic_demand = Map.update!(atomic_demand, :buffered_decrementation, &(&1 + value)) | ||
|
||
if atomic_demand.buffered_decrementation >= atomic_demand.throttling_factor do | ||
flush_buffered_decrementation(atomic_demand) | ||
else | ||
atomic_demand | ||
{:unchanged, atomic_demand} | ||
end | ||
end | ||
|
||
|
@@ -164,14 +164,17 @@ defmodule Membrane.Core.Element.AtomicDemand do | |
|
||
atomic_demand = %{atomic_demand | buffered_decrementation: 0} | ||
|
||
if not atomic_demand.toilet_overflowed? and | ||
get_receiver_status(atomic_demand) == {:resolved, :pull} and | ||
get_sender_status(atomic_demand) == {:resolved, :push} and | ||
-1 * atomic_demand_value > atomic_demand.toilet_capacity do | ||
overflow(atomic_demand, atomic_demand_value) | ||
else | ||
atomic_demand | ||
end | ||
atomic_demand = | ||
if not atomic_demand.toilet_overflowed? and | ||
get_receiver_status(atomic_demand) == {:resolved, :pull} and | ||
get_sender_status(atomic_demand) == {:resolved, :push} and | ||
-1 * atomic_demand_value > atomic_demand.toilet_capacity do | ||
overflow(atomic_demand, atomic_demand_value) | ||
else | ||
atomic_demand | ||
end | ||
Comment on lines
+167
to
+175
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Little suggestion, to break this conditional block; # in the function
atomic_demand = handle_atomic_demand(atomic_demand, atomic_demand_value)
{{:decreased, atomic_demand_value}, atomic_demand}
# in the code abyss...
@spec handle_atomic_demand...
defp handle_atomic_demand(atomic_demand, atomic_demand_value) do
if should_overflow?(atomic_demand, atomic_demand_value) do
overflow_demand(atomic_demand, atomic_demand_value)
else
atomic_demand
end
end
@spec should_overflow?...
# maybe it would be worth adding doc here?
defp should_overflow?(demand, value) do
not demand.overflowed? and
resolved_pull?(demand) and
resolved_push?(demand) and
exceeds_capacity?(value, demand.capacity)
end
@spec ..
defp resolved_pull?(demand), do: get_receiver_status(demand) == {:resolved, :pull}
defp resolved_push?(demand), do: get_sender_status(demand) == {:resolved, :push}
defp exceeds_capacity?(value, capacity), do: -1 * value > capacity |
||
|
||
{{:decreased, atomic_demand_value}, atomic_demand} | ||
end | ||
|
||
defp overflow(atomic_demand, atomic_demand_value) do | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,13 +23,20 @@ defmodule Membrane.Core.Element.DemandController do | |
|
||
@spec snapshot_atomic_demand(Pad.ref(), State.t()) :: State.t() | ||
def snapshot_atomic_demand(pad_ref, state) do | ||
with {:ok, pad_data} <- PadModel.get_data(state, pad_ref), | ||
with {:ok, pad_data} when not pad_data.end_of_stream? <- PadModel.get_data(state, pad_ref), | ||
%State{playback: :playing} <- state do | ||
if pad_data.direction == :input, | ||
do: raise("cannot snapshot atomic counter in input pad") | ||
|
||
do_snapshot_atomic_demand(pad_data, state) | ||
else | ||
{:ok, %{end_of_stream?: true}} -> | ||
Membrane.Logger.debug_verbose( | ||
"Skipping snapshot of pad #{inspect(pad_ref)}, because it has flag :end_of_stream? set to true" | ||
) | ||
|
||
state | ||
|
||
{:error, :unknown_pad} -> | ||
# We've got a :atomic_demand_increased message on already unlinked pad | ||
state | ||
|
@@ -43,13 +50,10 @@ defmodule Membrane.Core.Element.DemandController do | |
%{flow_control: :auto} = pad_data, | ||
%{effective_flow_control: :pull} = state | ||
) do | ||
%{ | ||
atomic_demand: atomic_demand, | ||
associated_pads: associated_pads | ||
} = pad_data | ||
|
||
if AtomicDemand.get(atomic_demand) > 0 do | ||
AutoFlowUtils.auto_adjust_atomic_demand(associated_pads, state) | ||
if AtomicDemand.get(pad_data.atomic_demand) > 0 do | ||
state | ||
|> Map.update!(:satisfied_auto_output_pads, &MapSet.delete(&1, pad_data.ref)) | ||
|> AutoFlowUtils.pop_queues_and_bump_demand() | ||
else | ||
state | ||
end | ||
|
@@ -91,9 +95,15 @@ defmodule Membrane.Core.Element.DemandController do | |
buffers_size = Buffer.Metric.from_unit(pad_data.demand_unit).buffers_size(buffers) | ||
|
||
demand = pad_data.demand - buffers_size | ||
atomic_demand = AtomicDemand.decrease(pad_data.atomic_demand, buffers_size) | ||
{decrease_result, atomic_demand} = AtomicDemand.decrease(pad_data.atomic_demand, buffers_size) | ||
|
||
PadModel.set_data!(state, pad_ref, %{ | ||
with {:decreased, new_value} when new_value <= 0 <- decrease_result, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What 0 represent? Could it be dumped into module attr, to avoid magic numbers? |
||
%{flow_control: :auto} <- pad_data do | ||
Map.update!(state, :satisfied_auto_output_pads, &MapSet.put(&1, pad_ref)) | ||
else | ||
_other -> state | ||
end | ||
|> PadModel.set_data!(pad_ref, %{ | ||
pad_data | ||
| demand: demand, | ||
atomic_demand: atomic_demand | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.