From ccd4c32ff63d8c5420eff0982c9045e05f999a39 Mon Sep 17 00:00:00 2001 From: saxon Date: Tue, 1 Jan 2019 16:03:04 +1030 Subject: [PATCH 01/10] revid: revid now has it's own rtpSender seperate from the loadSender slice used for multiple outputs, therefore, we can now bypass the ringbuffer in this case with a check if the rtpSender exists in the packer write method --- revid/revid.go | 15 ++++++++++++--- revid/senders.go | 14 +++++++++++--- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index 9e9efbd1..b4f7ac9d 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -118,6 +118,9 @@ type Revid struct { // destination is the target endpoint. destination []loadSender + // rtpSender + rtpSndr *rtpSender + // bitrate hold the last send bitrate calculation result. bitrate int @@ -147,6 +150,13 @@ func (p *packer) Write(frame []byte) (int, error) { return len(frame), nil } n, err := p.owner.buffer.Write(frame) + // If we have an rtp sender bypass and give straight to sender + if p.owner.rtpSndr != nil { + err = p.owner.rtpSndr.send(frame) + if err != nil { + p.owner.config.Logger.Log(smartlogger.Error, pkg+"rtp send failed with error", "error", err.Error()) + } + } if err != nil { if err == ring.ErrDropped { p.owner.config.Logger.Log(smartlogger.Warning, pkg+"dropped frame", "frame size", len(frame)) @@ -213,7 +223,7 @@ func (r *Revid) reset(config Config) error { } n := 1 - if r.config.Output2 != 0 { + if r.config.Output2 != 0 && r.config.Output2 != Rtp { n = 2 } r.destination = make([]loadSender, n) @@ -247,11 +257,10 @@ func (r *Revid) reset(config Config) error { } r.destination[outNo] = s case Rtp: - s, err := newRtpSender(r.config.RtpAddress, r.config.Logger.Log, r.config.FrameRate) + r.rtpSndr, err = newRtpSender(r.config.RtpAddress, r.config.Logger.Log, r.config.FrameRate) if err != nil { return err } - r.destination[outNo] = s } } diff --git a/revid/senders.go b/revid/senders.go index 6606350e..eab8af7c 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -388,9 +388,17 @@ func (s *rtpSender) load(c *ring.Chunk) error { return nil } -func (s *rtpSender) send() error { - _, err := s.chunk.WriteTo(s.encoder) - return err +func (s *rtpSender) send(d []byte) error { + var err error + if d != nil { + _, err = s.encoder.Write(d) + } else { + _, err = s.chunk.WriteTo(s.encoder) + } + if err != nil { + return err + } + return nil } func (s *rtpSender) release() { From d0d9e20c875809eeb60300b9b1d8c3b0fa78c8b4 Mon Sep 17 00:00:00 2001 From: saxon Date: Tue, 1 Jan 2019 16:11:32 +1030 Subject: [PATCH 02/10] revid: if no data is provided to rtpSender.send() then we check if the rtpSenders chunk is not nil, if it is, then return error --- revid/senders.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/revid/senders.go b/revid/senders.go index eab8af7c..c601bfec 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -29,6 +29,7 @@ LICENSE package revid import ( + "errors" "fmt" "io" "net" @@ -392,13 +393,12 @@ func (s *rtpSender) send(d []byte) error { var err error if d != nil { _, err = s.encoder.Write(d) - } else { + } else if s.chunk != nil { _, err = s.chunk.WriteTo(s.encoder) + } else { + err = errors.New("no data provided, but rtpSender chunk is empty") } - if err != nil { - return err - } - return nil + return err } func (s *rtpSender) release() { From aefdc46273fffed4b958c59532bd4ee7450f7704 Mon Sep 17 00:00:00 2001 From: saxon Date: Wed, 2 Jan 2019 08:50:59 +1030 Subject: [PATCH 03/10] revid: updated some comments --- revid/revid.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index b4f7ac9d..3ab67e7f 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -118,7 +118,8 @@ type Revid struct { // destination is the target endpoint. destination []loadSender - // rtpSender + // Rtp sending doesn't use ring buffer so we isolate this from Destination + // above rtpSndr *rtpSender // bitrate hold the last send bitrate calculation result. @@ -150,7 +151,7 @@ func (p *packer) Write(frame []byte) (int, error) { return len(frame), nil } n, err := p.owner.buffer.Write(frame) - // If we have an rtp sender bypass and give straight to sender + // If we have an rtp sender bypass ringbuffer and give straight to sender if p.owner.rtpSndr != nil { err = p.owner.rtpSndr.send(frame) if err != nil { From 496fa994bdacaaa2441d78e43c1182eb91e9d891 Mon Sep 17 00:00:00 2001 From: saxon Date: Thu, 3 Jan 2019 11:57:43 +1030 Subject: [PATCH 04/10] revid: rtpSndr=>rtpSender --- revid/revid.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index 3ab67e7f..ffd1df37 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -120,7 +120,7 @@ type Revid struct { // Rtp sending doesn't use ring buffer so we isolate this from Destination // above - rtpSndr *rtpSender + rtpSender *rtpSender // bitrate hold the last send bitrate calculation result. bitrate int @@ -152,8 +152,8 @@ func (p *packer) Write(frame []byte) (int, error) { } n, err := p.owner.buffer.Write(frame) // If we have an rtp sender bypass ringbuffer and give straight to sender - if p.owner.rtpSndr != nil { - err = p.owner.rtpSndr.send(frame) + if p.owner.rtpSender != nil { + err = p.owner.rtpSender.send(frame) if err != nil { p.owner.config.Logger.Log(smartlogger.Error, pkg+"rtp send failed with error", "error", err.Error()) } From 53d737d4269a13218ae216b0efb9555e33d89c86 Mon Sep 17 00:00:00 2001 From: saxon Date: Thu, 3 Jan 2019 11:59:29 +1030 Subject: [PATCH 05/10] revid: missed a rtpSndr --- revid/revid.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index b4db80a0..2ae77868 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -155,7 +155,7 @@ func (p *packer) Write(frame []byte) (int, error) { if p.owner.rtpSender != nil { err = p.owner.rtpSender.send(frame) if err != nil { - p.owner.config.Logger.Log(smartlogger.Error, pkg+"rtp send failed with error", "error", err.Error()) + p.owner.config.Logger.Log(logger.Error, pkg+"rtp send failed with error", "error", err.Error()) } } if err != nil { @@ -258,7 +258,7 @@ func (r *Revid) reset(config Config) error { } r.destination[outNo] = s case Rtp: - r.rtpSndr, err = newRtpSender(r.config.RtpAddress, r.config.Logger.Log, r.config.FrameRate) + r.rtpSender, err = newRtpSender(r.config.RtpAddress, r.config.Logger.Log, r.config.FrameRate) if err != nil { return err } From e12f3e0b4195c29aee88152b046c09f7ee56e14c Mon Sep 17 00:00:00 2001 From: saxon Date: Thu, 3 Jan 2019 12:03:06 +1030 Subject: [PATCH 06/10] revid: updated comment above revid.rtpSender declaration --- revid/revid.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index 2ae77868..4c3cd75e 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -118,8 +118,8 @@ type Revid struct { // destination is the target endpoint. destination []loadSender - // Rtp sending doesn't use ring buffer so we isolate this from Destination - // above + // rtpSender is an unbuffered sender. + // It is used to isolate RTP from ring buffer-induced delays. rtpSender *rtpSender // bitrate hold the last send bitrate calculation result. From a934e02e9a8be5abcab99f37f4c6eed3c6a8c998 Mon Sep 17 00:00:00 2001 From: saxon Date: Thu, 3 Jan 2019 12:06:51 +1030 Subject: [PATCH 07/10] revid: using switch in rtpSender.send logic rather than if-else --- revid/senders.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/revid/senders.go b/revid/senders.go index 0cb61ee8..4a8e2db8 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -391,11 +391,12 @@ func (s *rtpSender) load(c *ring.Chunk) error { func (s *rtpSender) send(d []byte) error { var err error - if d != nil { + switch { + case d != nil: _, err = s.encoder.Write(d) - } else if s.chunk != nil { + case s.chunk != nil: _, err = s.chunk.WriteTo(s.encoder) - } else { + default: err = errors.New("no data provided, but rtpSender chunk is empty") } return err From 4da0bddf2fa4f8a2dc893fc2db32aa1460193ead Mon Sep 17 00:00:00 2001 From: saxon Date: Thu, 3 Jan 2019 12:08:41 +1030 Subject: [PATCH 08/10] revid: improved error message in rtpSender.send when there is no data provided but also when there is no data in the senders chunk --- revid/senders.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/revid/senders.go b/revid/senders.go index 4a8e2db8..aa7144a6 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -397,7 +397,7 @@ func (s *rtpSender) send(d []byte) error { case s.chunk != nil: _, err = s.chunk.WriteTo(s.encoder) default: - err = errors.New("no data provided, but rtpSender chunk is empty") + err = errors.New("no data to send provided, but rtpSender chunk is also empty") } return err } From 5f20086440f96ff3d74835397aad8a3cccfdefc1 Mon Sep 17 00:00:00 2001 From: saxon Date: Thu, 3 Jan 2019 12:57:50 +1030 Subject: [PATCH 09/10] rtp: removed code in rtpSender relating to chunks - something we're not using anymore in this case --- revid/senders.go | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/revid/senders.go b/revid/senders.go index aa7144a6..662f4973 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -368,7 +368,6 @@ func (s *udpSender) close() error { return nil } // rtpSender implements loadSender for a native udp destination with rtp packetization. type rtpSender struct { log func(lvl int8, msg string, args ...interface{}) - chunk *ring.Chunk encoder *rtp.Encoder } @@ -384,27 +383,12 @@ func newRtpSender(addr string, log func(lvl int8, msg string, args ...interface{ return s, nil } -func (s *rtpSender) load(c *ring.Chunk) error { - s.chunk = c - return nil -} - func (s *rtpSender) send(d []byte) error { var err error - switch { - case d != nil: + if d != nil { _, err = s.encoder.Write(d) - case s.chunk != nil: - _, err = s.chunk.WriteTo(s.encoder) - default: + } else { err = errors.New("no data to send provided, but rtpSender chunk is also empty") } return err } - -func (s *rtpSender) release() { - s.chunk.Close() - s.chunk = nil -} - -func (s *rtpSender) close() error { return nil } From 26a43d54bb9fddc0b4c70698fc35df16a15b7b1a Mon Sep 17 00:00:00 2001 From: saxon Date: Thu, 3 Jan 2019 13:01:35 +1030 Subject: [PATCH 10/10] rtp: updated error message to suit new rtpSender.send() function --- revid/senders.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/revid/senders.go b/revid/senders.go index 662f4973..16087fba 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -388,7 +388,7 @@ func (s *rtpSender) send(d []byte) error { if d != nil { _, err = s.encoder.Write(d) } else { - err = errors.New("no data to send provided, but rtpSender chunk is also empty") + err = errors.New("no data to send provided") } return err }