mirror of https://bitbucket.org/ausocean/av.git
revid/config/config.go & config_test.go: simplified config and its validation
Not that alot of configuration is done by the device implementations, including validation, we can remove alot of this from the config package here.
This commit is contained in:
parent
866e398496
commit
0a059058a1
|
@ -33,36 +33,6 @@ import (
|
||||||
"bitbucket.org/ausocean/utils/logger"
|
"bitbucket.org/ausocean/utils/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Possible modes for raspivid --exposure parameter.
|
|
||||||
var ExposureModes = [...]string{
|
|
||||||
"auto",
|
|
||||||
"night",
|
|
||||||
"nightpreview",
|
|
||||||
"backlight",
|
|
||||||
"spotlight",
|
|
||||||
"sports",
|
|
||||||
"snow",
|
|
||||||
"beach",
|
|
||||||
"verylong",
|
|
||||||
"fixedfps",
|
|
||||||
"antishake",
|
|
||||||
"fireworks",
|
|
||||||
}
|
|
||||||
|
|
||||||
// Possible modes for raspivid --awb parameter.
|
|
||||||
var AutoWhiteBalanceModes = [...]string{
|
|
||||||
"off",
|
|
||||||
"auto",
|
|
||||||
"sun",
|
|
||||||
"cloud",
|
|
||||||
"shade",
|
|
||||||
"tungsten",
|
|
||||||
"fluorescent",
|
|
||||||
"incandescent",
|
|
||||||
"flash",
|
|
||||||
"horizon",
|
|
||||||
}
|
|
||||||
|
|
||||||
const pkg = "config: "
|
const pkg = "config: "
|
||||||
|
|
||||||
type Logger interface {
|
type Logger interface {
|
||||||
|
@ -70,19 +40,6 @@ type Logger interface {
|
||||||
Log(level int8, message string, params ...interface{})
|
Log(level int8, message string, params ...interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|
||||||
)
|
|
||||||
|
|
||||||
// Enums to define inputs, outputs and codecs.
|
// Enums to define inputs, outputs and codecs.
|
||||||
const (
|
const (
|
||||||
// Indicates no option has been set.
|
// Indicates no option has been set.
|
||||||
|
@ -114,37 +71,16 @@ const (
|
||||||
// General revid defaults.
|
// General revid defaults.
|
||||||
defaultInput = InputRaspivid
|
defaultInput = InputRaspivid
|
||||||
defaultOutput = OutputHTTP
|
defaultOutput = OutputHTTP
|
||||||
defaultFrameRate = 25
|
|
||||||
defaultWriteRate = 25
|
defaultWriteRate = 25
|
||||||
defaultTimeout = 0
|
defaultTimeout = 0
|
||||||
defaultInputCodec = codecutil.H264
|
defaultInputCodec = codecutil.H264
|
||||||
defaultVerbosity = logger.Error
|
defaultVerbosity = logger.Error
|
||||||
defaultRtpAddr = "localhost:6970"
|
defaultRtpAddr = "localhost:6970"
|
||||||
defaultCameraIP = "192.168.1.50"
|
defaultCameraIP = "192.168.1.50"
|
||||||
defaultVBR = false
|
|
||||||
defaultVBRQuality = QualityStandard
|
|
||||||
defaultBurstPeriod = 10 // Seconds
|
defaultBurstPeriod = 10 // Seconds
|
||||||
defaultVBRBitrate = 500 // kbps
|
|
||||||
defaultCameraChan = 2
|
|
||||||
|
|
||||||
// Raspivid video defaults.
|
|
||||||
defaultBrightness = 50
|
|
||||||
defaultExposure = "auto"
|
|
||||||
defaultAutoWhiteBalance = "auto"
|
|
||||||
defaultRotation = 0 // Degrees
|
|
||||||
defaultWidth = 1280
|
|
||||||
defaultHeight = 720
|
|
||||||
defaultMinFrames = 100
|
defaultMinFrames = 100
|
||||||
defaultClipDuration = 0
|
defaultClipDuration = 0
|
||||||
defaultQuantization = 30
|
|
||||||
defaultBitrate = 400
|
|
||||||
|
|
||||||
// Audio defaults.
|
|
||||||
defaultAudioInputCodec = codecutil.ADPCM
|
defaultAudioInputCodec = codecutil.ADPCM
|
||||||
defaultSampleRate = 48000
|
|
||||||
defaultBitDepth = 16
|
|
||||||
defaultChannels = 1
|
|
||||||
defaultRecPeriod = 1.0
|
|
||||||
|
|
||||||
// MTS ring buffer defaults.
|
// MTS ring buffer defaults.
|
||||||
defaultMTSRBSize = 100
|
defaultMTSRBSize = 100
|
||||||
|
@ -157,6 +93,19 @@ const (
|
||||||
defaultRTMPRBWriteTimeout = 5
|
defaultRTMPRBWriteTimeout = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
)
|
||||||
|
|
||||||
// Config provides parameters relevant to a revid instance. A new config must
|
// Config provides parameters relevant to a revid instance. A new config must
|
||||||
// be passed to the constructor. Default values for these fields are defined
|
// be passed to the constructor. Default values for these fields are defined
|
||||||
// as consts above.
|
// as consts above.
|
||||||
|
@ -352,8 +301,6 @@ func (c *Config) Validate() error {
|
||||||
default:
|
default:
|
||||||
c.Logger.Log(logger.Info, pkg+"no input codec defined, defaulting", "inputCodec", defaultInputCodec)
|
c.Logger.Log(logger.Info, pkg+"no input codec defined, defaulting", "inputCodec", defaultInputCodec)
|
||||||
c.InputCodec = defaultInputCodec
|
c.InputCodec = defaultInputCodec
|
||||||
c.Logger.Log(logger.Info, pkg+"defaulting quantization", "quantization", defaultQuantization)
|
|
||||||
c.Quantization = defaultQuantization
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,29 +309,15 @@ func (c *Config) Validate() error {
|
||||||
c.Outputs = append(c.Outputs, defaultOutput)
|
c.Outputs = append(c.Outputs, defaultOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
var haveRTMPOut bool
|
|
||||||
for i, o := range c.Outputs {
|
for i, o := range c.Outputs {
|
||||||
switch o {
|
switch o {
|
||||||
case OutputFile:
|
case OutputFile, OutputHTTP, OutputRTP:
|
||||||
case OutputRTMP:
|
case OutputRTMP:
|
||||||
haveRTMPOut = true
|
|
||||||
if c.Bitrate == 0 {
|
|
||||||
c.Bitrate = defaultBitrate
|
|
||||||
}
|
|
||||||
c.Quantization = 0
|
|
||||||
if c.RTMPURL == "" {
|
if c.RTMPURL == "" {
|
||||||
c.Logger.Log(logger.Info, pkg+"no RTMP URL: falling back to HTTP")
|
c.Logger.Log(logger.Info, pkg+"no RTMP URL: falling back to HTTP")
|
||||||
c.Outputs[i] = OutputHTTP
|
c.Outputs[i] = OutputHTTP
|
||||||
haveRTMPOut = false
|
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case OutputHTTP, OutputRTP:
|
|
||||||
if !haveRTMPOut {
|
|
||||||
c.Bitrate = 0
|
|
||||||
if c.Quantization == 0 {
|
|
||||||
c.Quantization = defaultQuantization
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return errors.New("bad output type defined in config")
|
return errors.New("bad output type defined in config")
|
||||||
}
|
}
|
||||||
|
@ -395,55 +328,6 @@ func (c *Config) Validate() error {
|
||||||
c.BurstPeriod = defaultBurstPeriod
|
c.BurstPeriod = defaultBurstPeriod
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Rotation > 359 {
|
|
||||||
c.Logger.Log(logger.Warning, pkg+"bad rotate angle, defaulting", "angle", defaultRotation)
|
|
||||||
c.Rotation = defaultRotation
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Width == 0 {
|
|
||||||
c.Logger.Log(logger.Info, pkg+"no width defined, defaulting", "width", defaultWidth)
|
|
||||||
c.Width = defaultWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Height == 0 {
|
|
||||||
c.Logger.Log(logger.Info, pkg+"no height defined, defaulting", "height", defaultHeight)
|
|
||||||
c.Height = defaultHeight
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.FrameRate == 0 {
|
|
||||||
c.Logger.Log(logger.Info, pkg+"no frame rate defined, defaulting", "fps", defaultFrameRate)
|
|
||||||
c.FrameRate = defaultFrameRate
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.SampleRate == 0 {
|
|
||||||
c.Logger.Log(logger.Info, pkg+"no sample rate defined, defaulting", "sampleRate", defaultSampleRate)
|
|
||||||
c.SampleRate = defaultSampleRate
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Channels == 0 {
|
|
||||||
c.Logger.Log(logger.Info, pkg+"no number of channels defined, defaulting", "Channels", defaultChannels)
|
|
||||||
c.Channels = defaultChannels
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.BitDepth == 0 {
|
|
||||||
c.Logger.Log(logger.Info, pkg+"no bit depth defined, defaulting", "BitDepth", defaultBitDepth)
|
|
||||||
c.BitDepth = defaultBitDepth
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.RecPeriod == 0 {
|
|
||||||
c.Logger.Log(logger.Info, pkg+"no record period defined, defaulting", "recPeriod", defaultRecPeriod)
|
|
||||||
c.RecPeriod = defaultRecPeriod
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.WriteRate == 0 {
|
|
||||||
c.Logger.Log(logger.Info, pkg+"no write rate defined, defaulting", "writeRate", defaultWriteRate)
|
|
||||||
c.WriteRate = defaultWriteRate
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Bitrate < 0 {
|
|
||||||
return errors.New("invalid bitrate")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.MinFrames == 0 {
|
if c.MinFrames == 0 {
|
||||||
c.Logger.Log(logger.Info, pkg+"no min period defined, defaulting", "MinFrames", defaultMinFrames)
|
c.Logger.Log(logger.Info, pkg+"no min period defined, defaulting", "MinFrames", defaultMinFrames)
|
||||||
c.MinFrames = defaultMinFrames
|
c.MinFrames = defaultMinFrames
|
||||||
|
@ -458,42 +342,10 @@ func (c *Config) Validate() error {
|
||||||
return errors.New("clip duration is less than 0")
|
return errors.New("clip duration is less than 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Quantization != 0 && (c.Quantization < 10 || c.Quantization > 40) {
|
|
||||||
return errInvalidQuantization
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.RTPAddress == "" {
|
if c.RTPAddress == "" {
|
||||||
c.RTPAddress = defaultRtpAddr
|
c.RTPAddress = defaultRtpAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
|
||||||
case c.Brightness == 0:
|
|
||||||
c.Logger.Log(logger.Info, pkg+"brightness undefined, defaulting", "brightness", defaultBrightness)
|
|
||||||
c.Brightness = defaultBrightness
|
|
||||||
case c.Brightness < 0 || c.Brightness > 100:
|
|
||||||
return errors.New(pkg + "bad brightness defined in config")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Saturation < -100 || c.Saturation > 100 {
|
|
||||||
return errors.New(pkg + "bad saturation setting in config")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case c.Exposure == "":
|
|
||||||
c.Logger.Log(logger.Info, pkg+"exposure undefined, defaulting", "exposure", defaultExposure)
|
|
||||||
c.Exposure = defaultExposure
|
|
||||||
case !stringInSlice(c.Exposure, ExposureModes[:]):
|
|
||||||
return errors.New(pkg + "bad exposure setting in config")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case c.AutoWhiteBalance == "":
|
|
||||||
c.Logger.Log(logger.Info, pkg+"auto white balance undefined, defaulting", "autoWhiteBalance", defaultAutoWhiteBalance)
|
|
||||||
c.AutoWhiteBalance = defaultAutoWhiteBalance
|
|
||||||
case !stringInSlice(c.AutoWhiteBalance, AutoWhiteBalanceModes[:]):
|
|
||||||
return errors.New(pkg + "bad auto white balance setting in config")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.RTMPRBSize <= 0 {
|
if c.RTMPRBSize <= 0 {
|
||||||
c.Logger.Log(logger.Info, pkg+"RTMPRBSize bad or unset, defaulting", "RTMPRBSize", defaultRTMPRBSize)
|
c.Logger.Log(logger.Info, pkg+"RTMPRBSize bad or unset, defaulting", "RTMPRBSize", defaultRTMPRBSize)
|
||||||
c.RTMPRBSize = defaultRTMPRBSize
|
c.RTMPRBSize = defaultRTMPRBSize
|
||||||
|
@ -524,23 +376,6 @@ func (c *Config) Validate() error {
|
||||||
c.MTSRBWriteTimeout = defaultMTSRBWriteTimeout
|
c.MTSRBWriteTimeout = defaultMTSRBWriteTimeout
|
||||||
}
|
}
|
||||||
|
|
||||||
switch c.VBRQuality {
|
|
||||||
case QualityStandard, QualityFair, QualityGood, QualityGreat, QualityExcellent:
|
|
||||||
default:
|
|
||||||
c.Logger.Log(logger.Info, pkg+"VBRQuality bad or unset, defaulting", "VBRQuality", defaultVBRQuality)
|
|
||||||
c.VBRQuality = defaultVBRQuality
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.VBRBitrate <= 0 {
|
|
||||||
c.Logger.Log(logger.Info, pkg+"VBRBitrate bad or unset, defaulting", "VBRBitrate", defaultVBRBitrate)
|
|
||||||
c.VBRBitrate = defaultVBRBitrate
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.CameraChan != 1 && c.CameraChan != 2 {
|
|
||||||
c.Logger.Log(logger.Info, pkg+"CamChan bad or unset, defaulting", "CamChan", defaultCameraChan)
|
|
||||||
c.CameraChan = defaultCameraChan
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,30 +40,6 @@ func TestValidate(t *testing.T) {
|
||||||
check func(c Config) error
|
check func(c Config) error
|
||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
{
|
|
||||||
in: Config{Outputs: []uint8{OutputHTTP}, Logger: &dumbLogger{}},
|
|
||||||
check: func(c Config) error {
|
|
||||||
if c.Bitrate != 0 {
|
|
||||||
return fmt.Errorf("did not get expected bitrate. Got: %v, Want: %v", c.Bitrate, 0)
|
|
||||||
}
|
|
||||||
if c.Quantization != defaultQuantization {
|
|
||||||
return fmt.Errorf("did not get expected quantization. Got: %v, Want: %v", c.Quantization, defaultQuantization)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
in: Config{Outputs: []uint8{OutputRTMP}, RTMPURL: "dummURL", Logger: &dumbLogger{}},
|
|
||||||
check: func(c Config) error {
|
|
||||||
if c.Bitrate != defaultBitrate {
|
|
||||||
return fmt.Errorf("did not get expected bitrate. Got: %v, Want: %v", c.Bitrate, defaultBitrate)
|
|
||||||
}
|
|
||||||
if c.Quantization != 0 {
|
|
||||||
return fmt.Errorf("did not get expected quantization. Got: %v, Want: %v", c.Quantization, 0)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
in: Config{Outputs: []uint8{OutputHTTP}, Quantization: 50, Logger: &dumbLogger{}},
|
in: Config{Outputs: []uint8{OutputHTTP}, Quantization: 50, Logger: &dumbLogger{}},
|
||||||
check: func(c Config) error { return nil },
|
check: func(c Config) error { return nil },
|
||||||
|
|
Loading…
Reference in New Issue