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
|
|
|
*/
|
|
|
|
|
2020-02-26 06:58:12 +03:00
|
|
|
// Package config contains the configuration settings for revid.
|
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 (
|
2019-08-25 10:44:06 +03:00
|
|
|
"time"
|
2018-02-12 10:58:29 +03:00
|
|
|
|
2021-02-22 06:46:41 +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
|
|
|
type Logger interface {
|
|
|
|
SetLevel(int8)
|
|
|
|
Log(level int8, message string, params ...interface{})
|
2021-01-20 04:19:01 +03:00
|
|
|
Debug(msg string, params ...interface{})
|
|
|
|
Info(msg string, params ...interface{})
|
|
|
|
Warning(msg string, params ...interface{})
|
|
|
|
Error(msg string, params ...interface{})
|
|
|
|
Fatal(msg string, params ...interface{})
|
2019-11-06 09:57:10 +03:00
|
|
|
}
|
|
|
|
|
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
|
2021-01-20 04:19:01 +03:00
|
|
|
InputRaspistill
|
2019-11-01 14:15:46 +03:00
|
|
|
InputV4L
|
|
|
|
InputRTSP
|
|
|
|
InputAudio
|
2019-05-13 09:12:16 +03:00
|
|
|
|
|
|
|
// Outputs.
|
2019-11-01 14:15:46 +03:00
|
|
|
OutputRTMP
|
|
|
|
OutputRTP
|
|
|
|
OutputHTTP
|
|
|
|
OutputMPEGTS
|
|
|
|
OutputFile
|
2021-01-20 04:19:01 +03:00
|
|
|
OutputFiles
|
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
|
2021-01-20 04:19:01 +03:00
|
|
|
MJPEG
|
2021-01-18 07:59:21 +03:00
|
|
|
JPEG
|
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
|
2020-02-10 07:57:43 +03:00
|
|
|
FilterDiff
|
2020-01-24 09:31:28 +03:00
|
|
|
FilterBasic
|
2019-12-20 03:12:51 +03:00
|
|
|
)
|
|
|
|
|
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 {
|
2020-05-20 04:43:14 +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
|
|
|
|
|
|
|
|
BitDepth uint // Sample bit depth.
|
|
|
|
Bitrate uint // Bitrate specifies the bitrate for constant bitrate in kbps.
|
|
|
|
Brightness uint
|
|
|
|
BurstPeriod uint // BurstPeriod defines the revid burst period in seconds.
|
|
|
|
CameraChan uint8 // This is the channel we're using for the GeoVision camera.
|
|
|
|
|
|
|
|
// CameraIP is the IP address of the camera in the case of the input camera
|
|
|
|
// being an IP camera.
|
|
|
|
CameraIP string
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
// 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.
|
|
|
|
CBR bool
|
|
|
|
|
|
|
|
Channels uint // Number of audio channels, 1 for mono, 2 for stereo.
|
|
|
|
|
|
|
|
// ClipDuration is the duration of MTS data that is sent using HTTP or RTP
|
|
|
|
// output. This defaults to 0, therefore MinFrames will determine the length of
|
|
|
|
// clips by default.
|
|
|
|
ClipDuration time.Duration
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
FileFPS uint // Defines the rate at which frames from a file source are processed.
|
|
|
|
Filters []uint // Defines the methods of filtering to be used in between lexing and encoding.
|
|
|
|
|
|
|
|
// FrameRate defines the input frame rate if configurable by the chosen input.
|
|
|
|
// Raspivid input supports custom framerate.
|
|
|
|
FrameRate uint
|
|
|
|
|
|
|
|
Height uint // Height defines the input video height Raspivid input.
|
|
|
|
HorizontalFlip bool // HorizontalFlip flips video horizontally for Raspivid input.
|
|
|
|
|
|
|
|
// HTTPAddress defines a custom HTTP destination if we do not wish to use that
|
|
|
|
// defined in /etc/netsender.conf.
|
|
|
|
HTTPAddress string
|
2019-05-13 09:12:16 +03:00
|
|
|
|
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:
|
2021-01-20 04:19:01 +03:00
|
|
|
// Use raspivid utility to capture video from Raspberry Pi Camera.
|
|
|
|
// InputRaspistill:
|
|
|
|
// Use raspistill utility to capture images from the 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:
|
2020-05-02 12:15:38 +03:00
|
|
|
// Read h.264 bytestream from a file.
|
2019-05-13 09:42:08 +03:00
|
|
|
// Location must be specified in InputPath field.
|
2019-11-06 13:56:39 +03:00
|
|
|
// InputRTSP:
|
2020-05-02 12:15:38 +03:00
|
|
|
// Read from a camera supporting RTSP communication.
|
2019-10-22 07:24:38 +03:00
|
|
|
// CameraIP should also be defined.
|
2020-05-02 12:15:38 +03:00
|
|
|
// InputAudio:
|
|
|
|
// Read from a ALSA audio source.
|
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.
|
2021-02-22 06:46:41 +03:00
|
|
|
InputCodec codecutil.Codec
|
2019-05-13 09:42:08 +03:00
|
|
|
|
2020-05-20 04:43:14 +03:00
|
|
|
// InputPath defines the input file location for File Input. This must be
|
|
|
|
// defined if File input is to be used.
|
|
|
|
InputPath string
|
|
|
|
|
|
|
|
// Logger holds an implementation of the Logger interface as defined in revid.go.
|
|
|
|
// This must be set for revid to work correctly.
|
|
|
|
Logger Logger
|
|
|
|
|
|
|
|
// 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.
|
|
|
|
LogLevel int8
|
|
|
|
|
|
|
|
Loop bool // If true will restart reading of input after an io.EOF.
|
|
|
|
MinFPS uint // The reduced framerate of the video when there is no motion.
|
|
|
|
|
|
|
|
// MinFrames defines the frequency of key NAL units SPS, PPS and IDR in
|
|
|
|
// number of NAL units. This will also determine the frequency of PSI if the
|
|
|
|
// output container is MPEG-TS. If ClipDuration is less than MinFrames,
|
|
|
|
// ClipDuration will default to MinFrames.
|
|
|
|
MinFrames uint
|
|
|
|
|
|
|
|
MotionDownscaling uint // Downscaling factor of frames used for motion detection.
|
|
|
|
MotionHistory uint // Length of filter's history (KNN & MOG only).
|
|
|
|
MotionInterval uint // Sets the number of frames that are held before the filter is used (on the nth frame).
|
|
|
|
MotionKernel uint // Size of kernel used for filling holes and removing noise (KNN only).
|
|
|
|
MotionMinArea float64 // Used to ignore small areas of motion detection (KNN & MOG only).
|
|
|
|
MotionPadding uint // Number of frames to keep before and after motion detected.
|
|
|
|
MotionPixels uint // Number of pixels with motion that is needed for a whole frame to be considered as moving (Basic only).
|
|
|
|
MotionThreshold float64 // Intensity value that is considered motion.
|
|
|
|
|
|
|
|
// OutputPath defines the output destination for File output. This must be
|
|
|
|
// defined if File output is to be used.
|
|
|
|
OutputPath string
|
|
|
|
|
2019-05-13 09:42:08 +03:00
|
|
|
// Outputs define the outputs we wish to output data too.
|
|
|
|
//
|
|
|
|
// Valid outputs are defined by enums:
|
2021-01-20 04:19:01 +03:00
|
|
|
// OutputFile & OutputFiles:
|
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
|
|
|
|
|
2021-01-20 04:19:01 +03:00
|
|
|
PSITime uint // Sets the time between a packet being sent.
|
|
|
|
Quantization uint // Quantization defines the quantization level, which will determine variable bitrate quality in the case of input from the Pi Camera.
|
|
|
|
RBCapacity uint // The number of bytes the ring buffer will occupy.
|
|
|
|
RBStartElementSize uint // The starting element size of the ring buffer from which element size will increase to accomodate frames.
|
|
|
|
RBWriteTimeout uint // The ringbuffer write timeout in seconds.
|
|
|
|
RecPeriod float64 // How many seconds to record at a time.
|
|
|
|
Rotation uint // Rotation defines the video rotation angle in degrees Raspivid input.
|
|
|
|
RTMPURL string // RTMPURL specifies the Rtmp output destination URL. This must be defined if RTMP is to be used as an output.
|
|
|
|
RTPAddress string // RTPAddress defines the RTP output destination.
|
|
|
|
SampleRate uint // Samples a second (Hz).
|
|
|
|
Saturation int
|
|
|
|
|
2021-01-27 06:11:29 +03:00
|
|
|
// JPEGQuality is a value 0-100 inclusive, controlling JPEG compression of the
|
2021-01-20 04:19:01 +03:00
|
|
|
// timelapse snaps. 100 represents minimal compression and 0 represents the most
|
|
|
|
// compression.
|
2021-01-27 06:11:29 +03:00
|
|
|
JPEGQuality int
|
2021-01-20 04:19:01 +03:00
|
|
|
|
|
|
|
Suppress bool // Holds logger suppression state.
|
|
|
|
|
2021-01-27 06:11:29 +03:00
|
|
|
// TimelapseInterval defines the interval between timelapse images when using
|
2021-01-20 04:19:01 +03:00
|
|
|
// raspistill input.
|
|
|
|
TimelapseInterval time.Duration
|
|
|
|
|
|
|
|
// TimelapseDuration defines the duration of timelapse i.e. duration over
|
|
|
|
// which all snaps are taken, when using raspistill input.
|
|
|
|
TimelapseDuration time.Duration
|
|
|
|
|
|
|
|
VBRBitrate uint // VBRBitrate describes maximal variable bitrate.
|
2019-05-13 10:25:20 +03:00
|
|
|
|
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
|
|
|
|
2020-08-14 05:02:32 +03:00
|
|
|
VerticalFlip bool // VerticalFlip flips video vertically for Raspivid input.
|
|
|
|
Width uint // Width defines the input video width Raspivid input.
|
2019-05-13 09:12:16 +03:00
|
|
|
}
|
|
|
|
|
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 {
|
2020-05-19 09:02:02 +03:00
|
|
|
for _, v := range Variables {
|
|
|
|
if v.Validate != nil {
|
|
|
|
v.Validate(c)
|
2019-05-09 05:41:02 +03:00
|
|
|
}
|
2018-02-10 10:08:14 +03:00
|
|
|
}
|
2020-05-19 09:02:02 +03:00
|
|
|
return nil
|
|
|
|
}
|
2018-02-10 10:08:14 +03:00
|
|
|
|
2020-05-19 09:02:02 +03:00
|
|
|
// Update takes a map of configuration variable names and their corresponding
|
|
|
|
// values, parses the string values and converting into correct type, and then
|
|
|
|
// sets the config struct fields as appropriate.
|
|
|
|
func (c *Config) Update(vars map[string]string) {
|
|
|
|
for _, value := range Variables {
|
|
|
|
if v, ok := vars[value.Name]; ok && value.Update != nil {
|
|
|
|
value.Update(c, v)
|
2018-06-08 03:02:13 +03:00
|
|
|
}
|
2018-11-25 15:40:38 +03:00
|
|
|
}
|
2018-02-10 10:08:14 +03:00
|
|
|
}
|
2019-03-15 09:54:29 +03:00
|
|
|
|
2020-02-06 02:12:12 +03:00
|
|
|
func (c *Config) LogInvalidField(name string, def interface{}) {
|
2020-03-27 17:34:02 +03:00
|
|
|
c.Logger.Log(logger.Info, name+" bad or unset, defaulting", name, def)
|
2020-01-28 08:38:26 +03:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|