Merged in parameter-implementations (pull request #376)

revid/config/parameter: wrote code for the generation of Parameter interface implementations and commit resulting code

Using a template, code has been created to generate repetitive implementations of an interface name Parameter. The code iterates through a list of params and creates implementations for each one.

Approved-by: Scott Barnard <scott@ausocean.org>
This commit is contained in:
Saxon Milton 2020-02-12 00:27:08 +00:00
parent 2ee8ded809
commit 81aa35b586
2 changed files with 1206 additions and 0 deletions

View File

@ -0,0 +1,303 @@
// +build ignore
/*
DESCRIPTION
generate_parameters.go uses a template to generate implementations for the
Parameter interface.
LICENSE
Copyright (C) 2020 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
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
*/
package main
import (
"bytes"
"fmt"
"go/format"
"math"
"os"
"strings"
"text/template"
)
// Filename to house Parameter interface implementations.
const fileName = "parameters.go"
// Param holds characteristics for describing Parameter interface implementations.
type Param struct {
// N is the name of the struct implementing the Parameter interface.
N string
// R is the name of the receiver for the Type and Set methods. This is set to
// the lowercase of the first letter of the Parameter implementation name, N.
R string
// BT is the base type of a Parameter implementation. For example, for a
// Parameter implementation named Bitrate, i.e. type Bitrate uint, the base
// type is uint.
BT string
// E are the enums of a type i.e. if there is a list of identifiers we wish
// to recocgnise, they are specified here. For example, a Parameter implementation
// named Output may take on a value of HTTP, RTMP, RTP or File, so E is set to
// []string{"HTTP","RTMP","RTP","File"} and a const list of type Output will be
// generated as a result:
// const (
// OutputHTTP Output = iota
// OutputRTMP
// OutputRTP
// OutputFile
// )
E []string
// M, if defined, indicates a "multiple option type", which is to mean a slice
// of another type that is defined. For example, if the base type, BT, is set
// to a slice of a type "[]Output" (where Output is also defined in the params
// list), then M would be set to "Output". The E field must be manually set to
// be consistent with the Enums defined for the Output type.
M string
// If we wish an int, uint, or float64 value to be constrained to a particular
// range then Min and Max are both set to indicate the inclusive Min and Max
// possible values for a type. This will result in the generation of a range
// check in the implementation's Set method.
Min, Max int
}
// NB: Alphabetical order.
var params = []Param{
{N: "AutoWhiteBalance", BT: "uint8", E: []string{"Off", "Auto", "Sun", "Cloud", "Shade", "Tungsten", "Fluorescent", "Incandescent", "Flash", "Horizon"}},
{N: "BitDepth", BT: "uint"}, // TODO(Trek): bounds.
{N: "Bitrate", BT: "uint", Min: 1000, Max: 10000000},
{N: "Brightness", BT: "uint", Min: 0, Max: 100},
{N: "BurstPeriod", BT: "time.Duration"},
{N: "CBR", BT: "bool"},
{N: "CameraChan", BT: "uint8", E: []string{"Channel1", "Channel2"}},
{N: "CameraIP", BT: "string"},
{N: "Channels", BT: "uint"}, // TODO(Trek): bounds.
{N: "ClipDuration", BT: "time.Duration"},
{N: "Codec", BT: "uint8", E: []string{"H264", "H265", "MJPEG", "PCM", "ADPCM"}},
{N: "Exposure", BT: "uint8", E: []string{"Auto", "Night", "NightPreview", "BackLight", "SpotLight", "Sports", "Snow", "Beach", "VeryLong", "FixedFPS", "AntiShake", "Fireworks"}},
{N: "FileFPS", BT: "uint", Min: 1, Max: 30},
{N: "Filter", BT: "uint8", E: []string{"NoOp", "MOG", "VariableFPS", "KNN", "Difference", "Basic"}},
{N: "FrameRate", BT: "uint", Min: 1, Max: 30},
{N: "HTTPAddress", BT: "string"},
{N: "Height", BT: "uint", Min: 360, Max: 1080},
{N: "HorizontalFlip", BT: "bool"},
{N: "Input", BT: "uint8", E: []string{"File", "Raspivid", "Webcam", "RTSP"}},
{N: "InputPath", BT: "string"},
{N: "Level", BT: "uint8", E: []string{"Debug", "Info", "Warning", "Error", "Fatal"}},
{N: "MinFPS", BT: "uint", Min: 1, Max: 30},
{N: "MinFrames", BT: "uint", Min: 0, Max: 1000},
{N: "Mode", BT: "uint8", E: []string{"Normal", "Paused", "Burst", "Loop"}},
{N: "MotionDownscaling", BT: "uint"}, // TODO(Scott): define bounds.
{N: "MotionHistory", BT: "uint"}, // TODO(Scott/Ella): define bounds.
{N: "MotionInterval", BT: "uint", Min: 0, Max: 30},
{N: "MotionKernel", BT: "uint"}, // TODO(Scott/Ella): define bounds.
{N: "MotionMinArea", BT: "float64"}, // TODO(Scott/Ella): define bounds.
{N: "MotionPixels", BT: "uint"}, // TODO(Scott/Ella): define bounds.
{N: "MotionThreshold", BT: "float64"}, // TODO(Scott/Ella): define bounds.
{N: "Output", BT: "uint8", E: []string{"HTTP", "RTMP", "RTP", "File"}},
{N: "OutputPath", BT: "string"},
{N: "Outputs", BT: "[]Output", M: "Output", E: []string{"HTTP", "RTMP", "RTP", "File"}},
{N: "PSITime", BT: "time.Duration"},
{N: "Quantization", BT: "uint"},
{N: "RBCapacity", BT: "uint", Min: 1000000, Max: 100000000},
{N: "RBMaxElements", BT: "uint", Min: 0, Max: math.MaxUint32},
{N: "RBWriteTimeout", BT: "time.Duration"},
{N: "RTMPURL", BT: "string"},
{N: "RTPAddress", BT: "string"},
{N: "RecPeriod", BT: "float64"}, // TODO(Trek): bounds.
{N: "Rotation", BT: "uint", Min: 0, Max: 359},
{N: "SampleRate", BT: "uint"}, // TODO(Trek): bounds.
{N: "Saturation", BT: "int", Min: -50, Max: 50},
{N: "ShowWindows", BT: "bool"},
{N: "VBRBitrate", BT: "uint", Min: 1, Max: 30},
{N: "VBRQuality", BT: "uint8", E: []string{"Standard", "Fair", "Good", "Great", "Excellent"}},
{N: "VerticalFlip", BT: "bool"},
{N: "Width", BT: "uint", Min: 640, Max: 1920},
{N: "WriteRate", BT: "float64"},
}
const fileHeader = `
/*
DESCRIPTION
Code generated by "go run generate_parameters.go; DO NOT EDIT.
parameters.go contains implementations of the Parameter interface for all
parameter types required by the configuration struct.
AUTHORS
Saxon Nelson-Milton <saxon@ausocean.org>
LICENSE
Copyright (C) 2020 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
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
*/
package parameter
import (
"fmt"
"strconv"
"time"
"strings"
)
type Parameter interface {
Type() string
Set(val string) error
}
`
const paramTemplate = `
type {{.N}} {{.BT}}
{{if and .E (not .M)}}
const (
{{$name := .N}}
{{- range $i, $e := .E}}{{- if eq $i 0}}{{$name}}{{$e}} {{$name}} = iota{{else}}{{$name}}{{$e}}{{end}}
{{end -}}
)
{{end -}}
{{- if .E}}
func ({{.R}} *{{.N}}) Type() string { return "enum:{{range $i, $e := .E}}{{if eq $i 0}}{{$e}}{{else}},{{$e}}{{end}}{{end}}"}
{{else}}
func ({{.R}} *{{.N}}) Type() string { return "{{.BT}}"}
{{end -}}
func ({{.R}} *{{.N}}) Set(val string) error {
{{- if eq .BT "string"}}
*{{.R}} = {{.N}}(val)
{{else if eq .BT "bool"}}
switch val {
case "true":
*{{.R}} = true
case "false":
*{{.R}} = false
default:
return fmt.Errorf("not boolean value: %s",val)
}
{{else if eq .BT "int"}}
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w",err)
}
*{{.R}} = {{.N}}(_v)
{{else if eq .BT "uint"}}
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w",err)
}
*{{.R}} = {{.N}}(_v)
{{else if eq .BT "float64"}}
_v, err := strconv.ParseFloat(val,64)
if err != nil {
return fmt.Errorf("could not convert set string to float: %w",err)
}
*{{.R}} = {{.N}}(_v)
{{else if eq .BT "time.Duration"}}
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w",err)
}
*{{.R}} = {{.N}}(time.Duration(_v)*time.Second)
{{else if .M}}
vals := strings.Split(val, ",")
*{{.R}} = make({{.BT}}, len(vals))
for i, v := range vals {
switch v {
{{- $receiver := .R}}
{{- $m := .M}}
{{range .E}}case "{{ . }}":
(*{{$receiver}})[i] = {{$m}}{{ . }}
{{end -}}
default:
return fmt.Errorf("unrecognised {{.N}}: %s",val)
}
}
{{else}}
switch val {
{{- $receiver := .R}}
{{- $name := .N}}
{{range .E}}case "{{ . }}":
*{{$receiver}} = {{$name}}{{ . }}
{{end -}}
default:
return fmt.Errorf("unrecognised {{.N}}: %s",val)
}
{{end -}}
{{- if and (or (or (eq .BT "int") (eq .BT "uint")) (eq .BT "float64")) (ne .Min .Max)}}
if *{{.R}} < {{.Min}} || *{{.R}} > {{.Max}} {
return fmt.Errorf("invalid value %v",*{{.R}})
}
{{end -}}
return nil
}
`
func main() {
f, err := os.Create(fileName)
if err != nil {
panic(fmt.Sprintf("error creating %s file: %v", fileName, err))
}
defer f.Close()
var buf bytes.Buffer
_, err = buf.Write([]byte(fileHeader))
if err != nil {
panic(fmt.Sprintf("error writing header: %v", err))
}
param := template.Must(template.New("param").Parse(paramTemplate))
for _, p := range params {
// Use first letter of parameter name as receiver.
p.R = strings.ToLower(p.N[:1])
err = param.Execute(&buf, p)
if err != nil {
panic(fmt.Sprintf("error executing template: %v", err))
}
}
b, err := format.Source(buf.Bytes())
if err != nil {
f.Write(buf.Bytes()) // Useful to debug bad format.
panic(fmt.Sprintf("error formatting: %v", err))
}
_, err = f.Write(b)
if err != nil {
panic(fmt.Sprintf("error writing %s file: %v", fileName, err))
}
}

View File

@ -0,0 +1,903 @@
/*
DESCRIPTION
Code generated by "go build generate_parameters.go; ./generate_parameters; DO NOT EDIT.
parameters.go contains implementations of the Parameter interface for all
parameter types required by the configuration struct.
AUTHORS
Saxon Nelson-Milton <saxon@ausocean.org>
LICENSE
Copyright (C) 2020 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
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
*/
package parameter
import (
"fmt"
"strconv"
"strings"
"time"
)
type Parameter interface {
Type() string
Set(val string) error
}
type AutoWhiteBalance uint8
const (
AutoWhiteBalanceOff AutoWhiteBalance = iota
AutoWhiteBalanceAuto
AutoWhiteBalanceSun
AutoWhiteBalanceCloud
AutoWhiteBalanceShade
AutoWhiteBalanceTungsten
AutoWhiteBalanceFluorescent
AutoWhiteBalanceIncandescent
AutoWhiteBalanceFlash
AutoWhiteBalanceHorizon
)
func (a *AutoWhiteBalance) Type() string {
return "enum:Off,Auto,Sun,Cloud,Shade,Tungsten,Fluorescent,Incandescent,Flash,Horizon"
}
func (a *AutoWhiteBalance) Set(val string) error {
switch val {
case "Off":
*a = AutoWhiteBalanceOff
case "Auto":
*a = AutoWhiteBalanceAuto
case "Sun":
*a = AutoWhiteBalanceSun
case "Cloud":
*a = AutoWhiteBalanceCloud
case "Shade":
*a = AutoWhiteBalanceShade
case "Tungsten":
*a = AutoWhiteBalanceTungsten
case "Fluorescent":
*a = AutoWhiteBalanceFluorescent
case "Incandescent":
*a = AutoWhiteBalanceIncandescent
case "Flash":
*a = AutoWhiteBalanceFlash
case "Horizon":
*a = AutoWhiteBalanceHorizon
default:
return fmt.Errorf("unrecognised AutoWhiteBalance: %s", val)
}
return nil
}
type BitDepth uint
func (b *BitDepth) Type() string { return "uint" }
func (b *BitDepth) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*b = BitDepth(_v)
return nil
}
type Bitrate uint
func (b *Bitrate) Type() string { return "uint" }
func (b *Bitrate) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*b = Bitrate(_v)
if *b < 1000 || *b > 10000000 {
return fmt.Errorf("invalid value %v", *b)
}
return nil
}
type Brightness uint
func (b *Brightness) Type() string { return "uint" }
func (b *Brightness) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*b = Brightness(_v)
if *b < 0 || *b > 100 {
return fmt.Errorf("invalid value %v", *b)
}
return nil
}
type BurstPeriod time.Duration
func (b *BurstPeriod) Type() string { return "time.Duration" }
func (b *BurstPeriod) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*b = BurstPeriod(time.Duration(_v) * time.Second)
return nil
}
type CBR bool
func (c *CBR) Type() string { return "bool" }
func (c *CBR) Set(val string) error {
switch val {
case "true":
*c = true
case "false":
*c = false
default:
return fmt.Errorf("not boolean value: %s", val)
}
return nil
}
type CameraChan uint8
const (
CameraChanChannel1 CameraChan = iota
CameraChanChannel2
)
func (c *CameraChan) Type() string { return "enum:Channel1,Channel2" }
func (c *CameraChan) Set(val string) error {
switch val {
case "Channel1":
*c = CameraChanChannel1
case "Channel2":
*c = CameraChanChannel2
default:
return fmt.Errorf("unrecognised CameraChan: %s", val)
}
return nil
}
type CameraIP string
func (c *CameraIP) Type() string { return "string" }
func (c *CameraIP) Set(val string) error {
*c = CameraIP(val)
return nil
}
type Channels uint
func (c *Channels) Type() string { return "uint" }
func (c *Channels) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*c = Channels(_v)
return nil
}
type ClipDuration time.Duration
func (c *ClipDuration) Type() string { return "time.Duration" }
func (c *ClipDuration) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*c = ClipDuration(time.Duration(_v) * time.Second)
return nil
}
type Codec uint8
const (
CodecH264 Codec = iota
CodecH265
CodecMJPEG
CodecPCM
CodecADPCM
)
func (c *Codec) Type() string { return "enum:H264,H265,MJPEG,PCM,ADPCM" }
func (c *Codec) Set(val string) error {
switch val {
case "H264":
*c = CodecH264
case "H265":
*c = CodecH265
case "MJPEG":
*c = CodecMJPEG
case "PCM":
*c = CodecPCM
case "ADPCM":
*c = CodecADPCM
default:
return fmt.Errorf("unrecognised Codec: %s", val)
}
return nil
}
type Exposure uint8
const (
ExposureAuto Exposure = iota
ExposureNight
ExposureNightPreview
ExposureBackLight
ExposureSpotLight
ExposureSports
ExposureSnow
ExposureBeach
ExposureVeryLong
ExposureFixedFPS
ExposureAntiShake
ExposureFireworks
)
func (e *Exposure) Type() string {
return "enum:Auto,Night,NightPreview,BackLight,SpotLight,Sports,Snow,Beach,VeryLong,FixedFPS,AntiShake,Fireworks"
}
func (e *Exposure) Set(val string) error {
switch val {
case "Auto":
*e = ExposureAuto
case "Night":
*e = ExposureNight
case "NightPreview":
*e = ExposureNightPreview
case "BackLight":
*e = ExposureBackLight
case "SpotLight":
*e = ExposureSpotLight
case "Sports":
*e = ExposureSports
case "Snow":
*e = ExposureSnow
case "Beach":
*e = ExposureBeach
case "VeryLong":
*e = ExposureVeryLong
case "FixedFPS":
*e = ExposureFixedFPS
case "AntiShake":
*e = ExposureAntiShake
case "Fireworks":
*e = ExposureFireworks
default:
return fmt.Errorf("unrecognised Exposure: %s", val)
}
return nil
}
type FileFPS uint
func (f *FileFPS) Type() string { return "uint" }
func (f *FileFPS) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*f = FileFPS(_v)
if *f < 1 || *f > 30 {
return fmt.Errorf("invalid value %v", *f)
}
return nil
}
type Filter uint8
const (
FilterNoOp Filter = iota
FilterMOG
FilterVariableFPS
FilterKNN
FilterDifference
FilterBasic
)
func (f *Filter) Type() string { return "enum:NoOp,MOG,VariableFPS,KNN,Difference,Basic" }
func (f *Filter) Set(val string) error {
switch val {
case "NoOp":
*f = FilterNoOp
case "MOG":
*f = FilterMOG
case "VariableFPS":
*f = FilterVariableFPS
case "KNN":
*f = FilterKNN
case "Difference":
*f = FilterDifference
case "Basic":
*f = FilterBasic
default:
return fmt.Errorf("unrecognised Filter: %s", val)
}
return nil
}
type FrameRate uint
func (f *FrameRate) Type() string { return "uint" }
func (f *FrameRate) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*f = FrameRate(_v)
if *f < 1 || *f > 30 {
return fmt.Errorf("invalid value %v", *f)
}
return nil
}
type HTTPAddress string
func (h *HTTPAddress) Type() string { return "string" }
func (h *HTTPAddress) Set(val string) error {
*h = HTTPAddress(val)
return nil
}
type Height uint
func (h *Height) Type() string { return "uint" }
func (h *Height) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*h = Height(_v)
if *h < 360 || *h > 1080 {
return fmt.Errorf("invalid value %v", *h)
}
return nil
}
type HorizontalFlip bool
func (h *HorizontalFlip) Type() string { return "bool" }
func (h *HorizontalFlip) Set(val string) error {
switch val {
case "true":
*h = true
case "false":
*h = false
default:
return fmt.Errorf("not boolean value: %s", val)
}
return nil
}
type Input uint8
const (
InputFile Input = iota
InputRaspivid
InputWebcam
InputRTSP
)
func (i *Input) Type() string { return "enum:File,Raspivid,Webcam,RTSP" }
func (i *Input) Set(val string) error {
switch val {
case "File":
*i = InputFile
case "Raspivid":
*i = InputRaspivid
case "Webcam":
*i = InputWebcam
case "RTSP":
*i = InputRTSP
default:
return fmt.Errorf("unrecognised Input: %s", val)
}
return nil
}
type InputPath string
func (i *InputPath) Type() string { return "string" }
func (i *InputPath) Set(val string) error {
*i = InputPath(val)
return nil
}
type Level uint8
const (
LevelDebug Level = iota
LevelInfo
LevelWarning
LevelError
LevelFatal
)
func (l *Level) Type() string { return "enum:Debug,Info,Warning,Error,Fatal" }
func (l *Level) Set(val string) error {
switch val {
case "Debug":
*l = LevelDebug
case "Info":
*l = LevelInfo
case "Warning":
*l = LevelWarning
case "Error":
*l = LevelError
case "Fatal":
*l = LevelFatal
default:
return fmt.Errorf("unrecognised Level: %s", val)
}
return nil
}
type MinFPS uint
func (m *MinFPS) Type() string { return "uint" }
func (m *MinFPS) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*m = MinFPS(_v)
if *m < 1 || *m > 30 {
return fmt.Errorf("invalid value %v", *m)
}
return nil
}
type MinFrames uint
func (m *MinFrames) Type() string { return "uint" }
func (m *MinFrames) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*m = MinFrames(_v)
if *m < 0 || *m > 1000 {
return fmt.Errorf("invalid value %v", *m)
}
return nil
}
type Mode uint8
const (
ModeNormal Mode = iota
ModePaused
ModeBurst
ModeLoop
)
func (m *Mode) Type() string { return "enum:Normal,Paused,Burst,Loop" }
func (m *Mode) Set(val string) error {
switch val {
case "Normal":
*m = ModeNormal
case "Paused":
*m = ModePaused
case "Burst":
*m = ModeBurst
case "Loop":
*m = ModeLoop
default:
return fmt.Errorf("unrecognised Mode: %s", val)
}
return nil
}
type MotionDownscaling uint
func (m *MotionDownscaling) Type() string { return "uint" }
func (m *MotionDownscaling) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*m = MotionDownscaling(_v)
return nil
}
type MotionHistory uint
func (m *MotionHistory) Type() string { return "uint" }
func (m *MotionHistory) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*m = MotionHistory(_v)
return nil
}
type MotionInterval uint
func (m *MotionInterval) Type() string { return "uint" }
func (m *MotionInterval) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*m = MotionInterval(_v)
if *m < 0 || *m > 30 {
return fmt.Errorf("invalid value %v", *m)
}
return nil
}
type MotionKernel uint
func (m *MotionKernel) Type() string { return "uint" }
func (m *MotionKernel) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*m = MotionKernel(_v)
return nil
}
type MotionMinArea float64
func (m *MotionMinArea) Type() string { return "float64" }
func (m *MotionMinArea) Set(val string) error {
_v, err := strconv.ParseFloat(val, 64)
if err != nil {
return fmt.Errorf("could not convert set string to float: %w", err)
}
*m = MotionMinArea(_v)
return nil
}
type MotionPixels uint
func (m *MotionPixels) Type() string { return "uint" }
func (m *MotionPixels) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*m = MotionPixels(_v)
return nil
}
type MotionThreshold float64
func (m *MotionThreshold) Type() string { return "float64" }
func (m *MotionThreshold) Set(val string) error {
_v, err := strconv.ParseFloat(val, 64)
if err != nil {
return fmt.Errorf("could not convert set string to float: %w", err)
}
*m = MotionThreshold(_v)
return nil
}
type Output uint8
const (
OutputHTTP Output = iota
OutputRTMP
OutputRTP
OutputFile
)
func (o *Output) Type() string { return "enum:HTTP,RTMP,RTP,File" }
func (o *Output) Set(val string) error {
switch val {
case "HTTP":
*o = OutputHTTP
case "RTMP":
*o = OutputRTMP
case "RTP":
*o = OutputRTP
case "File":
*o = OutputFile
default:
return fmt.Errorf("unrecognised Output: %s", val)
}
return nil
}
type OutputPath string
func (o *OutputPath) Type() string { return "string" }
func (o *OutputPath) Set(val string) error {
*o = OutputPath(val)
return nil
}
type Outputs []Output
func (o *Outputs) Type() string { return "enum:HTTP,RTMP,RTP,File" }
func (o *Outputs) Set(val string) error {
vals := strings.Split(val, ",")
*o = make([]Output, len(vals))
for i, v := range vals {
switch v {
case "HTTP":
(*o)[i] = OutputHTTP
case "RTMP":
(*o)[i] = OutputRTMP
case "RTP":
(*o)[i] = OutputRTP
case "File":
(*o)[i] = OutputFile
default:
return fmt.Errorf("unrecognised Outputs: %s", val)
}
}
return nil
}
type PSITime time.Duration
func (p *PSITime) Type() string { return "time.Duration" }
func (p *PSITime) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*p = PSITime(time.Duration(_v) * time.Second)
return nil
}
type Quantization uint
func (q *Quantization) Type() string { return "uint" }
func (q *Quantization) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*q = Quantization(_v)
return nil
}
type RBCapacity uint
func (r *RBCapacity) Type() string { return "uint" }
func (r *RBCapacity) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*r = RBCapacity(_v)
if *r < 1000000 || *r > 100000000 {
return fmt.Errorf("invalid value %v", *r)
}
return nil
}
type RBMaxElements uint
func (r *RBMaxElements) Type() string { return "uint" }
func (r *RBMaxElements) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*r = RBMaxElements(_v)
if *r < 0 || *r > 4294967295 {
return fmt.Errorf("invalid value %v", *r)
}
return nil
}
type RBWriteTimeout time.Duration
func (r *RBWriteTimeout) Type() string { return "time.Duration" }
func (r *RBWriteTimeout) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*r = RBWriteTimeout(time.Duration(_v) * time.Second)
return nil
}
type RTMPURL string
func (r *RTMPURL) Type() string { return "string" }
func (r *RTMPURL) Set(val string) error {
*r = RTMPURL(val)
return nil
}
type RTPAddress string
func (r *RTPAddress) Type() string { return "string" }
func (r *RTPAddress) Set(val string) error {
*r = RTPAddress(val)
return nil
}
type RecPeriod float64
func (r *RecPeriod) Type() string { return "float64" }
func (r *RecPeriod) Set(val string) error {
_v, err := strconv.ParseFloat(val, 64)
if err != nil {
return fmt.Errorf("could not convert set string to float: %w", err)
}
*r = RecPeriod(_v)
return nil
}
type Rotation uint
func (r *Rotation) Type() string { return "uint" }
func (r *Rotation) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*r = Rotation(_v)
if *r < 0 || *r > 359 {
return fmt.Errorf("invalid value %v", *r)
}
return nil
}
type SampleRate uint
func (s *SampleRate) Type() string { return "uint" }
func (s *SampleRate) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*s = SampleRate(_v)
return nil
}
type Saturation int
func (s *Saturation) Type() string { return "int" }
func (s *Saturation) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*s = Saturation(_v)
if *s < -50 || *s > 50 {
return fmt.Errorf("invalid value %v", *s)
}
return nil
}
type ShowWindows bool
func (s *ShowWindows) Type() string { return "bool" }
func (s *ShowWindows) Set(val string) error {
switch val {
case "true":
*s = true
case "false":
*s = false
default:
return fmt.Errorf("not boolean value: %s", val)
}
return nil
}
type VBRBitrate uint
func (v *VBRBitrate) Type() string { return "uint" }
func (v *VBRBitrate) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*v = VBRBitrate(_v)
if *v < 1 || *v > 30 {
return fmt.Errorf("invalid value %v", *v)
}
return nil
}
type VBRQuality uint8
const (
VBRQualityStandard VBRQuality = iota
VBRQualityFair
VBRQualityGood
VBRQualityGreat
VBRQualityExcellent
)
func (v *VBRQuality) Type() string { return "enum:Standard,Fair,Good,Great,Excellent" }
func (v *VBRQuality) Set(val string) error {
switch val {
case "Standard":
*v = VBRQualityStandard
case "Fair":
*v = VBRQualityFair
case "Good":
*v = VBRQualityGood
case "Great":
*v = VBRQualityGreat
case "Excellent":
*v = VBRQualityExcellent
default:
return fmt.Errorf("unrecognised VBRQuality: %s", val)
}
return nil
}
type VerticalFlip bool
func (v *VerticalFlip) Type() string { return "bool" }
func (v *VerticalFlip) Set(val string) error {
switch val {
case "true":
*v = true
case "false":
*v = false
default:
return fmt.Errorf("not boolean value: %s", val)
}
return nil
}
type Width uint
func (w *Width) Type() string { return "uint" }
func (w *Width) Set(val string) error {
_v, err := strconv.Atoi(val)
if err != nil {
return fmt.Errorf("could not convert set string to int: %w", err)
}
*w = Width(_v)
if *w < 640 || *w > 1920 {
return fmt.Errorf("invalid value %v", *w)
}
return nil
}
type WriteRate float64
func (w *WriteRate) Type() string { return "float64" }
func (w *WriteRate) Set(val string) error {
_v, err := strconv.ParseFloat(val, 64)
if err != nil {
return fmt.Errorf("could not convert set string to float: %w", err)
}
*w = WriteRate(_v)
return nil
}