Initial implementation

This commit is contained in:
Scott 2019-12-27 16:06:30 +10:30
parent c2df8a8fc1
commit 15efc8331d
2 changed files with 38 additions and 24 deletions

View File

@ -263,10 +263,10 @@ type Config struct {
Width uint // Width defines the input video width Raspivid input. Width uint // Width defines the input video width Raspivid input.
Bitrate uint // Bitrate specifies the bitrate for constant bitrate in kbps. Bitrate uint // Bitrate specifies the bitrate for constant bitrate in kbps.
HorizontalFlip bool // HorizontalFlip flips video horizontally for Raspivid input. HorizontalFlip bool // HorizontalFlip flips video horizontally for Raspivid input.
VerticalFlip bool // VerticalFlip flips video vertically for Raspivid input. VerticalFlip bool // VerticalFlip flips video vertically for Raspivid input.
Filter int // Defines the method of filtering to be used in between lexing and encoding. Filters []int // Defines the methods of filtering to be used in between lexing and encoding.
PSITime int // Sets the time between a packet being sent PSITime int // Sets the time between a packet being sent
// RTMP ring buffer parameters. // RTMP ring buffer parameters.
RTMPRBSize int // The number of elements in the RTMP sender ringbuffer. RTMPRBSize int // The number of elements in the RTMP sender ringbuffer.

View File

@ -129,8 +129,8 @@ type Revid struct {
// lexTo, encoder and packer handle transcoding the input stream. // lexTo, encoder and packer handle transcoding the input stream.
lexTo func(dest io.Writer, src io.Reader, delay time.Duration) error lexTo func(dest io.Writer, src io.Reader, delay time.Duration) error
// filter will hold the filter interface that will write to the chosen filter from the lexer. // filters will hold the filter interface that will write to the chosen filter from the lexer.
filter filter.Filter filters []filter.Filter
// encoders will hold the multiWriteCloser that writes to encoders from the filter. // encoders will hold the multiWriteCloser that writes to encoders from the filter.
encoders io.WriteCloser encoders io.WriteCloser
@ -346,18 +346,28 @@ func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate float64) (io.
r.encoders = multiWriter(encoders...) r.encoders = multiWriter(encoders...)
switch r.cfg.Filter { l := len(r.cfg.Filters)
case config.FilterNoOp: r.filters = []filter.Filter{filter.NewNoOp(r.encoders)}
r.filter = filter.NewNoOp(r.encoders) if l != 0 {
case config.FilterMOG: r.filters = make([]filter.Filter, l)
r.filter = filter.NewMOGFilter(r.encoders, mogMinArea, mogThreshold, mogHistory, r.cfg.ShowWindows) dst := r.encoders
case config.FilterVariableFPS:
r.filter = filter.NewVariableFPSFilter(r.encoders, minFPS, filter.NewMOGFilter(r.encoders, mogMinArea, mogThreshold, mogHistory, r.cfg.ShowWindows)) for i := l - 1; i >= 0; i-- {
case config.FilterKNN: switch r.cfg.Filters[i] {
r.filter = filter.NewKNNFilter(r.encoders, knnMinArea, knnThreshold, knnHistory, knnKernel, r.cfg.ShowWindows) case config.FilterNoOp:
r.filters[i] = filter.NewNoOp(dst)
case config.FilterMOG:
r.filters[i] = filter.NewMOGFilter(dst, mogMinArea, mogThreshold, mogHistory, r.cfg.ShowWindows)
case config.FilterVariableFPS:
r.filters[i] = filter.NewVariableFPSFilter(dst, minFPS, filter.NewMOGFilter(dst, mogMinArea, mogThreshold, mogHistory, r.cfg.ShowWindows))
case config.FilterKNN:
r.filters[i] = filter.NewKNNFilter(dst, knnMinArea, knnThreshold, knnHistory, knnKernel, r.cfg.ShowWindows)
default:
panic("Undefined Filter")
}
dst = r.filters[i]
}
default:
panic("Undefined Filter")
} }
switch r.cfg.Input { switch r.cfg.Input {
@ -474,7 +484,7 @@ func (r *Revid) Stop() {
r.cfg.Logger.Log(logger.Error, pkg+"failed to close pipeline", "error", err.Error()) r.cfg.Logger.Log(logger.Error, pkg+"failed to close pipeline", "error", err.Error())
} }
err = r.filter.Close() //err = r.filter.Close()
if err != nil { if err != nil {
r.cfg.Logger.Log(logger.Error, pkg+"failed to close pipeline", "error", err.Error()) r.cfg.Logger.Log(logger.Error, pkg+"failed to close pipeline", "error", err.Error())
} }
@ -667,13 +677,17 @@ func (r *Revid) Update(vars map[string]string) error {
default: default:
r.cfg.Logger.Log(logger.Warning, pkg+"invalid VerticalFlip param", "value", value) r.cfg.Logger.Log(logger.Warning, pkg+"invalid VerticalFlip param", "value", value)
} }
case "Filter": case "Filters":
filters := strings.Split(value, ",")
m := map[string]int{"NoOp": config.FilterNoOp, "MOG": config.FilterMOG, "VariableFPS": config.FilterVariableFPS, "KNN": config.FilterKNN} m := map[string]int{"NoOp": config.FilterNoOp, "MOG": config.FilterMOG, "VariableFPS": config.FilterVariableFPS, "KNN": config.FilterKNN}
v, ok := m[value] r.cfg.Filters = make([]int, len(filters))
if !ok { for i, filter := range filters {
r.cfg.Logger.Log(logger.Warning, pkg+"invalid FilterMethod param", "value", value) v, ok := m[filter]
if !ok {
r.cfg.Logger.Log(logger.Warning, pkg+"invalid Filters param", "value", value)
}
r.cfg.Filters[i] = v
} }
r.cfg.Filter = v
case "PSITime": case "PSITime":
v, err := strconv.Atoi(value) v, err := strconv.Atoi(value)
if err != nil || v < 0 { if err != nil || v < 0 {
@ -792,7 +806,7 @@ func (r *Revid) Update(vars map[string]string) error {
// processFrom is run as a routine to read from a input data source, lex and // processFrom is run as a routine to read from a input data source, lex and
// then send individual access units to revid's encoders. // then send individual access units to revid's encoders.
func (r *Revid) processFrom(read io.Reader, delay time.Duration) { func (r *Revid) processFrom(read io.Reader, delay time.Duration) {
r.err <- r.lexTo(r.filter, read, delay) r.err <- r.lexTo(r.filters[0], read, delay)
r.cfg.Logger.Log(logger.Info, pkg+"finished lexing") r.cfg.Logger.Log(logger.Info, pkg+"finished lexing")
r.wg.Done() r.wg.Done()
} }