-
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
Detect diamonds #909
base: master
Are you sure you want to change the base?
Detect diamonds #909
Conversation
# adding @component_path_prefix to component path causes that component path | ||
# always has more than 64 bytes, so it won't be copied during sending a message |
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.
I'm not convinced it's worth the hassle. Did you do any benchmarks? BTW, it seems we construct this 'serialized' component path every time we need it - I'd do that once and keep it in state.
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.
I see it's now constructed once, but I'm still unconvinced about prepending the prefix. Handling ref-counted binaries strains GC, and copying may be more efficient if the binary is small, so I wouldn't force either way, at least without benchmarks.
@@ -0,0 +1,207 @@ | |||
defmodule Membrane.Core.Element.DiamondDetectionController do | |||
@moduledoc false | |||
|
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.
Let's describe how the algorithm works
lib/membrane/core/element.ex
Outdated
defp do_handle_info(Message.new(:delete_diamond_detection_ref, diamond_detection_ref), state) do | ||
state = DiamondDetectionController.delete_diamond_detection_ref(diamond_detection_ref, state) | ||
{:noreply, state} | ||
end | ||
|
||
defp do_handle_info(Message.new(:start_diamond_detection_trigger, trigger_ref), state) do | ||
state = DiamondDetectionController.start_diamond_detection_trigger(trigger_ref, state) | ||
{:noreply, state} | ||
end | ||
|
||
defp do_handle_info(Message.new(:diamond_detection_trigger, trigger_ref), state) do | ||
state = DiamondDetectionController.handle_diamond_detection_trigger(trigger_ref, state) | ||
{:noreply, state} | ||
end | ||
|
||
defp do_handle_info(Message.new(:delete_diamond_detection_trigger_ref, trigger_ref), state) do | ||
state = DiamondDetectionController.delete_diamond_detection_trigger_ref(trigger_ref, state) | ||
{:noreply, state} | ||
end |
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.
These messages seem quite internal to the diamond detection. I'd make them a single message and dispatch within DiamondDetectionController
lib/membrane/core/element/state.ex
Outdated
diamond_detection_ref_to_path: %{ | ||
optional(reference()) => PathInGraph.t() | ||
}, | ||
diamond_detection_trigger_refs: MapSet.t(reference()), | ||
diamond_detection_postponed?: boolean() |
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.
let's put these into a single diamond_detection
map/struct
97730c6
to
1d003ba
Compare
# it means in :manual flow control or in :auto flow control if the effective flow control | ||
# is set to :pull. |
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.
# it means in :manual flow control or in :auto flow control if the effective flow control | |
# is set to :pull. | |
# that is they're either in the :manual flow control or in the :auto flow control and the effective flow control | |
# is set to :pull. |
# a pipeline that contains: | ||
# * MP4 demuxer that has two output pads | ||
# * MKV muxer that is linked to both of them | ||
# and let's assume that the MP4 container that is consumed by the MP4 demuxer is unbalanced. |
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.
# and let's assume that the MP4 container that is consumed by the MP4 demuxer is unbalanced. | |
# and let's assume that the MP4 file that is consumed by the MP4 demuxer is unbalanced | |
# (audio and video streams are not interleaved, for example audio comes first and then video) |
# * MKV muxer that is linked to both of them | ||
# and let's assume that the MP4 container that is consumed by the MP4 demuxer is unbalanced. | ||
# If the MKV muxer has pads working in pull mode, then demand on one pad will be satisfied, | ||
# but on the other won't, because the MP4 container is unbalanced. Then, if MP4 demuxer |
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.
# but on the other won't, because the MP4 container is unbalanced. Then, if MP4 demuxer | |
# but on the other won't, because the source MP4 file is unbalanced. Then, if the MP4 demuxer |
|
||
# Let's notice that: | ||
# * a new diamond can be created only after linking a new spec | ||
# * if the new spec caused some new diamond to occur, this diamond will contain some of |
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.
# * if the new spec caused some new diamond to occur, this diamond will contain some of | |
# * if the new spec created a new diamond, this diamond will contain some of |
# demand on the input, because one of the pads output with :auto flow control doesn't | ||
# have positive demand, so the whole pipeline will get stuck and won't process more data. | ||
|
||
# The algorithm is made of two phases: (1) triggering and (2) proper searching. |
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.
why proper searching? :P
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.
It is supposed to be a translation of "właściwe szukanie"
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.
Got it, 'proper' is more like 'correct'. The best term I know would be 'actual search', though I'd just go for 'search', since the whole process is called 'detection', not 'search', so there's no other 'search' unless I'm missing something ;)
:start | ||
| :start_trigger | ||
| :diamond_detection | ||
| :trigger | ||
| :delete_ref | ||
| :delete_trigger_ref, |
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.
I'm not a fan of these names :P there's start
, start_trigger
and trigger
, hard to tell the difference. diamond_detection
is pretty generic. They should at least correspond to the terms used in the algorithm description (proper search?), ideally be mentioned there
# adding @component_path_prefix to component path causes that component path | ||
# always has more than 64 bytes, so it won't be copied during sending a message |
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.
I see it's now constructed once, but I'm still unconvinced about prepending the prefix. Handling ref-counted binaries strains GC, and copying may be more efficient if the binary is small, so I wouldn't force either way, at least without benchmarks.
lib/membrane/core/element/state.ex
Outdated
serialized_component_path: nil, | ||
ref_to_path: %{}, | ||
trigger_refs: MapSet.new(), | ||
postponed?: false |
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.
NIT: You can move the type and initialization to the DiamondDetection module
# all elements whose output pads have been linked in this spec. The reference of the trigger | ||
# is always set to the spec reference. | ||
# After the spec status is set to :done, the parent component that returned the spec will | ||
# triggerall elements whose output pads have been linked in this spec (`type: :start_trigger`). |
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.
# triggerall elements whose output pads have been linked in this spec (`type: :start_trigger`). | |
# trigger all elements whose output pads have been linked in this spec (`type: :start_trigger`). |
# of the proper searching, this means that at the time there is at most one proper searching | ||
# postponed in the single element | ||
|
||
# (2) Proper searching: |
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.
Seems like 'proper' is still there, can we make it just 'searching'?
Closes #873