2018-02-27 18:10:38 +03:00
|
|
|
/*
|
|
|
|
NAME
|
|
|
|
Config.go
|
|
|
|
|
|
|
|
AUTHORS
|
2018-06-07 14:50:57 +03:00
|
|
|
Saxon A. Nelson-Milton <saxon@ausocean.org>
|
2019-05-08 13:01:25 +03:00
|
|
|
Trek Hopton <trek@ausocean.org>
|
2018-02-27 18:10:38 +03:00
|
|
|
|
|
|
|
LICENSE
|
2018-06-08 03:02:13 +03:00
|
|
|
Config.go is Copyright (C) 2017-2018 the Australian Ocean Lab (AusOcean)
|
2018-02-27 18:10:38 +03:00
|
|
|
|
|
|
|
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
|
2018-06-07 14:50:57 +03:00
|
|
|
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
|
2018-02-27 18:10:38 +03:00
|
|
|
*/
|
|
|
|
|
2019-11-06 09:57:10 +03:00
|
|
|
package config
|
2018-02-10 10:08:14 +03:00
|
|
|
|
2018-02-12 10:58:29 +03:00
|
|
|
import (
|
|
|
|
"errors"
|
2020-01-02 07:33:43 +03:00
|
|
|
"fmt"
|
|
|
|
"os/exec"
|
2019-08-25 10:44:06 +03:00
|
|
|
"time"
|
2018-02-12 10:58:29 +03:00
|
|
|
|
2019-06-05 19:39:55 +03:00
|
|
|
"bitbucket.org/ausocean/av/codec/codecutil"
|
2019-01-02 08:09:47 +03:00
|
|
|
"bitbucket.org/ausocean/utils/logger"
|
2018-02-12 10:58:29 +03:00
|
|
|
)
|
|
|
|
|
2019-11-06 09:57:10 +03:00
|
|
|
const pkg = "config: "
|
|
|
|
|
|
|
|
type Logger interface {
|
|
|
|
SetLevel(int8)
|
|
|
|
Log(level int8, message string, params ...interface{})
|
|
|
|
}
|
|
|
|
|
2019-05-13 09:12:16 +03:00
|
|
|
// Enums to define inputs, outputs and codecs.
|
2018-02-10 10:08:14 +03:00
|
|
|
const (
|
2019-05-13 09:12:16 +03:00
|
|
|
// Indicates no option has been set.
|
2018-06-07 14:50:57 +03:00
|
|
|
NothingDefined = iota
|
2019-05-13 09:12:16 +03:00
|
|
|
|
|
|
|
// Input/Output.
|
2019-11-01 14:15:46 +03:00
|
|
|
InputFile
|
|
|
|
InputRaspivid
|
|
|
|
InputV4L
|
|
|
|
InputRTSP
|
|
|
|
InputAudio
|
2019-05-13 09:12:16 +03:00
|
|
|
|
|
|
|
// Outputs.
|
2019-11-01 14:15:46 +03:00
|
|
|
OutputAudio
|
|
|
|
OutputRTMP
|
|
|
|
OutputRTP
|
|
|
|
OutputHTTP
|
|
|
|
OutputMPEGTS
|
|
|
|
OutputFile
|
2019-05-13 09:12:16 +03:00
|
|
|
|
|
|
|
// Codecs.
|
2018-06-07 14:50:57 +03:00
|
|
|
H264
|
2019-05-27 08:45:26 +03:00
|
|
|
H265
|
2019-05-13 09:48:41 +03:00
|
|
|
MJPEG
|
2018-02-10 10:08:14 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
// Default config settings
|
|
|
|
const (
|
2019-08-08 06:50:02 +03:00
|
|
|
// General revid defaults.
|
2019-11-12 08:46:45 +03:00
|
|
|
defaultInput = InputRaspivid
|
|
|
|
defaultOutput = OutputHTTP
|
|
|
|
defaultTimeout = 0
|
|
|
|
defaultInputCodec = codecutil.H264
|
|
|
|
defaultVerbosity = logger.Error
|
|
|
|
defaultRtpAddr = "localhost:6970"
|
|
|
|
defaultCameraIP = "192.168.1.50"
|
|
|
|
defaultBurstPeriod = 10 // Seconds
|
|
|
|
defaultMinFrames = 100
|
2019-11-13 06:08:33 +03:00
|
|
|
defaultFrameRate = 25
|
2019-11-13 06:28:53 +03:00
|
|
|
defaultWriteRate = 25
|
2019-11-12 08:46:45 +03:00
|
|
|
defaultClipDuration = 0
|
2019-06-05 19:39:55 +03:00
|
|
|
defaultAudioInputCodec = codecutil.ADPCM
|
2019-12-19 03:45:47 +03:00
|
|
|
defaultPSITime = 2
|
2019-08-08 06:50:02 +03:00
|
|
|
|
2020-01-08 15:20:29 +03:00
|
|
|
// Ring buffer defaults.
|
|
|
|
|
2019-10-12 13:40:48 +03:00
|
|
|
// MTS ring buffer defaults.
|
2020-01-08 15:20:29 +03:00
|
|
|
defaultMTSRBMaxElements = 10000
|
|
|
|
defaultMTSRBCapacity = 200000000 // bytes
|
2019-10-15 03:32:28 +03:00
|
|
|
defaultMTSRBWriteTimeout = 5
|
2019-10-12 13:40:48 +03:00
|
|
|
|
|
|
|
// RTMP ring buffer defaults.
|
2020-01-08 15:20:29 +03:00
|
|
|
defaultRTMPRBMaxElements = 10000
|
|
|
|
defaultRTMPRBCapacity = 200000000 // bytes
|
2019-10-15 03:32:28 +03:00
|
|
|
defaultRTMPRBWriteTimeout = 5
|
2020-01-08 03:12:34 +03:00
|
|
|
|
|
|
|
// Motion filter parameter defaults.
|
|
|
|
defaultMinFPS = 1.0
|
|
|
|
|
|
|
|
// KNN filter parameter defaults.
|
|
|
|
defaultKNNMinArea = 25.0
|
|
|
|
defaultKNNThreshold = 300
|
|
|
|
defaultKNNHistory = 300
|
|
|
|
defaultKNNKernel = 9
|
|
|
|
|
|
|
|
// MOG filter parameter defaults.
|
|
|
|
defaultMOGMinArea = 25.0
|
|
|
|
defaultMOGThreshold = 20.0
|
|
|
|
defaultMOGHistory = 500
|
2018-02-10 10:08:14 +03:00
|
|
|
)
|
|
|
|
|
2020-01-08 03:12:34 +03:00
|
|
|
// Quality represents video quality.
|
2019-11-12 08:46:45 +03:00
|
|
|
type Quality int
|
|
|
|
|
|
|
|
// The different video qualities that can be used for variable bitrate when
|
|
|
|
// using the GeoVision camera.
|
|
|
|
const (
|
|
|
|
QualityStandard Quality = iota
|
|
|
|
QualityFair
|
|
|
|
QualityGood
|
|
|
|
QualityGreat
|
|
|
|
QualityExcellent
|
|
|
|
)
|
|
|
|
|
2019-12-23 04:29:17 +03:00
|
|
|
// The different media filters.
|
2019-12-20 03:12:51 +03:00
|
|
|
const (
|
|
|
|
FilterNoOp = iota
|
|
|
|
FilterMOG
|
2019-12-24 06:38:42 +03:00
|
|
|
FilterVariableFPS
|
2019-12-23 07:28:35 +03:00
|
|
|
FilterKNN
|
2019-12-20 03:12:51 +03:00
|
|
|
)
|
|
|
|
|
2020-01-02 07:43:39 +03:00
|
|
|
// OS names
|
|
|
|
const raspian = "Raspbian GNU/Linux"
|
|
|
|
|
2019-05-13 09:12:16 +03:00
|
|
|
// Config provides parameters relevant to a revid instance. A new config must
|
|
|
|
// be passed to the constructor. Default values for these fields are defined
|
2019-05-13 09:42:08 +03:00
|
|
|
// as consts above.
|
2019-05-13 09:12:16 +03:00
|
|
|
type Config struct {
|
2019-05-13 09:42:08 +03:00
|
|
|
// LogLevel is the revid logging verbosity level.
|
|
|
|
// Valid values are defined by enums from the logger package: logger.Debug,
|
|
|
|
// logger.Info, logger.Warning logger.Error, logger.Fatal.
|
2019-05-13 09:12:16 +03:00
|
|
|
LogLevel int8
|
|
|
|
|
2019-05-13 09:42:08 +03:00
|
|
|
// Input defines the input data source.
|
|
|
|
//
|
|
|
|
// Valid values are defined by enums:
|
2019-11-06 13:56:39 +03:00
|
|
|
// InputRaspivid:
|
2019-05-13 09:42:08 +03:00
|
|
|
// Read data from a Raspberry Pi Camera.
|
2019-11-06 13:56:39 +03:00
|
|
|
// InputV4l:
|
2019-05-13 09:42:08 +03:00
|
|
|
// Read from webcam.
|
2019-11-06 13:56:39 +03:00
|
|
|
// InputFile:
|
2019-05-13 09:42:08 +03:00
|
|
|
// Location must be specified in InputPath field.
|
2019-11-06 13:56:39 +03:00
|
|
|
// InputRTSP:
|
2019-10-22 07:24:38 +03:00
|
|
|
// CameraIP should also be defined.
|
2019-05-13 09:42:08 +03:00
|
|
|
Input uint8
|
|
|
|
|
2019-05-28 06:07:50 +03:00
|
|
|
// InputCodec defines the input codec we wish to use, and therefore defines the
|
|
|
|
// lexer for use in the pipeline. This defaults to H264, but H265 is also a
|
|
|
|
// valid option if we expect this from the input.
|
2019-05-13 09:42:08 +03:00
|
|
|
InputCodec uint8
|
|
|
|
|
|
|
|
// Outputs define the outputs we wish to output data too.
|
|
|
|
//
|
|
|
|
// Valid outputs are defined by enums:
|
2019-11-06 13:56:39 +03:00
|
|
|
// OutputFile:
|
2019-05-13 09:42:08 +03:00
|
|
|
// Location must be defined by the OutputPath field. MPEG-TS packetization
|
|
|
|
// is used.
|
2019-11-06 13:56:39 +03:00
|
|
|
// OutputHTTP:
|
2019-05-13 09:42:08 +03:00
|
|
|
// Destination is defined by the sh field located in /etc/netsender.conf.
|
|
|
|
// MPEGT-TS packetization is used.
|
2019-11-06 13:56:39 +03:00
|
|
|
// OutputRTMP:
|
2019-05-13 09:42:08 +03:00
|
|
|
// Destination URL must be defined in the RtmpUrl field. FLV packetization
|
|
|
|
// is used.
|
2019-11-06 13:56:39 +03:00
|
|
|
// OutputRTP:
|
2019-05-13 09:42:08 +03:00
|
|
|
// Destination is defined by RtpAddr field, otherwise it will default to
|
|
|
|
// localhost:6970. MPEGT-TS packetization is used.
|
|
|
|
Outputs []uint8
|
|
|
|
|
2019-05-13 10:25:20 +03:00
|
|
|
// RTMPURL specifies the Rtmp output destination URL. This must be defined if
|
2019-05-13 09:42:08 +03:00
|
|
|
// RTMP is to be used as an output.
|
2019-05-13 10:25:20 +03:00
|
|
|
RTMPURL string
|
|
|
|
|
2019-10-22 07:24:38 +03:00
|
|
|
// CameraIP is the IP address of the camera in the case of the input camera
|
|
|
|
// being an IP camera.
|
|
|
|
CameraIP string
|
2019-05-27 08:45:26 +03:00
|
|
|
|
2019-05-13 10:25:20 +03:00
|
|
|
// OutputPath defines the output destination for File output. This must be
|
|
|
|
// defined if File output is to be used.
|
|
|
|
OutputPath string
|
|
|
|
|
|
|
|
// InputPath defines the input file location for File Input. This must be
|
|
|
|
// defined if File input is to be used.
|
|
|
|
InputPath string
|
|
|
|
|
|
|
|
// FrameRate defines the input frame rate if configurable by the chosen input.
|
|
|
|
// Raspivid input supports custom framerate.
|
|
|
|
FrameRate uint
|
|
|
|
|
2019-06-13 17:45:04 +03:00
|
|
|
// WriteRate is how many times a second revid encoders will be written to.
|
|
|
|
WriteRate float64
|
|
|
|
|
2019-05-13 10:25:20 +03:00
|
|
|
// HTTPAddress defines a custom HTTP destination if we do not wish to use that
|
|
|
|
// defined in /etc/netsender.conf.
|
|
|
|
HTTPAddress string
|
|
|
|
|
2019-11-22 06:08:57 +03:00
|
|
|
// CBR indicates whether we wish to use constant or variable bitrate. If CBR
|
|
|
|
// is true then we will use constant bitrate, and variable bitrate otherwise.
|
2019-10-22 07:24:38 +03:00
|
|
|
// In the case of the Pi camera, variable bitrate quality is controlled by
|
|
|
|
// the Quantization parameter below. In the case of the GeoVision camera,
|
|
|
|
// variable bitrate quality is controlled by firstly the VBRQuality parameter
|
|
|
|
// and second the VBRBitrate parameter.
|
2019-11-22 06:08:57 +03:00
|
|
|
CBR bool
|
2019-10-22 07:24:38 +03:00
|
|
|
|
|
|
|
// Quantization defines the quantization level, which will determine variable
|
|
|
|
// bitrate quality in the case of input from the Pi Camera.
|
2019-05-13 10:25:20 +03:00
|
|
|
Quantization uint
|
|
|
|
|
2019-10-22 07:24:38 +03:00
|
|
|
// VBRQuality describes the general quality of video from the GeoVision camera
|
|
|
|
// under variable bitrate. VBRQuality can be one 5 consts defined:
|
|
|
|
// qualityStandard, qualityFair, qualityGood, qualityGreat and qualityExcellent.
|
2019-11-06 09:57:10 +03:00
|
|
|
VBRQuality Quality
|
2019-10-22 07:24:38 +03:00
|
|
|
|
|
|
|
// VBRBitrate describes maximal bitrate for the GeoVision camera when under
|
|
|
|
// variable bitrate.
|
|
|
|
VBRBitrate int
|
|
|
|
|
2019-10-25 04:42:30 +03:00
|
|
|
// This is the channel we're using for the GeoVision camera.
|
|
|
|
CameraChan int
|
|
|
|
|
2019-08-26 07:13:45 +03:00
|
|
|
// MinFrames defines the frequency of key NAL units SPS, PPS and IDR in
|
2019-08-25 10:44:06 +03:00
|
|
|
// number of NAL units. This will also determine the frequency of PSI if the
|
2019-08-26 07:13:45 +03:00
|
|
|
// output container is MPEG-TS. If ClipDuration is less than MinFrames,
|
|
|
|
// ClipDuration will default to MinFrames.
|
|
|
|
MinFrames uint
|
2019-08-25 10:44:06 +03:00
|
|
|
|
|
|
|
// ClipDuration is the duration of MTS data that is sent using HTTP or RTP
|
2019-08-26 07:13:45 +03:00
|
|
|
// output. This defaults to 0, therefore MinFrames will determine the length of
|
2019-08-25 10:44:06 +03:00
|
|
|
// clips by default.
|
|
|
|
ClipDuration time.Duration
|
2019-05-13 10:25:20 +03:00
|
|
|
|
|
|
|
// Logger holds an implementation of the Logger interface as defined in revid.go.
|
|
|
|
// This must be set for revid to work correctly.
|
|
|
|
Logger Logger
|
|
|
|
|
|
|
|
// Brightness and saturation define the brightness and saturation levels for
|
|
|
|
// Raspivid input.
|
|
|
|
Brightness uint
|
|
|
|
Saturation int
|
|
|
|
|
|
|
|
// Exposure defines the exposure mode used by the Raspivid input. Valid modes
|
|
|
|
// are defined in the exported []string ExposureModes defined at the start
|
|
|
|
// of the file.
|
|
|
|
Exposure string
|
|
|
|
|
2020-01-02 04:15:36 +03:00
|
|
|
// ShowWindows enables or disables the display of windows used for debugging
|
|
|
|
// motion filters.
|
|
|
|
ShowWindows bool
|
|
|
|
|
2019-05-13 10:25:20 +03:00
|
|
|
// AutoWhiteBalance defines the auto white balance mode used by Raspivid input.
|
|
|
|
// Valid modes are defined in the exported []string AutoWhiteBalanceModes
|
|
|
|
// defined at the start of the file.
|
|
|
|
AutoWhiteBalance string
|
|
|
|
|
2019-06-13 17:45:04 +03:00
|
|
|
// Audio
|
|
|
|
SampleRate int // Samples a second (Hz).
|
|
|
|
RecPeriod float64 // How many seconds to record at a time.
|
|
|
|
Channels int // Number of audio channels, 1 for mono, 2 for stereo.
|
|
|
|
BitDepth int // Sample bit depth.
|
|
|
|
|
2019-12-17 02:51:56 +03:00
|
|
|
RTPAddress string // RTPAddress defines the RTP output destination.
|
|
|
|
BurstPeriod uint // BurstPeriod defines the revid burst period in seconds.
|
|
|
|
Rotation uint // Rotation defines the video rotation angle in degrees Raspivid input.
|
|
|
|
Height uint // Height defines the input video height Raspivid input.
|
|
|
|
Width uint // Width defines the input video width Raspivid input.
|
|
|
|
Bitrate uint // Bitrate specifies the bitrate for constant bitrate in kbps.
|
|
|
|
|
2019-12-27 08:36:30 +03:00
|
|
|
HorizontalFlip bool // HorizontalFlip flips video horizontally for Raspivid input.
|
|
|
|
VerticalFlip bool // VerticalFlip flips video vertically for Raspivid input.
|
|
|
|
Filters []int // Defines the methods of filtering to be used in between lexing and encoding.
|
2020-01-02 09:35:50 +03:00
|
|
|
PSITime int // Sets the time between a packet being sent.
|
2019-08-08 06:50:02 +03:00
|
|
|
|
2019-10-12 13:40:48 +03:00
|
|
|
// RTMP ring buffer parameters.
|
2020-01-08 15:20:29 +03:00
|
|
|
RTMPRBMaxElements int // The maximum possible number of elements in ring buffer.
|
|
|
|
RTMPRBCapacity int // The total number of bytes available for the ring buffer.
|
2019-10-15 03:32:28 +03:00
|
|
|
RTMPRBWriteTimeout int // The ringbuffer write timeout in seconds.
|
2019-10-12 13:40:48 +03:00
|
|
|
|
|
|
|
// MTS ring buffer parameters.
|
2020-01-08 15:20:29 +03:00
|
|
|
MTSRBMaxElements int // The maximum possible number of elements in ring buffer.
|
|
|
|
MTSRBCapacity int // The total number of bytes available for the ring buffer.
|
2019-10-15 03:32:28 +03:00
|
|
|
MTSRBWriteTimeout int // The ringbuffer write timeout in seconds.
|
2020-01-08 03:12:34 +03:00
|
|
|
|
|
|
|
// Motion filter parameters.
|
|
|
|
MinFPS float64 // The reduced framerate of the video when there is no motion.
|
|
|
|
|
|
|
|
// KNN filter parameters.
|
|
|
|
KNNMinArea float64 // Used to ignore small areas of motion detection.
|
|
|
|
KNNThreshold float64 // Intensity value from the KNN motion detection algorithm that is considered motion.
|
|
|
|
KNNHistory uint // Length of KNN filter's history
|
|
|
|
KNNKernel uint // Size of kernel used for filling holes and removing noise.
|
|
|
|
|
|
|
|
// MOG filter parameters.
|
|
|
|
MOGMinArea float64 // Used to ignore small areas of motion detection.
|
|
|
|
MOGThreshold float64 // Intensity value from the KNN motion detection algorithm that is considered motion.
|
|
|
|
MOGHistory uint // Length of MOG filter's history
|
2019-05-13 09:12:16 +03:00
|
|
|
}
|
|
|
|
|
2019-12-05 09:39:28 +03:00
|
|
|
// TypeData contains information about all of the variables that
|
|
|
|
// can be set over the web. It is a psuedo const.
|
|
|
|
var TypeData = map[string]string{
|
|
|
|
"AutoWhiteBalance": "enum:off,auto,sun,cloud,shade,tungsten,fluorescent,incandescent,flash,horizon",
|
|
|
|
"BitDepth": "int",
|
2019-12-18 08:32:20 +03:00
|
|
|
"Brightness": "uint",
|
|
|
|
"BurstPeriod": "uint",
|
|
|
|
"CameraChan": "int",
|
|
|
|
"CBR": "bool",
|
2019-12-05 09:39:28 +03:00
|
|
|
"ClipDuration": "uint",
|
2019-12-18 08:32:20 +03:00
|
|
|
"Exposure": "enum:auto,night,nightpreview,backlight,spotlight,sports,snow,beach,verylong,fixedfps,antishake,fireworks",
|
2019-12-31 04:13:26 +03:00
|
|
|
"Filters": "enums:NoOp,MOG,VariableFPS,KNN",
|
2019-12-18 08:32:20 +03:00
|
|
|
"FrameRate": "uint",
|
|
|
|
"Height": "uint",
|
2019-12-05 09:39:28 +03:00
|
|
|
"HorizontalFlip": "bool",
|
2019-12-18 08:32:20 +03:00
|
|
|
"HTTPAddress": "string",
|
|
|
|
"Input": "enum:raspivid,rtsp,v4l,file",
|
|
|
|
"InputCodec": "enum:H264,MJPEG",
|
|
|
|
"InputPath": "string",
|
2020-01-08 03:12:34 +03:00
|
|
|
"KNNHistory": "uint",
|
|
|
|
"KNNKernel": "float",
|
|
|
|
"KNNMinArea": "float",
|
|
|
|
"KNNThreshold": "float",
|
2019-12-23 08:51:49 +03:00
|
|
|
"logging": "enum:Debug,Info,Warning,Error,Fatal",
|
2020-01-08 03:12:34 +03:00
|
|
|
"MinFPS": "float",
|
2019-12-18 08:32:20 +03:00
|
|
|
"MinFrames": "uint",
|
2020-01-08 03:12:34 +03:00
|
|
|
"MOGHistory": "uint",
|
|
|
|
"MOGMinArea": "float",
|
|
|
|
"MOGThreshold": "float",
|
2020-01-08 15:47:51 +03:00
|
|
|
"MTSRBCapacity": "uint",
|
|
|
|
"MTSRBMaxElements": "uint",
|
|
|
|
"MTSRBWriteTimeout": "uint",
|
2019-12-23 09:25:40 +03:00
|
|
|
"Output": "enum:File,Http,Rtmp,Rtp",
|
2020-01-08 03:12:34 +03:00
|
|
|
"OutputPath": "string",
|
2020-01-02 02:52:46 +03:00
|
|
|
"Outputs": "enums:File,Http,Rtmp,Rtp",
|
2019-12-18 08:32:20 +03:00
|
|
|
"Quantization": "uint",
|
|
|
|
"Rotation": "uint",
|
2020-01-08 15:47:51 +03:00
|
|
|
"RTMPRBCapacity": "uint",
|
|
|
|
"RTMPRBMaxElements": "uint",
|
|
|
|
"RTMPRBWriteTimeout": "uint",
|
2019-12-18 08:32:20 +03:00
|
|
|
"RTMPURL": "string",
|
|
|
|
"RTPAddress": "string",
|
|
|
|
"Saturation": "int",
|
2020-01-02 04:15:36 +03:00
|
|
|
"ShowWindows": "bool",
|
2019-12-05 09:39:28 +03:00
|
|
|
"VBRBitrate": "int",
|
2019-12-18 08:32:20 +03:00
|
|
|
"VBRQuality": "enum:standard,fair,good,great,excellent",
|
|
|
|
"VerticalFlip": "bool",
|
|
|
|
"Width": "uint",
|
2019-12-05 09:39:28 +03:00
|
|
|
}
|
|
|
|
|
2019-08-24 07:32:24 +03:00
|
|
|
// Validation errors.
|
|
|
|
var (
|
|
|
|
errInvalidQuantization = errors.New("invalid quantization")
|
|
|
|
)
|
|
|
|
|
2018-03-17 16:29:42 +03:00
|
|
|
// Validate checks for any errors in the config fields and defaults settings
|
2018-02-10 10:08:14 +03:00
|
|
|
// if particular parameters have not been defined.
|
2019-08-24 07:32:24 +03:00
|
|
|
func (c *Config) Validate() error {
|
2018-09-22 08:16:54 +03:00
|
|
|
switch c.LogLevel {
|
2019-12-05 02:00:51 +03:00
|
|
|
case logger.Debug, logger.Info, logger.Warning, logger.Error, logger.Fatal:
|
2018-03-17 16:29:42 +03:00
|
|
|
default:
|
2018-09-22 08:16:54 +03:00
|
|
|
c.LogLevel = defaultVerbosity
|
2019-05-06 09:29:41 +03:00
|
|
|
c.Logger.Log(logger.Info, pkg+"bad LogLevel mode defined, defaulting", "LogLevel", defaultVerbosity)
|
2018-03-17 16:29:42 +03:00
|
|
|
}
|
|
|
|
|
2019-10-22 15:34:33 +03:00
|
|
|
if c.CameraIP == "" {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"no CameraIP defined, defaulting", "CameraIP", defaultCameraIP)
|
|
|
|
c.CameraIP = defaultCameraIP
|
|
|
|
}
|
|
|
|
|
2018-06-09 05:01:21 +03:00
|
|
|
switch c.Input {
|
2019-11-01 14:15:46 +03:00
|
|
|
case InputRaspivid, InputV4L, InputFile, InputAudio, InputRTSP:
|
2018-02-10 10:08:14 +03:00
|
|
|
case NothingDefined:
|
2019-05-06 09:29:41 +03:00
|
|
|
c.Logger.Log(logger.Info, pkg+"no input type defined, defaulting", "input", defaultInput)
|
2018-06-09 05:01:21 +03:00
|
|
|
c.Input = defaultInput
|
2018-02-10 10:08:14 +03:00
|
|
|
default:
|
2018-09-20 05:04:17 +03:00
|
|
|
return errors.New("bad input type defined in config")
|
2018-02-10 10:08:14 +03:00
|
|
|
}
|
|
|
|
|
2018-06-09 05:01:21 +03:00
|
|
|
switch c.InputCodec {
|
2019-09-24 01:12:26 +03:00
|
|
|
case codecutil.H264, codecutil.MJPEG, codecutil.PCM, codecutil.ADPCM:
|
2019-06-05 19:39:55 +03:00
|
|
|
default:
|
2019-05-09 05:41:02 +03:00
|
|
|
switch c.Input {
|
2019-11-01 14:15:46 +03:00
|
|
|
case OutputAudio:
|
2019-05-09 05:41:02 +03:00
|
|
|
c.Logger.Log(logger.Info, pkg+"input is audio but no codec defined, defaulting", "inputCodec", defaultAudioInputCodec)
|
|
|
|
c.InputCodec = defaultAudioInputCodec
|
|
|
|
default:
|
|
|
|
c.Logger.Log(logger.Info, pkg+"no input codec defined, defaulting", "inputCodec", defaultInputCodec)
|
|
|
|
c.InputCodec = defaultInputCodec
|
|
|
|
}
|
2018-02-10 10:08:14 +03:00
|
|
|
}
|
|
|
|
|
2019-05-05 16:20:59 +03:00
|
|
|
if c.Outputs == nil {
|
2019-05-06 09:29:41 +03:00
|
|
|
c.Logger.Log(logger.Info, pkg+"no output defined, defaulting", "output", defaultOutput)
|
2019-05-05 16:20:59 +03:00
|
|
|
c.Outputs = append(c.Outputs, defaultOutput)
|
2019-08-24 07:32:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
for i, o := range c.Outputs {
|
|
|
|
switch o {
|
2019-11-12 08:46:45 +03:00
|
|
|
case OutputFile, OutputHTTP, OutputRTP:
|
2019-11-01 14:15:46 +03:00
|
|
|
case OutputRTMP:
|
2019-08-24 07:32:24 +03:00
|
|
|
if c.RTMPURL == "" {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"no RTMP URL: falling back to HTTP")
|
2019-11-01 14:15:46 +03:00
|
|
|
c.Outputs[i] = OutputHTTP
|
2019-08-24 07:32:24 +03:00
|
|
|
}
|
|
|
|
default:
|
|
|
|
return errors.New("bad output type defined in config")
|
2018-06-08 03:02:13 +03:00
|
|
|
}
|
2018-11-25 15:40:38 +03:00
|
|
|
}
|
|
|
|
|
2019-02-03 16:13:51 +03:00
|
|
|
if c.BurstPeriod == 0 {
|
2019-03-04 05:17:57 +03:00
|
|
|
c.Logger.Log(logger.Info, pkg+"no burst period defined, defaulting", "burstPeriod", defaultBurstPeriod)
|
2019-02-03 16:13:51 +03:00
|
|
|
c.BurstPeriod = defaultBurstPeriod
|
|
|
|
}
|
|
|
|
|
2019-12-03 08:00:58 +03:00
|
|
|
const maxMinFrames = 1000
|
|
|
|
switch {
|
|
|
|
case c.MinFrames == 0:
|
2019-08-26 07:13:45 +03:00
|
|
|
c.Logger.Log(logger.Info, pkg+"no min period defined, defaulting", "MinFrames", defaultMinFrames)
|
|
|
|
c.MinFrames = defaultMinFrames
|
2019-12-03 08:00:58 +03:00
|
|
|
case c.MinFrames < 0:
|
2019-08-25 10:44:06 +03:00
|
|
|
return errors.New("refresh period is less than 0")
|
2019-12-03 08:00:58 +03:00
|
|
|
case c.MinFrames > maxMinFrames:
|
|
|
|
return errors.New("refresh period is greater than 1000")
|
2019-08-25 10:44:06 +03:00
|
|
|
}
|
|
|
|
|
2019-11-13 06:28:53 +03:00
|
|
|
if c.FrameRate <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"frame rate bad or unset, defaulting", "FrameRate", defaultFrameRate)
|
2019-11-13 06:08:33 +03:00
|
|
|
c.FrameRate = defaultFrameRate
|
2019-11-13 06:28:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if c.WriteRate <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"write rate bad or unset, defaulting", "writeRate", defaultWriteRate)
|
|
|
|
c.WriteRate = defaultWriteRate
|
2019-11-13 06:08:33 +03:00
|
|
|
}
|
|
|
|
|
2019-08-25 10:44:06 +03:00
|
|
|
if c.ClipDuration == 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"no clip duration defined, defaulting", "ClipDuration", defaultClipDuration)
|
|
|
|
c.ClipDuration = defaultClipDuration
|
|
|
|
} else if c.ClipDuration < 0 {
|
|
|
|
return errors.New("clip duration is less than 0")
|
2018-02-10 10:08:14 +03:00
|
|
|
}
|
|
|
|
|
2019-05-13 09:53:38 +03:00
|
|
|
if c.RTPAddress == "" {
|
|
|
|
c.RTPAddress = defaultRtpAddr
|
2018-11-20 17:37:38 +03:00
|
|
|
}
|
2019-03-15 09:54:29 +03:00
|
|
|
|
2020-01-08 15:20:29 +03:00
|
|
|
if c.RTMPRBMaxElements <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"RTMPRBMaxElements bad or unset, defaulting", "RTMPRBMaxElements", defaultRTMPRBMaxElements)
|
|
|
|
c.RTMPRBMaxElements = defaultRTMPRBMaxElements
|
2019-08-08 06:50:02 +03:00
|
|
|
}
|
|
|
|
|
2020-01-08 15:20:29 +03:00
|
|
|
if c.RTMPRBCapacity <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"RTMPRBCapacity bad or unset, defaulting", "RTMPRBCapacity", defaultRTMPRBCapacity)
|
|
|
|
c.RTMPRBCapacity = defaultRTMPRBCapacity
|
2019-08-08 06:50:02 +03:00
|
|
|
}
|
|
|
|
|
2019-10-12 13:40:48 +03:00
|
|
|
if c.RTMPRBWriteTimeout <= 0 {
|
2019-10-15 03:32:28 +03:00
|
|
|
c.Logger.Log(logger.Info, pkg+"RTMPRBWriteTimeout bad or unset, defaulting", "RTMPRBWriteTimeout", defaultRTMPRBWriteTimeout)
|
2019-10-12 13:40:48 +03:00
|
|
|
c.RTMPRBWriteTimeout = defaultRTMPRBWriteTimeout
|
|
|
|
}
|
|
|
|
|
2020-01-08 15:20:29 +03:00
|
|
|
if c.MTSRBMaxElements <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"MTSRBSize bad or unset, defaulting", "MTSRBSize", defaultMTSRBMaxElements)
|
|
|
|
c.MTSRBMaxElements = defaultMTSRBMaxElements
|
2019-08-08 06:50:02 +03:00
|
|
|
}
|
|
|
|
|
2020-01-08 15:20:29 +03:00
|
|
|
if c.MTSRBCapacity <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"MTSRBElementSize bad or unset, defaulting", "MTSRBElementSize", defaultMTSRBCapacity)
|
|
|
|
c.MTSRBCapacity = defaultMTSRBCapacity
|
2019-08-08 06:50:02 +03:00
|
|
|
}
|
|
|
|
|
2019-10-12 13:40:48 +03:00
|
|
|
if c.MTSRBWriteTimeout <= 0 {
|
2019-10-15 03:32:28 +03:00
|
|
|
c.Logger.Log(logger.Info, pkg+"MTSRBWriteTimeout bad or unset, defaulting", "MTSRBWriteTimeout", defaultMTSRBWriteTimeout)
|
2019-10-12 13:40:48 +03:00
|
|
|
c.MTSRBWriteTimeout = defaultMTSRBWriteTimeout
|
|
|
|
}
|
|
|
|
|
2019-12-19 03:45:47 +03:00
|
|
|
if c.PSITime <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"PSITime bad or unset, defaulting", "PSITime", defaultPSITime)
|
|
|
|
c.PSITime = defaultPSITime
|
2019-12-17 02:51:56 +03:00
|
|
|
}
|
|
|
|
|
2020-01-08 03:12:34 +03:00
|
|
|
if c.MinFPS <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"MinFPS bad or unset, defaulting", "MinFPS", defaultMinFPS)
|
|
|
|
c.MinFPS = defaultMinFPS
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.KNNMinArea <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"KNNMinArea bad or unset, defaulting", "KNNMinArea", defaultKNNMinArea)
|
|
|
|
c.KNNMinArea = defaultKNNMinArea
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.KNNThreshold <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"KNNThreshold bad or unset, defaulting", "KNNThreshold", defaultKNNThreshold)
|
|
|
|
c.KNNThreshold = defaultKNNThreshold
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.KNNHistory == 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"KNNHistory bad or unset, defaulting", "KNNHistory", defaultKNNHistory)
|
|
|
|
c.KNNHistory = defaultKNNHistory
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.KNNKernel <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"KNNKernel bad or unset, defaulting", "KNNKernel", defaultKNNKernel)
|
|
|
|
c.KNNKernel = defaultKNNKernel
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.MOGMinArea <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"MOGMinArea bad or unset, defaulting", "MOGMinArea", defaultMOGMinArea)
|
|
|
|
c.MOGMinArea = defaultMOGMinArea
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.MOGThreshold <= 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"MOGThreshold bad or unset, defaulting", "MOGThreshold", defaultMOGThreshold)
|
|
|
|
c.MOGThreshold = defaultMOGThreshold
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.MOGHistory == 0 {
|
|
|
|
c.Logger.Log(logger.Info, pkg+"MOGHistory bad or unset, defaulting", "MOGHistory", defaultMOGHistory)
|
|
|
|
c.MOGHistory = defaultMOGHistory
|
|
|
|
}
|
|
|
|
|
2020-01-02 07:43:39 +03:00
|
|
|
if c.ShowWindows {
|
2020-01-02 07:33:43 +03:00
|
|
|
os, err := osName()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-01-02 07:43:39 +03:00
|
|
|
if os == raspian {
|
2020-01-02 07:33:43 +03:00
|
|
|
c.Logger.Log(logger.Info, "ShowWindows disabled on Raspbian GNU/Linux")
|
|
|
|
c.ShowWindows = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-12 10:58:29 +03:00
|
|
|
return nil
|
2018-02-10 10:08:14 +03:00
|
|
|
}
|
2019-03-15 09:54:29 +03:00
|
|
|
|
2020-01-02 07:33:43 +03:00
|
|
|
func osName() (string, error) {
|
|
|
|
out, err := exec.Command("grep", "^NAME=", "/etc/os-release").Output()
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("could not get OS name: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return string(out)[6 : len(out)-2], nil
|
|
|
|
}
|
|
|
|
|
2019-03-15 10:28:24 +03:00
|
|
|
// stringInSlice returns true if want is in slice.
|
2019-03-15 09:54:29 +03:00
|
|
|
func stringInSlice(want string, slice []string) bool {
|
|
|
|
for _, s := range slice {
|
|
|
|
if s == want {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|