Skip to content
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

Allow multiple parents and fix hanging producer #1431

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7bc6ba9
Allow multiple parents and fix hanging producer
seydx Nov 3, 2024
ff3e354
Improve managing from parent and child nodes
seydx Nov 7, 2024
fb7ed66
Track failed producer state to prevent restart loop
seydx Nov 7, 2024
b4d2c53
typo
seydx Nov 8, 2024
d9d6afc
Optimize child and parent relationships and improve synchronization
seydx Nov 9, 2024
188c2d8
Merge branch 'master' into multiple-parents
seydx Nov 13, 2024
683bfdf
revert failed state for producer
seydx Nov 13, 2024
10a1e8a
Fix broken incoming sources after v1.9.7 #1458
AlexxIT Nov 14, 2024
334bbb3
Merge branch 'AlexxIT:master' into multiple-parents
seydx Nov 15, 2024
d854b2d
Merge branch 'AlexxIT:master' into multiple-parents
seydx Dec 13, 2024
196018d
Merge branch 'master' into multiple-parents
seydx Jan 12, 2025
9ad9180
Merge branch 'master' into multiple-parents
seydx Jan 25, 2025
601c433
Add support H264, H265, NV12 for V4L2 source #1546
AlexxIT Jan 26, 2025
9a8cc22
Ignore unknown NAL unit types for RTP/H264 #1570
AlexxIT Feb 2, 2025
4470e79
Improve delay for MSE player
AlexxIT Feb 2, 2025
6aa1a6a
Add readme for V4L2 module
AlexxIT Feb 2, 2025
a66eec6
Merge branch 'AlexxIT:master' into multiple-parents
seydx Feb 10, 2025
e8797c0
Code refactoring for multi parents
AlexxIT Feb 21, 2025
c10e4a4
Merge branch 'AlexxIT:master' into multiple-parents
seydx Mar 11, 2025
b797495
Merge branch 'AlexxIT:master' into multiple-parents
seydx Mar 12, 2025
0bab1df
Merge branch 'AlexxIT:master' into multiple-parents
seydx Mar 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions internal/streams/dot.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ func humanBytes(i int) string {
}

type node struct {
ID uint32 `json:"id"`
Codec map[string]any `json:"codec"`
Parent uint32 `json:"parent"`
Childs []uint32 `json:"childs"`
Bytes int `json:"bytes"`
ID uint32 `json:"id"`
Codec map[string]any `json:"codec"`
Parents []uint32 `json:"parents"`
Childs []uint32 `json:"childs"`
Bytes int `json:"bytes"`
//Packets uint32 `json:"packets"`
//Drops uint32 `json:"drops"`
}
Expand Down Expand Up @@ -124,9 +124,11 @@ func (c *conn) appendDOT(dot []byte, group string) []byte {
dot = recv.appendDOT(dot, "node")
}
for _, send := range c.Senders {
dot = fmt.Appendf(dot, "%d -> %d [label=%q];\n", send.Parent, c.ID, humanBytes(send.Bytes))
//dot = fmt.Appendf(dot, "%d -> %d [label=%q];\n", send.ID, c.ID, humanBytes(send.Bytes))
//dot = send.appendDOT(dot, "node")
for _, parentID := range send.Parents {
dot = fmt.Appendf(dot, "%d -> %d [label=%q];\n", parentID, c.ID, humanBytes(send.Bytes))
//dot = fmt.Appendf(dot, "%d -> %d [label=%q];\n", send.ID, c.ID, humanBytes(send.Bytes))
//dot = send.appendDOT(dot, "node")
}
}
return dot
}
Expand Down
48 changes: 32 additions & 16 deletions pkg/core/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ type Node struct {
Input HandlerFunc
Output HandlerFunc

id uint32
childs []*Node
parent *Node
id uint32
childs []*Node
parents []*Node

mu sync.Mutex
}
Expand All @@ -44,30 +44,41 @@ func (n *Node) AppendChild(child *Node) {
n.childs = append(n.childs, child)
n.mu.Unlock()

child.parent = n
child.mu.Lock()
child.parents = append(child.parents, n)
child.mu.Unlock()
}

func (n *Node) RemoveChild(child *Node) {
n.mu.Lock()
for i, ch := range n.childs {
if ch == child {
n.childs = append(n.childs[:i], n.childs[i+1:]...)
break
}
if i := Index(n.childs, child); i != -1 {
n.childs = append(n.childs[:i], n.childs[i+1:]...)
}
n.mu.Unlock()

child.mu.Lock()
if i := Index(child.parents, n); i != -1 {
child.parents = append(child.parents[:i], child.parents[i+1:]...)
}
child.mu.Unlock()
}

func (n *Node) Close() {
if parent := n.parent; parent != nil {
parent.RemoveChild(n)
n.mu.Lock()
if n.parents != nil && len(n.parents) > 0 {
parents := n.parents
n.mu.Unlock()

if len(parent.childs) == 0 {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this is missing?

parent.Close()
for _, parent := range parents {
parent.RemoveChild(n)
}
} else {
for _, childs := range n.childs {
childs.Close()
childs := n.childs
n.childs = nil
n.mu.Unlock()

for _, child := range childs {
child.Close()
}
}
}
Expand All @@ -83,6 +94,11 @@ func MoveNode(dst, src *Node) {
dst.mu.Unlock()

for _, child := range childs {
child.parent = dst
child.mu.Lock()
if i := Index(child.parents, dst); i != -1 {
child.parents = append(child.parents[:i], child.parents[i+1:]...)
}
child.parents = append(child.parents, dst)
child.mu.Unlock()
}
}
20 changes: 10 additions & 10 deletions pkg/core/track.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,12 @@ func (s *Sender) WithParent(parent *Receiver) *Sender {

func (s *Sender) Start() {
s.mu.Lock()
defer s.mu.Unlock()

if s.buf == nil || s.done != nil {
s.mu.Unlock()
return
}
s.done = make(chan struct{})
s.mu.Unlock()

go func() {
// for range on nil chan is OK
Expand Down Expand Up @@ -197,21 +197,21 @@ func (r *Receiver) MarshalJSON() ([]byte, error) {

func (s *Sender) MarshalJSON() ([]byte, error) {
v := struct {
ID uint32 `json:"id"`
Codec *Codec `json:"codec"`
Parent uint32 `json:"parent,omitempty"`
Bytes int `json:"bytes,omitempty"`
Packets int `json:"packets,omitempty"`
Drops int `json:"drops,omitempty"`
ID uint32 `json:"id"`
Codec *Codec `json:"codec"`
Parents []*uint32 `json:"parents,omitempty"`
Bytes int `json:"bytes,omitempty"`
Packets int `json:"packets,omitempty"`
Drops int `json:"drops,omitempty"`
}{
ID: s.Node.id,
Codec: s.Node.Codec,
Bytes: s.Bytes,
Packets: s.Packets,
Drops: s.Drops,
}
if s.parent != nil {
v.Parent = s.parent.id
for _, parent := range s.parents {
v.Parents = append(v.Parents, &parent.id)
}
return json.Marshal(v)
}