av/revid/config.go

313 lines
8.7 KiB
Go

/*
NAME
Config.go
DESCRIPTION
See Readme.md
AUTHORS
Saxon A. Nelson-Milton <saxon@ausocean.org>
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 revid
import (
"errors"
"strconv"
"bitbucket.org/ausocean/utils/smartlogger"
)
// Config provides parameters relevant to a revid instance. A new config must
// be passed to the constructor.
type Config struct {
Input uint8
InputCodec uint8
Output uint8
RtmpMethod uint8
Packetization uint8
QuantizationMode uint8
Verbosity int8
HorizontalFlip uint8
VerticalFlip uint8
FramesPerClip int
RtmpUrl string
Bitrate string
OutputFileName string
InputFileName string
Height string
Width string
FrameRate string
HttpAddress string
Quantization string
Timeout string
IntraRefreshPeriod string
Logger Logger
}
// Enums for config struct
const (
NothingDefined = iota
Raspivid
H264Codec
File
Http
H264
Mjpeg
None
Mpegts
Ffmpeg
Flv
LibRtmp
QuantizationOn
QuantizationOff
Yes
No
Rtmp
FfmpegRtmp
)
// Default config settings
const (
defaultInput = Raspivid
defaultOutput = Http
defaultPacketization = Flv
defaultFrameRate = "25"
defaultWidth = "1280"
defaultHeight = "720"
defaultIntraRefreshPeriod = "100"
defaultTimeout = "0"
defaultQuantization = "40"
defaultBitrate = "500000"
defaultQuantizationMode = QuantizationOff
defaultFramesPerClip = 1
defaultVerticalFlip = No
defaultHorizontalFlip = No
httpFramesPerClip = 7
defaultInputCodec = H264
defaultVerbosity = No
)
// Validate checks for any errors in the config fields and defaults settings
// if particular parameters have not been defined.
func (c *Config) Validate(r *Revid) error {
switch c.Verbosity {
case Yes:
case No:
case NothingDefined:
c.Verbosity = defaultVerbosity
c.Logger.Log(smartlogger.Warning, pkg+"No verbosity mode defined, defaulting",
"verbosity", defaultVerbosity)
default:
return errors.New("Bad Verbosity defined in config!")
}
switch c.QuantizationMode {
case QuantizationOn:
case QuantizationOff:
case NothingDefined:
c.Logger.Log(smartlogger.Warning, pkg+"No quantization mode defined, defaulting",
"quantizationMode", QuantizationOff)
c.QuantizationMode = QuantizationOff
default:
return errors.New("Bad QuantizationMode defined in config!")
}
switch c.Input {
case Raspivid:
case File:
case NothingDefined:
c.Logger.Log(smartlogger.Warning, pkg+"No input type defined, defaulting", "input",
defaultInput)
c.Input = defaultInput
default:
return errors.New("Bad input type defined in config!")
}
switch c.InputCodec {
case H264:
if c.Bitrate != "" && c.Quantization != "" {
bitrate, err := strconv.Atoi(c.Bitrate)
if err != nil {
return errors.New("Something is wrong with bitrate in conig!")
}
quantization, err := strconv.Atoi(c.Quantization)
if err != nil {
return errors.New("Something is wrong with quantization in config!")
}
if (bitrate > 0 && quantization > 0) || (bitrate == 0 && quantization == 0) {
return errors.New("Bad bitrate and quantization combination for H264 input!")
}
}
case Mjpeg:
if c.Quantization != "" {
quantization, err := strconv.Atoi(c.Quantization)
if err != nil {
return errors.New("Something is wrong with quantization in config!")
}
if quantization > 0 || c.Bitrate == "" {
return errors.New("Bad bitrate or quantization for mjpeg input!")
}
}
case NothingDefined:
c.Logger.Log(smartlogger.Warning, pkg+"No input codec defined, defaulting",
"inputCodec", defaultInputCodec)
c.InputCodec = defaultInputCodec
c.Logger.Log(smartlogger.Warning, pkg+"Defaulting quantization", "quantization",
defaultQuantization)
c.Quantization = defaultQuantization
default:
return errors.New("Bad input codec defined in config!")
}
switch c.Output {
case File:
case Rtmp, FfmpegRtmp:
if c.RtmpUrl == "" {
c.Logger.Log(smartlogger.Info, pkg+"No RTMP URL: falling back to HTTP")
c.Output = Http
break
}
c.Logger.Log(smartlogger.Info, pkg+"Defaulting frames per clip for rtmp out",
"framesPerClip", defaultFramesPerClip)
c.FramesPerClip = defaultFramesPerClip
case NothingDefined:
c.Logger.Log(smartlogger.Warning, pkg+"No output defined, defaulting", "output",
defaultOutput)
c.Output = defaultOutput
fallthrough
case Http:
c.Logger.Log(smartlogger.Info, pkg+"Defaulting frames per clip for http out",
"framesPerClip", httpFramesPerClip)
c.FramesPerClip = httpFramesPerClip
default:
return errors.New("Bad output type defined in config!")
}
switch c.Packetization {
case None:
case Mpegts:
case Flv:
case NothingDefined:
c.Logger.Log(smartlogger.Warning, pkg+"No packetization option defined, defaulting",
"packetization", defaultPacketization)
c.Packetization = defaultPacketization
default:
return errors.New("Bad packetization option defined in config!")
}
switch c.HorizontalFlip {
case Yes:
case No:
case NothingDefined:
c.Logger.Log(smartlogger.Warning, pkg+"No horizontal flip option defined, defaulting",
"horizontalFlip", defaultHorizontalFlip)
c.HorizontalFlip = defaultHorizontalFlip
default:
return errors.New("Bad horizontal flip option defined in config!")
}
switch c.VerticalFlip {
case Yes:
case No:
case NothingDefined:
c.Logger.Log(smartlogger.Warning, pkg+"No vertical flip option defined, defaulting",
"verticalFlip", defaultVerticalFlip)
c.VerticalFlip = defaultVerticalFlip
default:
return errors.New("Bad vertical flip option defined in config!")
}
if c.FramesPerClip < 1 {
c.Logger.Log(smartlogger.Warning, pkg+"No FramesPerClip defined, defaulting",
"framesPerClip", defaultFramesPerClip)
c.FramesPerClip = defaultFramesPerClip
}
if c.Width == "" {
c.Logger.Log(smartlogger.Warning, pkg+"No width defined, defaulting", "width",
defaultWidth)
c.Width = defaultWidth
} else {
if integer, err := strconv.Atoi(c.Width); integer < 0 || err != nil {
return errors.New("Bad width defined in config!")
}
}
if c.Height == "" {
c.Logger.Log(smartlogger.Warning, pkg+"No height defined, defaulting", "height",
defaultHeight)
c.Height = defaultHeight
} else {
if integer, err := strconv.Atoi(c.Height); integer < 0 || err != nil {
return errors.New("Bad height defined in config!")
}
}
if c.FrameRate == "" {
c.Logger.Log(smartlogger.Warning, pkg+"No frame rate defined, defaulting", "fps",
defaultFrameRate)
c.FrameRate = defaultFrameRate
} else {
if integer, err := strconv.Atoi(c.FrameRate); integer < 0 || err != nil {
return errors.New("Bad frame rate defined in config!")
}
}
if c.Bitrate == "" {
c.Logger.Log(smartlogger.Warning, pkg+"No bitrate defined, defaulting", "bitrate",
defaultBitrate)
c.Bitrate = defaultBitrate
} else {
if integer, err := strconv.Atoi(c.Bitrate); integer < 0 || err != nil {
return errors.New("Bad bitrate defined in config!")
}
}
if c.Timeout == "" {
c.Logger.Log(smartlogger.Warning, pkg+"No timeout defined, defaulting", "timeout", defaultTimeout)
c.Timeout = defaultTimeout
} else {
if integer, err := strconv.Atoi(c.Timeout); integer < 0 || err != nil {
return errors.New("Bad timeout defined in config!")
}
}
if c.IntraRefreshPeriod == "" {
c.Logger.Log(smartlogger.Warning, pkg+"No intra refresh defined, defaulting", "intraRefresh",
defaultIntraRefreshPeriod)
c.IntraRefreshPeriod = defaultIntraRefreshPeriod
} else {
if integer, err := strconv.Atoi(c.IntraRefreshPeriod); integer < 0 || err != nil {
return errors.New("Bad intra refresh defined in config!")
}
}
if c.Quantization == "" {
c.Logger.Log(smartlogger.Warning, pkg+"No quantization defined, defaulting", "quantization",
defaultQuantization)
c.Quantization = defaultQuantization
} else {
if integer, err := strconv.Atoi(c.Quantization); integer < 0 || integer > 51 || err != nil {
return errors.New("Bad quantization defined in config!")
}
}
return nil
}