/* NAME Config.go AUTHORS Saxon A. Nelson-Milton Trek Hopton LICENSE Config.go is Copyright (C) 2017-2018 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 contains the configuration settings for revid. package config import ( "time" "bitbucket.org/ausocean/utils/logger" ) type Logger interface { SetLevel(int8) Log(level int8, message string, params ...interface{}) 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{}) } // Enums to define inputs, outputs and codecs. const ( // Indicates no option has been set. NothingDefined = iota // Input/Output. InputFile InputRaspivid InputRaspistill InputV4L InputRTSP InputAudio // Outputs. OutputRTMP OutputRTP OutputHTTP OutputMPEGTS OutputFile OutputFiles // Codecs. H264 H265 MJPEG JPEG ) // Quality represents video quality. 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 ) // The different media filters. const ( FilterNoOp = iota FilterMOG FilterVariableFPS FilterKNN FilterDiff FilterBasic ) // Config provides parameters relevant to a revid instance. A new config must // be passed to the constructor. Default values for these fields are defined // as consts above. type Config struct { // 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 // AWBGains sets the blue and red channel gains of an image/video capture device. AWBGains 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 // Contrast is the contrast of captured video/images from a capture device. Contrast 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 // EV is the exposure value for image/video capture devices. EV int 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 // Input defines the input data source. // // Valid values are defined by enums: // InputRaspivid: // Use raspivid utility to capture video from Raspberry Pi Camera. // InputRaspistill: // Use raspistill utility to capture images from the Raspberry Pi Camera. // InputV4l: // Read from webcam. // InputFile: // Read h.264 bytestream from a file. // Location must be specified in InputPath field. // InputRTSP: // Read from a camera supporting RTSP communication. // CameraIP should also be defined. // InputAudio: // Read from a ALSA audio source. Input uint8 // 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. InputCodec uint8 // InputPath defines the input file location for File Input. This must be // defined if File input is to be used. InputPath string // ISO sets the image/video capture device's sensitivity to light. ISO uint // 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 // Outputs define the outputs we wish to output data too. // // Valid outputs are defined by enums: // OutputFile & OutputFiles: // Location must be defined by the OutputPath field. MPEG-TS packetization // is used. // OutputHTTP: // Destination is defined by the sh field located in /etc/netsender.conf. // MPEGT-TS packetization is used. // OutputRTMP: // Destination URL must be defined in the RtmpUrl field. FLV packetization // is used. // OutputRTP: // Destination is defined by RtpAddr field, otherwise it will default to // localhost:6970. MPEGT-TS packetization is used. Outputs []uint8 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 // Sharpness is the sharpness of capture image/video from a capture device. Sharpness int // JPEGQuality is a value 0-100 inclusive, controlling JPEG compression of the // timelapse snaps. 100 represents minimal compression and 0 represents the most // compression. JPEGQuality int Suppress bool // Holds logger suppression state. // TimelapseInterval defines the interval between timelapse images when using // 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. // 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. VBRQuality Quality VerticalFlip bool // VerticalFlip flips video vertically for Raspivid input. Width uint // Width defines the input video width Raspivid input. } // Validate checks for any errors in the config fields and defaults settings // if particular parameters have not been defined. func (c *Config) Validate() error { for _, v := range Variables { if v.Validate != nil { v.Validate(c) } } return nil } // 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) } } } func (c *Config) LogInvalidField(name string, def interface{}) { c.Logger.Log(logger.Info, name+" bad or unset, defaulting", name, def) } func stringInSlice(want string, slice []string) bool { for _, s := range slice { if s == want { return true } } return false }