From 9876b0cd35d3f0dd8d3afce2952ff41c5190ac28 Mon Sep 17 00:00:00 2001 From: Scott Date: Tue, 24 Dec 2019 14:08:42 +1030 Subject: [PATCH 1/3] Created motion filter that has a minimum frame rate. --- filter/variable_fps.go | 68 ++++++++++++++++++++++++++++++++++++++++++ revid/config/config.go | 1 + revid/revid.go | 4 ++- 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 filter/variable_fps.go diff --git a/filter/variable_fps.go b/filter/variable_fps.go new file mode 100644 index 00000000..39c68d0d --- /dev/null +++ b/filter/variable_fps.go @@ -0,0 +1,68 @@ +/* +DESCRIPTION + A motion filter that has a variable frame rate. When motion is detected, + the filter sends all frames and when it is not, the filter sends frames + at a reduced rate, as set by a parameter. + +AUTHORS + Scott Barnard + +LICENSE + variable_fps.go is Copyright (C) 2019 the Australian Ocean Lab (AusOcean) + + It is free software: you can redistribute it and/or modify them + under the terms of the GNU General Public License as published by the + Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + It is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + in gpl.txt. If not, see http://www.gnu.org/licenses. +*/ + +package filter + +import ( + "io" +) + +// VariableFps is a filter that has a variable frame rate. When motion is +// detected, the filter sends all frames and when it is not, the filter +// sends frames at a reduced framerate. +type VariableFps struct { + motionFilter Filter + dst io.WriteCloser + frames uint + count uint +} + +// NewVariableFps returns a pointer to a new VariableFps filter. +func NewVariableFps(dst io.WriteCloser, fps float64) *VariableFps { + frames := uint(25 / fps) + mf := NewMOGFilter(dst, 25, 20, 500, 3, true) + return &VariableFps{mf, dst, frames, 0} +} + +// Implements io.Writer. +// Write applies the motion filter to the video stream. Frames are sent +// at a reduced frame rate, except when motion is detected, then all frames +// with motion are sent. +func (v *VariableFps) Write(f []byte) (int, error) { + v.count++ + if v.count > v.frames { + v.count = 0 + return v.dst.Write(f) + } + + return v.motionFilter.Write(f) +} + +// Implements io.Closer. +// Close calls the motion filter's Close method. +func (v *VariableFps) Close() error { + return v.motionFilter.Close() +} diff --git a/revid/config/config.go b/revid/config/config.go index 9a19f4ab..0fb687e8 100644 --- a/revid/config/config.go +++ b/revid/config/config.go @@ -112,6 +112,7 @@ const ( const ( FilterNoOp = iota FilterMOG + FilterVariableFPS ) // Config provides parameters relevant to a revid instance. A new config must diff --git a/revid/revid.go b/revid/revid.go index 8389939f..8c221738 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -333,6 +333,8 @@ func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate float64) (io. r.filter = filter.NewNoOp(r.encoders) case config.FilterMOG: r.filter = filter.NewMOGFilter(r.encoders, 25, 20, 500, 3, true) + case config.FilterVariableFPS: + r.filter = filter.NewVariableFps(r.encoders, 1.0) default: panic("Undefined Filter") } @@ -630,7 +632,7 @@ func (r *Revid) Update(vars map[string]string) error { r.cfg.Logger.Log(logger.Warning, pkg+"invalid VerticalFlip param", "value", value) } case "Filter": - m := map[string]int{"NoOp": config.FilterNoOp, "MOG": config.FilterMOG} + m := map[string]int{"NoOp": config.FilterNoOp, "MOG": config.FilterMOG, "VariableFPS": config.FilterVariableFPS} v, ok := m[value] if !ok { r.cfg.Logger.Log(logger.Warning, pkg+"invalid FilterMethod param", "value", value) From 5286ded51f308c712f55372d566f6bdfdf666e1a Mon Sep 17 00:00:00 2001 From: Scott Date: Fri, 27 Dec 2019 13:51:50 +1030 Subject: [PATCH 2/3] Small fixes and simplifications --- filter/variable_fps.go | 12 ++++++------ revid/revid.go | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/filter/variable_fps.go b/filter/variable_fps.go index 39c68d0d..606b3656 100644 --- a/filter/variable_fps.go +++ b/filter/variable_fps.go @@ -41,9 +41,9 @@ type VariableFps struct { } // NewVariableFps returns a pointer to a new VariableFps filter. -func NewVariableFps(dst io.WriteCloser, fps float64) *VariableFps { - frames := uint(25 / fps) - mf := NewMOGFilter(dst, 25, 20, 500, 3, true) +func NewVariableFps(dst io.WriteCloser, minFPS float64, debug bool) *VariableFps { + frames := uint(25 / minFPS) + mf := NewMOGFilter(dst, 25, 20, 500, 3, debug) return &VariableFps{mf, dst, frames, 0} } @@ -52,9 +52,9 @@ func NewVariableFps(dst io.WriteCloser, fps float64) *VariableFps { // at a reduced frame rate, except when motion is detected, then all frames // with motion are sent. func (v *VariableFps) Write(f []byte) (int, error) { - v.count++ - if v.count > v.frames { - v.count = 0 + v.count = (v.count + 1) % v.frames + + if v.count == 0 { return v.dst.Write(f) } diff --git a/revid/revid.go b/revid/revid.go index 8c221738..74bbe65a 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -334,7 +334,7 @@ func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate float64) (io. case config.FilterMOG: r.filter = filter.NewMOGFilter(r.encoders, 25, 20, 500, 3, true) case config.FilterVariableFPS: - r.filter = filter.NewVariableFps(r.encoders, 1.0) + r.filter = filter.NewVariableFps(r.encoders, 1.0, true) default: panic("Undefined Filter") } From 62af00ff4f6d6cbf54f78c5d91a51f4cf538548e Mon Sep 17 00:00:00 2001 From: Scott Date: Tue, 31 Dec 2019 10:54:13 +1030 Subject: [PATCH 3/3] PR changes #1 --- filter/{variable_fps.go => vfps.go} | 29 ++++++++++++++--------------- revid/revid.go | 2 +- 2 files changed, 15 insertions(+), 16 deletions(-) rename filter/{variable_fps.go => vfps.go} (68%) diff --git a/filter/variable_fps.go b/filter/vfps.go similarity index 68% rename from filter/variable_fps.go rename to filter/vfps.go index 606b3656..93b6f543 100644 --- a/filter/variable_fps.go +++ b/filter/vfps.go @@ -8,7 +8,7 @@ AUTHORS Scott Barnard LICENSE - variable_fps.go is Copyright (C) 2019 the Australian Ocean Lab (AusOcean) + vfps.go is Copyright (C) 2019 the Australian Ocean Lab (AusOcean) It is free software: you can redistribute it and/or modify them under the terms of the GNU General Public License as published by the @@ -30,39 +30,38 @@ import ( "io" ) -// VariableFps is a filter that has a variable frame rate. When motion is +// VariableFPSFilter is a filter that has a variable frame rate. When motion is // detected, the filter sends all frames and when it is not, the filter // sends frames at a reduced framerate. -type VariableFps struct { - motionFilter Filter - dst io.WriteCloser - frames uint - count uint +type VariableFPSFilter struct { + filter Filter + dst io.WriteCloser + frames uint + count uint } -// NewVariableFps returns a pointer to a new VariableFps filter. -func NewVariableFps(dst io.WriteCloser, minFPS float64, debug bool) *VariableFps { +// NewVariableFPSFilter returns a pointer to a new VariableFPSFilter struct. +func NewVariableFPSFilter(dst io.WriteCloser, minFPS float64, filter Filter) *VariableFPSFilter { frames := uint(25 / minFPS) - mf := NewMOGFilter(dst, 25, 20, 500, 3, debug) - return &VariableFps{mf, dst, frames, 0} + return &VariableFPSFilter{filter, dst, frames, 0} } // Implements io.Writer. // Write applies the motion filter to the video stream. Frames are sent // at a reduced frame rate, except when motion is detected, then all frames // with motion are sent. -func (v *VariableFps) Write(f []byte) (int, error) { +func (v *VariableFPSFilter) Write(f []byte) (int, error) { v.count = (v.count + 1) % v.frames if v.count == 0 { return v.dst.Write(f) } - return v.motionFilter.Write(f) + return v.filter.Write(f) } // Implements io.Closer. // Close calls the motion filter's Close method. -func (v *VariableFps) Close() error { - return v.motionFilter.Close() +func (v *VariableFPSFilter) Close() error { + return v.filter.Close() } diff --git a/revid/revid.go b/revid/revid.go index 74bbe65a..073c4348 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -334,7 +334,7 @@ func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate float64) (io. case config.FilterMOG: r.filter = filter.NewMOGFilter(r.encoders, 25, 20, 500, 3, true) case config.FilterVariableFPS: - r.filter = filter.NewVariableFps(r.encoders, 1.0, true) + r.filter = filter.NewVariableFPSFilter(r.encoders, 1.0, filter.NewMOGFilter(r.encoders, 25, 20, 500, 3, true)) default: panic("Undefined Filter") }