2020-05-19 09:02:02 +03:00
|
|
|
/*
|
|
|
|
DESCRIPTION
|
|
|
|
variables.go contains a list of structs that provide a variable Name, type in
|
|
|
|
a string format, a function for updating the variable in the Config struct
|
|
|
|
from a string, and finally, a validation function to check the validity of the
|
|
|
|
corresponding field value in the Config.
|
|
|
|
|
|
|
|
AUTHORS
|
|
|
|
Saxon A. 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 config
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"bitbucket.org/ausocean/av/codec/codecutil"
|
|
|
|
"bitbucket.org/ausocean/utils/logger"
|
|
|
|
)
|
|
|
|
|
2021-01-20 04:19:01 +03:00
|
|
|
// Config map Keys.
|
2021-01-04 06:22:57 +03:00
|
|
|
const (
|
2021-01-20 04:19:01 +03:00
|
|
|
KeyAutoWhiteBalance = "AutoWhiteBalance"
|
2021-03-30 06:36:00 +03:00
|
|
|
KeyAWBGains = "AWBGains"
|
2021-01-20 04:19:01 +03:00
|
|
|
KeyBitDepth = "BitDepth"
|
|
|
|
KeyBitrate = "Bitrate"
|
|
|
|
KeyBrightness = "Brightness"
|
|
|
|
KeyBurstPeriod = "BurstPeriod"
|
|
|
|
KeyCameraChan = "CameraChan"
|
|
|
|
KeyCameraIP = "CameraIP"
|
|
|
|
KeyCBR = "CBR"
|
|
|
|
KeyClipDuration = "ClipDuration"
|
|
|
|
KeyChannels = "Channels"
|
2021-03-30 06:36:00 +03:00
|
|
|
KeyContrast = "Contrast"
|
2021-01-20 04:19:01 +03:00
|
|
|
KeyExposure = "Exposure"
|
2021-03-30 06:36:00 +03:00
|
|
|
KeyEV = "EV"
|
2021-01-20 04:19:01 +03:00
|
|
|
KeyFileFPS = "FileFPS"
|
|
|
|
KeyFilters = "Filters"
|
|
|
|
KeyFrameRate = "FrameRate"
|
|
|
|
KeyHeight = "Height"
|
|
|
|
KeyHorizontalFlip = "HorizontalFlip"
|
|
|
|
KeyHTTPAddress = "HTTPAddress"
|
|
|
|
KeyInput = "Input"
|
|
|
|
KeyInputCodec = "InputCodec"
|
|
|
|
KeyInputPath = "InputPath"
|
2021-03-30 06:36:00 +03:00
|
|
|
KeyISO = "ISO"
|
2021-01-20 04:19:01 +03:00
|
|
|
KeyLogging = "logging"
|
|
|
|
KeyLoop = "Loop"
|
|
|
|
KeyMinFPS = "MinFPS"
|
|
|
|
KeyMinFrames = "MinFrames"
|
|
|
|
KeyMode = "mode"
|
|
|
|
KeyMotionDownscaling = "MotionDownscaling"
|
|
|
|
KeyMotionHistory = "MotionHistory"
|
|
|
|
KeyMotionInterval = "MotionInterval"
|
|
|
|
KeyMotionKernel = "MotionKernel"
|
|
|
|
KeyMotionMinArea = "MotionMinArea"
|
|
|
|
KeyMotionPadding = "MotionPadding"
|
|
|
|
KeyMotionPixels = "MotionPixels"
|
|
|
|
KeyMotionThreshold = "MotionThreshold"
|
|
|
|
KeyOutput = "Output"
|
|
|
|
KeyOutputPath = "OutputPath"
|
|
|
|
KeyOutputs = "Outputs"
|
|
|
|
KeyPSITime = "PSITime"
|
|
|
|
KeyQuantization = "Quantization"
|
|
|
|
KeyRBCapacity = "RBCapacity"
|
|
|
|
KeyRBStartElementSize = "RBStartElementSize"
|
|
|
|
KeyRBWriteTimeout = "RBWriteTimeout"
|
|
|
|
KeyRecPeriod = "RecPeriod"
|
|
|
|
KeyRotation = "Rotation"
|
|
|
|
KeyRTMPURL = "RTMPURL"
|
|
|
|
KeyRTPAddress = "RTPAddress"
|
|
|
|
KeySampleRate = "SampleRate"
|
|
|
|
KeySaturation = "Saturation"
|
2021-03-30 06:36:00 +03:00
|
|
|
KeySharpness = "Sharpness"
|
2021-01-27 06:11:29 +03:00
|
|
|
KeyJPEGQuality = "JPEGQuality"
|
2021-01-20 04:19:01 +03:00
|
|
|
KeySuppress = "Suppress"
|
|
|
|
KeyTimelapseDuration = "TimelapseDuration"
|
|
|
|
KeyTimelapseInterval = "TimelapseInterval"
|
|
|
|
KeyVBRBitrate = "VBRBitrate"
|
|
|
|
KeyVBRQuality = "VBRQuality"
|
|
|
|
KeyVerticalFlip = "VerticalFlip"
|
|
|
|
KeyWidth = "Width"
|
2021-01-04 06:22:57 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
// Config map parameter types.
|
|
|
|
const (
|
|
|
|
typeString = "string"
|
2021-01-20 04:19:01 +03:00
|
|
|
typeInt = "int"
|
2021-01-04 06:22:57 +03:00
|
|
|
typeUint = "uint"
|
|
|
|
typeBool = "bool"
|
|
|
|
typeFloat = "float"
|
|
|
|
)
|
|
|
|
|
2020-05-19 09:02:02 +03:00
|
|
|
// Default variable values.
|
|
|
|
const (
|
|
|
|
// General revid defaults.
|
2020-08-11 05:13:17 +03:00
|
|
|
defaultInput = InputRaspivid
|
|
|
|
defaultOutput = OutputHTTP
|
|
|
|
defaultInputCodec = codecutil.H264
|
|
|
|
defaultVerbosity = logger.Error
|
|
|
|
defaultRTPAddr = "localhost:6970"
|
|
|
|
defaultCameraIP = "192.168.1.50"
|
|
|
|
defaultBurstPeriod = 10 // Seconds
|
|
|
|
defaultMinFrames = 100
|
|
|
|
defaultFrameRate = 25
|
|
|
|
defaultClipDuration = 0
|
|
|
|
defaultPSITime = 2
|
|
|
|
defaultFileFPS = 0
|
2020-05-19 09:02:02 +03:00
|
|
|
|
|
|
|
// Ring buffer defaults.
|
2021-01-20 04:19:01 +03:00
|
|
|
defaultRBCapacity = 50000000 // => 50MB
|
|
|
|
defaultRBStartElementSize = 1000 // bytes
|
|
|
|
defaultRBWriteTimeout = 5 // Seconds.
|
2020-05-19 09:02:02 +03:00
|
|
|
|
|
|
|
// Motion filter parameter defaults.
|
|
|
|
defaultMinFPS = 1.0
|
|
|
|
)
|
|
|
|
|
|
|
|
var Variables = []struct {
|
|
|
|
Name string
|
|
|
|
Type_ string
|
|
|
|
Update func(*Config, string)
|
|
|
|
Validate func(*Config)
|
|
|
|
}{
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyAutoWhiteBalance,
|
2020-05-19 09:02:02 +03:00
|
|
|
Type_: "enum:off,auto,sun,cloud,shade,tungsten,fluorescent,incandescent,flash,horizon",
|
|
|
|
Update: func(c *Config, v string) { c.AutoWhiteBalance = v },
|
|
|
|
},
|
2021-03-30 06:36:00 +03:00
|
|
|
{
|
|
|
|
Name: KeyAWBGains,
|
|
|
|
Type_: typeString,
|
|
|
|
Update: func(c *Config, v string) { c.AWBGains = v },
|
|
|
|
},
|
2020-05-19 09:02:02 +03:00
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyBitDepth,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.BitDepth = parseUint(KeyBitDepth, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyBitrate,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.Bitrate = parseUint(KeyBitrate, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyBrightness,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.Brightness = parseUint(KeyBrightness, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyBurstPeriod,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.BurstPeriod = parseUint(KeyBurstPeriod, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
Validate: func(c *Config) {
|
|
|
|
if c.BurstPeriod <= 0 {
|
2021-01-18 08:18:43 +03:00
|
|
|
c.LogInvalidField(KeyBurstPeriod, defaultBurstPeriod)
|
2020-05-19 09:02:02 +03:00
|
|
|
c.BurstPeriod = defaultBurstPeriod
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyCameraChan,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.CameraChan = uint8(parseUint(KeyCameraChan, v, c)) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyCameraIP,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeString,
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) { c.CameraIP = v },
|
|
|
|
Validate: func(c *Config) {
|
|
|
|
if c.CameraIP == "" {
|
2021-01-18 08:18:43 +03:00
|
|
|
c.LogInvalidField(KeyCameraIP, defaultCameraIP)
|
2020-05-19 09:02:02 +03:00
|
|
|
c.CameraIP = defaultCameraIP
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyCBR,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeBool,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.CBR = parseBool(KeyCBR, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyClipDuration,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
_v, err := strconv.Atoi(v)
|
|
|
|
if err != nil {
|
|
|
|
c.Logger.Log(logger.Warning, "invalid ClipDuration param", "value", v)
|
|
|
|
}
|
|
|
|
c.ClipDuration = time.Duration(_v) * time.Second
|
|
|
|
},
|
|
|
|
Validate: func(c *Config) {
|
|
|
|
if c.ClipDuration <= 0 {
|
2021-01-18 08:18:43 +03:00
|
|
|
c.LogInvalidField(KeyClipDuration, defaultClipDuration)
|
2020-05-19 09:02:02 +03:00
|
|
|
c.ClipDuration = defaultClipDuration
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
2020-08-11 05:13:17 +03:00
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyChannels,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.Channels = parseUint(KeyChannels, v, c) },
|
2020-08-11 05:13:17 +03:00
|
|
|
},
|
2021-03-30 06:36:00 +03:00
|
|
|
{
|
|
|
|
Name: KeyContrast,
|
|
|
|
Type_: typeInt,
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
_v, err := strconv.Atoi(v)
|
|
|
|
if err != nil {
|
|
|
|
c.Logger.Log(logger.Warning, "invalid contrast param", "value", v)
|
|
|
|
}
|
|
|
|
c.Contrast = _v
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: KeyEV,
|
|
|
|
Type_: typeInt,
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
_v, err := strconv.Atoi(v)
|
|
|
|
if err != nil {
|
|
|
|
c.Logger.Log(logger.Warning, "invalid EV param", "value", v)
|
|
|
|
}
|
|
|
|
c.EV = _v
|
|
|
|
},
|
|
|
|
},
|
2020-05-19 09:02:02 +03:00
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyExposure,
|
2020-05-19 09:02:02 +03:00
|
|
|
Type_: "enum:auto,night,nightpreview,backlight,spotlight,sports,snow,beach,verylong,fixedfps,antishake,fireworks",
|
|
|
|
Update: func(c *Config, v string) { c.Exposure = v },
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyFileFPS,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.FileFPS = parseUint(KeyFileFPS, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
Validate: func(c *Config) {
|
|
|
|
if c.FileFPS <= 0 || (c.FileFPS > 0 && c.Input != InputFile) {
|
2021-01-18 08:18:43 +03:00
|
|
|
c.LogInvalidField(KeyFileFPS, defaultFileFPS)
|
2020-05-19 09:02:02 +03:00
|
|
|
c.FileFPS = defaultFileFPS
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyFilters,
|
2020-05-19 09:02:02 +03:00
|
|
|
Type_: "enums:NoOp,MOG,VariableFPS,KNN,Difference,Basic",
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
filters := strings.Split(v, ",")
|
|
|
|
m := map[string]uint{"NoOp": FilterNoOp, "MOG": FilterMOG, "VariableFPS": FilterVariableFPS, "KNN": FilterKNN, "Difference": FilterDiff, "Basic": FilterBasic}
|
|
|
|
c.Filters = make([]uint, len(filters))
|
|
|
|
for i, filter := range filters {
|
|
|
|
v, ok := m[filter]
|
|
|
|
if !ok {
|
|
|
|
c.Logger.Log(logger.Warning, "invalid Filters param", "value", v)
|
|
|
|
}
|
|
|
|
c.Filters[i] = uint(v)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyFrameRate,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.FrameRate = parseUint(KeyFrameRate, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
Validate: func(c *Config) {
|
|
|
|
if c.FrameRate <= 0 || c.FrameRate > 60 {
|
2021-01-18 08:18:43 +03:00
|
|
|
c.LogInvalidField(KeyFrameRate, defaultFrameRate)
|
2020-05-19 09:02:02 +03:00
|
|
|
c.FrameRate = defaultFrameRate
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyHeight,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.Height = parseUint(KeyHeight, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyHorizontalFlip,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeBool,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.HorizontalFlip = parseBool(KeyHorizontalFlip, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyHTTPAddress,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeString,
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) { c.HTTPAddress = v },
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyInput,
|
2021-01-20 04:19:01 +03:00
|
|
|
Type_: "enum:raspivid,raspistill,rtsp,v4l,file,audio",
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
c.Input = parseEnum(
|
2021-01-18 08:18:43 +03:00
|
|
|
KeyInput,
|
2020-05-19 09:02:02 +03:00
|
|
|
v,
|
|
|
|
map[string]uint8{
|
2021-01-20 04:19:01 +03:00
|
|
|
"raspivid": InputRaspivid,
|
|
|
|
"raspistill": InputRaspistill,
|
|
|
|
"rtsp": InputRTSP,
|
|
|
|
"v4l": InputV4L,
|
|
|
|
"file": InputFile,
|
|
|
|
"audio": InputAudio,
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
c,
|
|
|
|
)
|
|
|
|
},
|
|
|
|
Validate: func(c *Config) {
|
|
|
|
switch c.Input {
|
2021-01-20 04:19:01 +03:00
|
|
|
case InputRaspivid, InputRaspistill, InputV4L, InputFile, InputAudio, InputRTSP:
|
2020-05-19 09:02:02 +03:00
|
|
|
default:
|
2021-01-18 08:18:43 +03:00
|
|
|
c.LogInvalidField(KeyInput, defaultInput)
|
2020-05-19 09:02:02 +03:00
|
|
|
c.Input = defaultInput
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyInputCodec,
|
2021-01-20 04:19:01 +03:00
|
|
|
Type_: "enum:H264,H265,MJPEG,JPEG,PCM,ADPCM",
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
c.InputCodec = parseEnum(
|
2021-01-18 08:18:43 +03:00
|
|
|
KeyInputCodec,
|
2020-05-19 09:02:02 +03:00
|
|
|
v,
|
|
|
|
map[string]uint8{
|
|
|
|
"h264": codecutil.H264,
|
|
|
|
"h265": codecutil.H265,
|
|
|
|
"mjpeg": codecutil.MJPEG,
|
2021-01-20 04:19:01 +03:00
|
|
|
"jpeg": codecutil.JPEG,
|
2020-05-19 09:02:02 +03:00
|
|
|
"pcm": codecutil.PCM,
|
|
|
|
"adpcm": codecutil.ADPCM,
|
|
|
|
},
|
|
|
|
c,
|
|
|
|
)
|
|
|
|
},
|
|
|
|
Validate: func(c *Config) {
|
|
|
|
switch c.InputCodec {
|
2021-01-20 04:19:01 +03:00
|
|
|
case codecutil.H264, codecutil.MJPEG, codecutil.JPEG, codecutil.PCM, codecutil.ADPCM:
|
2020-05-19 09:02:02 +03:00
|
|
|
default:
|
2021-01-18 08:18:43 +03:00
|
|
|
c.LogInvalidField(KeyInputCodec, defaultInputCodec)
|
2020-08-11 05:13:17 +03:00
|
|
|
c.InputCodec = defaultInputCodec
|
2020-05-19 09:02:02 +03:00
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyInputPath,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeString,
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) { c.InputPath = v },
|
|
|
|
},
|
2021-03-30 06:36:00 +03:00
|
|
|
{
|
|
|
|
Name: KeyISO,
|
|
|
|
Type_: typeUint,
|
|
|
|
Update: func(c *Config, v string) { c.ISO = parseUint(KeyISO, v, c) },
|
|
|
|
},
|
2020-05-19 09:02:02 +03:00
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyLogging,
|
2020-05-19 09:02:02 +03:00
|
|
|
Type_: "enum:Debug,Info,Warning,Error,Fatal",
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
switch v {
|
|
|
|
case "Debug":
|
|
|
|
c.LogLevel = logger.Debug
|
|
|
|
case "Info":
|
|
|
|
c.LogLevel = logger.Info
|
|
|
|
case "Warning":
|
|
|
|
c.LogLevel = logger.Warning
|
|
|
|
case "Error":
|
|
|
|
c.LogLevel = logger.Error
|
|
|
|
case "Fatal":
|
|
|
|
c.LogLevel = logger.Fatal
|
|
|
|
default:
|
|
|
|
c.Logger.Log(logger.Warning, "invalid Logging param", "value", v)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Validate: func(c *Config) {
|
|
|
|
switch c.LogLevel {
|
|
|
|
case logger.Debug, logger.Info, logger.Warning, logger.Error, logger.Fatal:
|
|
|
|
default:
|
|
|
|
c.LogInvalidField("LogLevel", defaultVerbosity)
|
|
|
|
c.LogLevel = defaultVerbosity
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyLoop,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeBool,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.Loop = parseBool(KeyLoop, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyMinFPS,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.MinFPS = parseUint(KeyMinFPS, v, c) },
|
|
|
|
Validate: func(c *Config) { c.MinFPS = lessThanOrEqual(KeyMinFPS, c.MinFPS, 0, c, defaultMinFPS) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyMinFrames,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.MinFrames = parseUint(KeyMinFrames, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
Validate: func(c *Config) {
|
|
|
|
const maxMinFrames = 1000
|
|
|
|
if c.MinFrames <= 0 || c.MinFrames > maxMinFrames {
|
2021-01-18 08:18:43 +03:00
|
|
|
c.LogInvalidField(KeyMinFrames, defaultMinFrames)
|
2020-05-19 09:02:02 +03:00
|
|
|
c.MinFrames = defaultMinFrames
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyMode,
|
2020-05-19 09:02:02 +03:00
|
|
|
Type_: "enum:Normal,Paused,Burst,Loop",
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
c.Loop = false
|
2021-01-18 08:18:43 +03:00
|
|
|
if v == KeyLoop {
|
2020-05-19 09:02:02 +03:00
|
|
|
c.Loop = true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyMotionDownscaling,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.MotionDownscaling = parseUint(KeyMotionDownscaling, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyMotionHistory,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.MotionHistory = parseUint(KeyMotionHistory, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyMotionInterval,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.MotionInterval = parseUint(KeyMotionInterval, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyMotionKernel,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.MotionKernel = parseUint(KeyMotionKernel, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyMotionMinArea,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeFloat,
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
f, err := strconv.ParseFloat(v, 64)
|
|
|
|
if err != nil {
|
|
|
|
c.Logger.Log(logger.Warning, "invalid MotionMinArea var", "value", v)
|
|
|
|
}
|
|
|
|
c.MotionMinArea = f
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyMotionPadding,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.MotionPadding = parseUint(KeyMotionPadding, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyMotionPixels,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.MotionPixels = parseUint(KeyMotionPixels, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyMotionThreshold,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeFloat,
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
f, err := strconv.ParseFloat(v, 64)
|
|
|
|
if err != nil {
|
|
|
|
c.Logger.Log(logger.Warning, "invalid MotionThreshold var", "value", v)
|
|
|
|
}
|
|
|
|
c.MotionThreshold = f
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyOutput,
|
2020-05-19 09:02:02 +03:00
|
|
|
Type_: "enum:File,HTTP,RTMP,RTP",
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
c.Outputs = make([]uint8, 1)
|
|
|
|
switch strings.ToLower(v) {
|
|
|
|
case "file":
|
|
|
|
c.Outputs[0] = OutputFile
|
2021-01-20 04:19:01 +03:00
|
|
|
case "files":
|
|
|
|
c.Outputs[0] = OutputFiles
|
2020-05-19 09:02:02 +03:00
|
|
|
case "http":
|
|
|
|
c.Outputs[0] = OutputHTTP
|
|
|
|
case "rtmp":
|
|
|
|
c.Outputs[0] = OutputRTMP
|
|
|
|
case "rtp":
|
|
|
|
c.Outputs[0] = OutputRTP
|
|
|
|
default:
|
|
|
|
c.Logger.Log(logger.Warning, "invalid output param", "value", v)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyOutputPath,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeString,
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) { c.OutputPath = v },
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyOutputs,
|
2020-05-19 09:02:02 +03:00
|
|
|
Type_: "enums:File,HTTP,RTMP,RTP",
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
outputs := strings.Split(v, ",")
|
|
|
|
c.Outputs = make([]uint8, len(outputs))
|
|
|
|
for i, output := range outputs {
|
|
|
|
switch strings.ToLower(output) {
|
|
|
|
case "file":
|
|
|
|
c.Outputs[i] = OutputFile
|
2021-01-20 04:19:01 +03:00
|
|
|
case "files":
|
|
|
|
c.Outputs[i] = OutputFiles
|
2020-05-19 09:02:02 +03:00
|
|
|
case "http":
|
|
|
|
c.Outputs[i] = OutputHTTP
|
|
|
|
case "rtmp":
|
|
|
|
c.Outputs[i] = OutputRTMP
|
|
|
|
case "rtp":
|
|
|
|
c.Outputs[i] = OutputRTP
|
|
|
|
default:
|
|
|
|
c.Logger.Log(logger.Warning, "invalid outputs param", "value", v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Validate: func(c *Config) {
|
|
|
|
if c.Outputs == nil {
|
2021-01-18 08:18:43 +03:00
|
|
|
c.LogInvalidField(KeyOutputs, defaultOutput)
|
2020-05-19 09:02:02 +03:00
|
|
|
c.Outputs = append(c.Outputs, defaultOutput)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyPSITime,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.PSITime = parseUint(KeyPSITime, v, c) },
|
|
|
|
Validate: func(c *Config) { c.PSITime = lessThanOrEqual(KeyPSITime, c.PSITime, 0, c, defaultPSITime) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyQuantization,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.Quantization = parseUint(KeyQuantization, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyRBCapacity,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.RBCapacity = parseUint(KeyRBCapacity, v, c) },
|
|
|
|
Validate: func(c *Config) { c.RBCapacity = lessThanOrEqual(KeyRBCapacity, c.RBCapacity, 0, c, defaultRBCapacity) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
2021-01-20 04:19:01 +03:00
|
|
|
{
|
|
|
|
Name: KeyRBStartElementSize,
|
|
|
|
Type_: typeUint,
|
|
|
|
Update: func(c *Config, v string) { c.RBStartElementSize = parseUint("RBStartElementSize", v, c) },
|
|
|
|
Validate: func(c *Config) {
|
|
|
|
c.RBStartElementSize = lessThanOrEqual("RBStartElementSize", c.RBStartElementSize, 0, c, defaultRBStartElementSize)
|
|
|
|
},
|
|
|
|
},
|
2020-05-19 09:02:02 +03:00
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyRBWriteTimeout,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.RBWriteTimeout = parseUint(KeyRBWriteTimeout, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
Validate: func(c *Config) {
|
2021-01-18 08:18:43 +03:00
|
|
|
c.RBWriteTimeout = lessThanOrEqual(KeyRBWriteTimeout, c.RBWriteTimeout, 0, c, defaultRBWriteTimeout)
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
},
|
2020-08-11 05:13:17 +03:00
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyRecPeriod,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeFloat,
|
2020-08-11 05:13:17 +03:00
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
_v, err := strconv.ParseFloat(v, 64)
|
|
|
|
if err != nil {
|
2021-01-18 08:18:43 +03:00
|
|
|
c.Logger.Log(logger.Warning, fmt.Sprintf("invalid %s param", KeyRecPeriod), "value", v)
|
2020-08-11 05:13:17 +03:00
|
|
|
}
|
2020-08-11 07:19:41 +03:00
|
|
|
c.RecPeriod = _v
|
2020-08-11 05:13:17 +03:00
|
|
|
},
|
|
|
|
},
|
2020-05-19 09:02:02 +03:00
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyRotation,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.Rotation = parseUint(KeyRotation, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyRTMPURL,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeString,
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) { c.RTMPURL = v },
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyRTPAddress,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeString,
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) { c.RTPAddress = v },
|
|
|
|
Validate: func(c *Config) {
|
|
|
|
if c.RTPAddress == "" {
|
2021-01-18 08:18:43 +03:00
|
|
|
c.LogInvalidField(KeyRTPAddress, defaultRTPAddr)
|
2020-05-19 09:02:02 +03:00
|
|
|
c.RTPAddress = defaultRTPAddr
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
2020-08-11 05:13:17 +03:00
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeySampleRate,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.SampleRate = parseUint(KeySampleRate, v, c) },
|
2020-08-11 05:13:17 +03:00
|
|
|
},
|
2020-05-19 09:02:02 +03:00
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeySaturation,
|
2021-01-20 04:19:01 +03:00
|
|
|
Type_: typeInt,
|
2020-05-19 09:02:02 +03:00
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
_v, err := strconv.Atoi(v)
|
|
|
|
if err != nil {
|
|
|
|
c.Logger.Log(logger.Warning, "invalid saturation param", "value", v)
|
|
|
|
}
|
|
|
|
c.Saturation = _v
|
|
|
|
},
|
|
|
|
},
|
2021-03-30 06:36:00 +03:00
|
|
|
{
|
|
|
|
Name: KeySharpness,
|
|
|
|
Type_: typeInt,
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
_v, err := strconv.Atoi(v)
|
|
|
|
if err != nil {
|
|
|
|
c.Logger.Log(logger.Warning, "invalid Sharpness param", "value", v)
|
|
|
|
}
|
|
|
|
c.Sharpness = _v
|
|
|
|
},
|
|
|
|
},
|
2021-01-20 04:19:01 +03:00
|
|
|
{
|
2021-01-27 06:11:29 +03:00
|
|
|
Name: KeyJPEGQuality,
|
2021-01-20 04:19:01 +03:00
|
|
|
Type_: typeUint,
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
_v, err := strconv.Atoi(v)
|
|
|
|
if err != nil {
|
2021-01-27 06:11:29 +03:00
|
|
|
c.Logger.Log(logger.Warning, "invalid JPEGQuality param", "value", v)
|
2021-01-20 04:19:01 +03:00
|
|
|
}
|
2021-01-27 06:11:29 +03:00
|
|
|
c.JPEGQuality = _v
|
2021-01-20 04:19:01 +03:00
|
|
|
},
|
|
|
|
},
|
2020-05-19 17:41:14 +03:00
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeySuppress,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeBool,
|
2020-05-19 17:41:14 +03:00
|
|
|
Update: func(c *Config, v string) {
|
2021-01-18 08:18:43 +03:00
|
|
|
c.Suppress = parseBool(KeySuppress, v, c)
|
2020-05-19 17:41:14 +03:00
|
|
|
c.Logger.(*logger.Logger).SetSuppress(c.Suppress)
|
|
|
|
},
|
|
|
|
},
|
2021-01-20 04:19:01 +03:00
|
|
|
{
|
|
|
|
Name: KeyTimelapseInterval,
|
|
|
|
Type_: typeUint,
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
_v, err := strconv.Atoi(v)
|
|
|
|
if err != nil {
|
|
|
|
c.Logger.Log(logger.Warning, "invalid TimelapseInterval param", "value", v)
|
|
|
|
}
|
|
|
|
c.TimelapseInterval = time.Duration(_v) * time.Second
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: KeyTimelapseDuration,
|
|
|
|
Type_: typeUint,
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
_v, err := strconv.Atoi(v)
|
|
|
|
if err != nil {
|
|
|
|
c.Logger.Log(logger.Warning, "invalid TimelapseDuration param", "value", v)
|
|
|
|
}
|
|
|
|
c.TimelapseDuration = time.Duration(_v) * time.Second
|
|
|
|
},
|
|
|
|
},
|
2020-05-19 09:02:02 +03:00
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyVBRBitrate,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.VBRBitrate = parseUint(KeyVBRBitrate, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyVBRQuality,
|
2020-05-19 09:02:02 +03:00
|
|
|
Type_: "enum:standard,fair,good,great,excellent",
|
|
|
|
Update: func(c *Config, v string) {
|
|
|
|
c.VBRQuality = Quality(parseEnum(
|
2021-01-18 08:18:43 +03:00
|
|
|
KeyVBRQuality,
|
2020-05-19 09:02:02 +03:00
|
|
|
v,
|
|
|
|
map[string]uint8{
|
|
|
|
"standard": uint8(QualityStandard),
|
|
|
|
"fair": uint8(QualityFair),
|
|
|
|
"good": uint8(QualityGood),
|
|
|
|
"great": uint8(QualityGreat),
|
|
|
|
"excellent": uint8(QualityExcellent),
|
|
|
|
},
|
|
|
|
c,
|
|
|
|
))
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyVerticalFlip,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeBool,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.VerticalFlip = parseBool(KeyVerticalFlip, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
{
|
2021-01-18 08:18:43 +03:00
|
|
|
Name: KeyWidth,
|
2021-01-04 06:22:57 +03:00
|
|
|
Type_: typeUint,
|
2021-01-18 08:18:43 +03:00
|
|
|
Update: func(c *Config, v string) { c.Width = parseUint(KeyWidth, v, c) },
|
2020-05-19 09:02:02 +03:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseUint(n, v string, c *Config) uint {
|
|
|
|
_v, err := strconv.Atoi(v)
|
|
|
|
if err != nil {
|
|
|
|
c.Logger.Log(logger.Warning, fmt.Sprintf("invalid %s param", n), "value", v)
|
|
|
|
}
|
|
|
|
return uint(_v)
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseBool(n, v string, c *Config) (b bool) {
|
|
|
|
switch strings.ToLower(v) {
|
|
|
|
case "true":
|
|
|
|
b = true
|
|
|
|
case "false":
|
|
|
|
b = false
|
|
|
|
default:
|
|
|
|
c.Logger.Log(logger.Warning, fmt.Sprintf("invalid value for %s param", n), "value", v)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseEnum(n, v string, enums map[string]uint8, c *Config) uint8 {
|
|
|
|
_v, ok := enums[strings.ToLower(v)]
|
|
|
|
if !ok {
|
|
|
|
c.Logger.Log(logger.Warning, fmt.Sprintf("invalid value for %s param", n), "value", v)
|
|
|
|
}
|
|
|
|
return _v
|
|
|
|
}
|
|
|
|
|
|
|
|
func lessThanOrEqual(n string, v, cmp uint, c *Config, def uint) uint {
|
|
|
|
if v <= cmp {
|
|
|
|
c.LogInvalidField(n, def)
|
|
|
|
return def
|
|
|
|
}
|
|
|
|
return v
|
|
|
|
}
|