av/revid/config.go

262 lines
6.9 KiB
Go
Raw Normal View History

/*
NAME
Config.go
DESCRIPTION
See Readme.md
AUTHORS
2018-06-07 14:50:57 +03:00
Saxon A. Nelson-Milton <saxon@ausocean.org>
LICENSE
2018-06-08 03:02:13 +03:00
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
2018-06-07 14:50:57 +03:00
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
*/
2018-02-10 10:08:14 +03:00
package revid
import (
"errors"
"bitbucket.org/ausocean/utils/logger"
)
2018-02-10 10:08:14 +03:00
// Config provides parameters relevant to a revid instance. A new config must
// be passed to the constructor.
type Config struct {
LogLevel int8
Input uint8
InputCodec uint8
Outputs []uint8
RtmpMethod uint8
Packetization uint8
// Quantize specifies whether the input to
// revid will have constant or variable
// bitrate.
Quantize bool
// FlipHorizonatla and FlipVertical specify
// whether video frames should be flipped.
FlipHorizontal bool
FlipVertical bool
FramesPerClip uint
2018-02-10 10:08:14 +03:00
RtmpUrl string
Bitrate uint
OutputPath string
InputPath string
Height uint
Width uint
FrameRate uint
2018-02-10 10:08:14 +03:00
HttpAddress string
Quantization uint
IntraRefreshPeriod uint
RtpAddress string
Logger Logger
2018-12-14 13:20:26 +03:00
SendRetry bool
BurstPeriod uint
Rotation uint
2018-02-10 10:08:14 +03:00
}
// Enums for config struct
const (
2018-06-07 14:50:57 +03:00
NothingDefined = iota
Raspivid
V4L
2018-06-07 14:50:57 +03:00
H264Codec
File
Http
H264
Mjpeg
None
Mpegts
Ffmpeg
Flv
LibRtmp
QuantizationOn
QuantizationOff
Yes
No
Rtmp
FfmpegRtmp
Udp
MpegtsRtp
Rtp
2018-02-10 10:08:14 +03:00
)
// Default config settings
const (
2018-05-06 11:38:45 +03:00
defaultInput = Raspivid
2018-06-08 03:02:13 +03:00
defaultOutput = Http
2018-05-06 11:38:45 +03:00
defaultPacketization = Flv
defaultFrameRate = 25
defaultWidth = 1280
defaultHeight = 720
defaultIntraRefreshPeriod = 100
defaultTimeout = 0
defaultQuantization = 40
defaultBitrate = 400000
defaultQuantizationMode = QuantizationOff
2018-06-20 08:08:34 +03:00
defaultFramesPerClip = 1
httpFramesPerClip = 560
defaultInputCodec = H264
defaultVerbosity = No // FIXME(kortschak): This makes no sense whatsoever. No is currently 15.
defaultRtpAddr = "localhost:6970"
defaultBurstPeriod = 10 // Seconds
defaultRotation = 0 // Degrees
2018-02-10 10:08:14 +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.
2018-06-09 05:01:21 +03:00
func (c *Config) Validate(r *Revid) error {
switch c.LogLevel {
case Yes:
case No:
case NothingDefined:
c.LogLevel = defaultVerbosity
c.Logger.Log(logger.Info, pkg+"no LogLevel mode defined, defaulting",
"LogLevel", defaultVerbosity)
default:
return errors.New("bad LogLevel defined in config")
}
2018-06-09 05:01:21 +03:00
switch c.Input {
case Raspivid, V4L, File:
2018-02-10 10:08:14 +03:00
case NothingDefined:
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:
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 {
2018-02-10 10:08:14 +03:00
case H264:
// FIXME(kortschak): This is not really what we want.
// Configuration really needs to be rethought here.
if c.Quantize && c.Quantization == 0 {
c.Quantization = defaultQuantization
2018-02-10 10:08:14 +03:00
}
if (c.Bitrate > 0 && c.Quantize) || (c.Bitrate == 0 && !c.Quantize) {
return errors.New("bad bitrate and quantization combination for H264 input")
}
2018-02-10 10:08:14 +03:00
case Mjpeg:
if c.Quantization > 0 || c.Bitrate == 0 {
return errors.New("bad bitrate or quantization for mjpeg input")
2018-02-10 10:08:14 +03:00
}
2018-02-10 10:08:14 +03:00
case NothingDefined:
c.Logger.Log(logger.Info, pkg+"no input codec defined, defaulting",
"inputCodec", defaultInputCodec)
c.InputCodec = defaultInputCodec
c.Logger.Log(logger.Info, pkg+"defaulting quantization", "quantization",
defaultQuantization)
2018-06-09 05:01:21 +03:00
c.Quantization = defaultQuantization
2018-02-10 10:08:14 +03:00
default:
return errors.New("bad input codec defined in config")
2018-02-10 10:08:14 +03:00
}
for i, o := range c.Outputs {
switch o {
case File:
case Udp:
case Rtmp, FfmpegRtmp:
if c.RtmpUrl == "" {
c.Logger.Log(logger.Info, pkg+"no RTMP URL: falling back to HTTP")
c.Outputs[i] = Http
// FIXME(kortschak): Does this want the same line as below?
// c.FramesPerClip = httpFramesPerClip
break
}
c.Logger.Log(logger.Info, pkg+"defaulting frames per clip for rtmp out",
"framesPerClip", defaultFramesPerClip)
c.FramesPerClip = defaultFramesPerClip
c.Packetization = Flv
c.SendRetry = true
case NothingDefined:
c.Logger.Log(logger.Info, pkg+"no output defined, defaulting", "output",
defaultOutput)
c.Outputs[i] = defaultOutput
c.Packetization = defaultPacketization
fallthrough
case Http, Rtp:
c.Logger.Log(logger.Info, pkg+"defaulting frames per clip for http out",
"framesPerClip", httpFramesPerClip)
c.FramesPerClip = httpFramesPerClip
c.Packetization = Mpegts
default:
return errors.New("bad output type defined in config")
2018-06-08 03:02:13 +03:00
}
}
if c.BurstPeriod == 0 {
c.Logger.Log(logger.Info, pkg+"no burst period defined, defaulting", "burstPeriod", defaultBurstPeriod)
c.BurstPeriod = defaultBurstPeriod
}
2018-06-20 08:08:34 +03:00
if c.FramesPerClip < 1 {
c.Logger.Log(logger.Info, pkg+"no FramesPerClip defined, defaulting",
"framesPerClip", defaultFramesPerClip)
2018-06-13 08:15:03 +03:00
c.FramesPerClip = defaultFramesPerClip
2018-02-10 10:08:14 +03:00
}
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)
2018-06-09 05:01:21 +03:00
c.Width = defaultWidth
2018-02-10 10:08:14 +03:00
}
if c.Height == 0 {
c.Logger.Log(logger.Info, pkg+"no height defined, defaulting", "height", defaultHeight)
2018-06-09 05:01:21 +03:00
c.Height = defaultHeight
2018-02-10 10:08:14 +03:00
}
if c.FrameRate == 0 {
c.Logger.Log(logger.Info, pkg+"no frame rate defined, defaulting", "fps", defaultFrameRate)
2018-06-09 05:01:21 +03:00
c.FrameRate = defaultFrameRate
2018-02-10 10:08:14 +03:00
}
if c.Bitrate == 0 {
c.Logger.Log(logger.Info, pkg+"no bitrate defined, defaulting", "bitrate", defaultBitrate)
2018-06-09 05:01:21 +03:00
c.Bitrate = defaultBitrate
2018-02-10 10:08:14 +03:00
}
if c.IntraRefreshPeriod == 0 {
c.Logger.Log(logger.Info, pkg+"no intra refresh defined, defaulting", "intraRefresh", defaultIntraRefreshPeriod)
2018-06-09 05:01:21 +03:00
c.IntraRefreshPeriod = defaultIntraRefreshPeriod
2018-02-10 10:08:14 +03:00
}
if c.Quantization == 0 {
c.Logger.Log(logger.Info, pkg+"no quantization defined, defaulting", "quantization", defaultQuantization)
2018-06-09 05:01:21 +03:00
c.Quantization = defaultQuantization
} else if c.Quantization > 51 {
return errors.New("quantisation is over threshold")
2018-02-10 10:08:14 +03:00
}
if c.RtpAddress == "" {
c.RtpAddress = defaultRtpAddr
}
return nil
2018-02-10 10:08:14 +03:00
}