Merged in correct-config-types (pull request #401)

Correct types of fields in revid/config/config.go Config struct
This commit is contained in:
Saxon Milton 2020-05-02 03:55:13 +00:00
parent acb74e79f6
commit 4cf155bbc2
15 changed files with 115 additions and 109 deletions

View File

@ -143,17 +143,23 @@ func main() {
}
cf := pcm.BufferFormat{
SFormat: sf,
Channels: ab.Format.Channels,
Rate: ab.Format.Rate,
Channels: uint(ab.Format.Channels),
Rate: uint(ab.Format.Rate),
}
ac.pb = pcm.Buffer{
Format: cf,
Data: ab.Data,
}
cs := pcm.DataSize(ac.parameters.rate, ac.parameters.channels, ac.parameters.bits, float64(ac.parameters.period), 0)
cs := pcm.DataSize(
uint(ac.parameters.rate),
uint(ac.parameters.channels),
uint(ac.parameters.bits),
float64(ac.parameters.period),
0,
)
rbLen := rbDuration / ac.period
ac.rb = ring.NewBuffer(rbLen, cs, rbTimeout)
ac.rb = ring.NewBuffer(int(rbLen), cs, rbTimeout)
go ac.input()
@ -386,7 +392,7 @@ func (ac *audioClient) input() {
// This function also handles NetReceiver configuration requests and updating of NetReceiver vars.
func (ac *audioClient) output() {
// Calculate the size of the output data based on wanted channels and rate.
outLen := (((len(ac.pb.Data) / ac.pb.Format.Channels) * ac.channels) / ac.pb.Format.Rate) * ac.rate
outLen := (((len(ac.pb.Data) / int(ac.pb.Format.Channels)) * ac.channels) / int(ac.pb.Format.Rate)) * ac.rate
buf := make([]byte, outLen)
mime := "audio/x-wav;codec=pcm;rate=" + strconv.Itoa(ac.rate) + ";channels=" + strconv.Itoa(ac.channels) + ";bits=" + strconv.Itoa(ac.bits)
@ -533,13 +539,13 @@ func (ac *audioClient) formatBuffer() pcm.Buffer {
ac.mu.Unlock()
// If nothing needs to be changed, return the original.
if ac.pb.Format.Channels == wantChannels && ac.pb.Format.Rate == wantRate {
if int(ac.pb.Format.Channels) == wantChannels && int(ac.pb.Format.Rate) == wantRate {
return ac.pb
}
formatted := pcm.Buffer{Format: ac.pb.Format}
bufCopied := false
if ac.pb.Format.Channels != wantChannels {
if int(ac.pb.Format.Channels) != wantChannels {
// Convert channels.
if ac.pb.Format.Channels == 2 && wantChannels == 1 {
@ -552,18 +558,18 @@ func (ac *audioClient) formatBuffer() pcm.Buffer {
}
}
if ac.pb.Format.Rate != wantRate {
if int(ac.pb.Format.Rate) != wantRate {
// Convert rate.
if bufCopied {
formatted, err = pcm.Resample(formatted, wantRate)
formatted, err = pcm.Resample(formatted, uint(wantRate))
} else {
formatted, err = pcm.Resample(ac.pb, wantRate)
formatted, err = pcm.Resample(ac.pb, uint(wantRate))
}
if err != nil {
log.Log(logger.Warning, "rate conversion failed, audio has remained original rate", "error", err.Error())
} else {
formatted.Format.Rate = wantRate
formatted.Format.Rate = uint(wantRate)
}
}
return formatted

View File

@ -57,8 +57,8 @@ const (
// BufferFormat contains the format for a PCM Buffer.
type BufferFormat struct {
SFormat SampleFormat
Rate int
Channels int
Rate uint
Channels uint
}
// Buffer contains a buffer of PCM data and the format that it is in.
@ -68,7 +68,7 @@ type Buffer struct {
}
// DataSize takes audio attributes describing audio data and returns the size of that data.
func DataSize(rate, channels, bitDepth int, period float64, codec uint8) int {
func DataSize(rate, channels, bitDepth uint, period float64, codec uint8) int {
s := int(float64(channels) * float64(rate) * float64(bitDepth/8) * period)
if codec == codecutil.ADPCM {
s = adpcm.EncBytes(s)
@ -81,7 +81,7 @@ func DataSize(rate, channels, bitDepth int, period float64, codec uint8) int {
// - Currently only downsampling is implemented and c's rate must be divisible by 'rate' or an error will occur.
// - If the number of bytes in c.Data is not divisible by the decimation factor (ratioFrom), the remaining bytes will
// not be included in the result. Eg. input of length 480002 downsampling 6:1 will result in output length 80000.
func Resample(c Buffer, rate int) (Buffer, error) {
func Resample(c Buffer, rate uint) (Buffer, error) {
if c.Format.Rate == rate {
return c, nil
}
@ -96,9 +96,9 @@ func Resample(c Buffer, rate int) (Buffer, error) {
var sampleLen int
switch c.Format.SFormat {
case S32_LE:
sampleLen = 4 * c.Format.Channels
sampleLen = int(4 * c.Format.Channels)
case S16_LE:
sampleLen = 2 * c.Format.Channels
sampleLen = int(2 * c.Format.Channels)
default:
return Buffer{}, fmt.Errorf("Unhandled ALSA format: %v", c.Format.SFormat)
}
@ -106,8 +106,8 @@ func Resample(c Buffer, rate int) (Buffer, error) {
// Calculate sample rate ratio ratioFrom:ratioTo.
rateGcd := gcd(rate, c.Format.Rate)
ratioFrom := c.Format.Rate / rateGcd
ratioTo := rate / rateGcd
ratioFrom := int(c.Format.Rate / rateGcd)
ratioTo := int(rate / rateGcd)
// ratioTo = 1 is the only number that will result in an even sampling.
if ratioTo != 1 {
@ -197,7 +197,7 @@ func StereoToMono(c Buffer) (Buffer, error) {
// gcd is used for calculating the greatest common divisor of two positive integers, a and b.
// assumes given a and b are positive.
func gcd(a, b int) int {
func gcd(a, b uint) uint {
for b != 0 {
a, b = b, a%b
}

View File

@ -75,9 +75,9 @@ type ALSA struct {
// Config provides parameters used by the ALSA device.
type Config struct {
SampleRate int
Channels int
BitDepth int
SampleRate uint
Channels uint
BitDepth uint
RecPeriod float64
Codec uint8
}
@ -145,8 +145,8 @@ func (d *ALSA) Set(c config.Config) error {
}
cf := pcm.BufferFormat{
SFormat: sf,
Channels: ab.Format.Channels,
Rate: ab.Format.Rate,
Channels: uint(ab.Format.Channels),
Rate: uint(ab.Format.Rate),
}
d.pb = pcm.Buffer{
Format: cf,
@ -258,10 +258,10 @@ func (d *ALSA) open() error {
var rate int
foundRate := false
for r := range rates {
if r < d.SampleRate {
if r < int(d.SampleRate) {
continue
}
if r%d.SampleRate == 0 {
if r%int(d.SampleRate) == 0 {
rate, err = d.dev.NegotiateRate(r)
if err == nil {
foundRate = true

View File

@ -37,12 +37,12 @@ func main() {
var (
hostPtr = flag.String("host", "192.168.1.50", "IP of GeoVision camera.")
codecPtr = flag.String("codec", "", "h264, h265 or mjpeg")
heightPtr = flag.Int("height", 0, "256, 360 or 720")
fpsPtr = flag.Int("fps", 0, "Frame rate in frames per second.")
heightPtr = flag.Uint("height", 0, "256, 360 or 720")
fpsPtr = flag.Uint("fps", 0, "Frame rate in frames per second.")
vbrPtr = flag.Bool("vbr", false, "If true, variable bitrate.")
vbrQualityPtr = flag.Int("quality", -1, "General quality under variable bitrate, 0 to 4 inclusive.")
vbrRatePtr = flag.Int("vbr-rate", 0, "Variable bitrate maximal bitrate in kbps.")
cbrRatePtr = flag.Int("cbr-rate", 0, "Constant bitrate, bitrate in kbps.")
vbrRatePtr = flag.Uint("vbr-rate", 0, "Variable bitrate maximal bitrate in kbps.")
cbrRatePtr = flag.Uint("cbr-rate", 0, "Constant bitrate, bitrate in kbps.")
refreshPtr = flag.Float64("refresh", 0, "Inter refresh period in seconds.")
)
flag.Parse()

View File

@ -112,7 +112,7 @@ func Set(host string, options ...Option) error {
}
// Channel will set the GeoVision channel we will be using.
func Channel(c int) Option {
func Channel(c uint8) Option {
return func(s settings) (settings, error) {
if c != 1 && c != 2 {
return s, errors.New("invalid channel")
@ -146,15 +146,15 @@ func CodecOut(c Codec) Option {
// Height will set the height component of the video resolution. Available
// heights are 256, 360 and 720.
func Height(h int) Option {
func Height(h uint) Option {
return func(s settings) (settings, error) {
var m map[int]string
var m map[uint]string
switch s.ch {
case 1:
// TODO: add other resolutions supported by channel 1.
m = map[int]string{1080: res1080}
m = map[uint]string{1080: res1080}
case 2:
m = map[int]string{256: res256, 360: res360, 720: res720}
m = map[uint]string{256: res256, 360: res360, 720: res720}
}
v, ok := m[h]
if !ok {
@ -167,12 +167,12 @@ func Height(h int) Option {
// FrameRate will set the frame rate of the video. This value is defined in
// units of frames per second, and must be between 1 and 30 inclusive.
func FrameRate(f int) Option {
func FrameRate(f uint) Option {
return func(s settings) (settings, error) {
if 1 > f || f > 30 {
return s, fmt.Errorf("invalid frame rate: %d", f)
}
s.frameRate = strconv.Itoa(f * 1000)
s.frameRate = strconv.Itoa(int(f * 1000))
return s, nil
}
}
@ -221,9 +221,9 @@ func VBRQuality(q Quality) Option {
// the camera) as: 250, 500, 750, 1000, 1250, 1500, 1750, 2000, 2250 and 2500.
// If the passed rate does not match one of these values, the closest value is
// selected.
func VBRBitrate(r int) Option {
func VBRBitrate(r uint) Option {
return func(s settings) (settings, error) {
var vbrRates = []int{250, 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500}
var vbrRates = []uint{250, 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500}
if s.vbr == "1" {
s.vbrBitrate = convRate(r, vbrRates)
return s, nil
@ -239,13 +239,13 @@ func VBRBitrate(r int) Option {
// 720p: 1024, 2048, 4096, 6144
// If the passed rate does not align with one of these values, the closest
// value is selected.
func CBRBitrate(r int) Option {
func CBRBitrate(r uint) Option {
return func(s settings) (settings, error) {
v, ok := map[string]string{
res1080: convRate(r, []int{2048, 4096, 6144, 8192}),
res720: convRate(r, []int{1024, 2048, 4096, 6144}),
res360: convRate(r, []int{512, 1024, 2048, 3072}),
res256: convRate(r, []int{128, 256, 512, 1024}),
res1080: convRate(r, []uint{2048, 4096, 6144, 8192}),
res720: convRate(r, []uint{1024, 2048, 4096, 6144}),
res360: convRate(r, []uint{512, 1024, 2048, 3072}),
res256: convRate(r, []uint{128, 256, 512, 1024}),
}[s.res]
if !ok {
panic("bad resolution")
@ -269,8 +269,8 @@ func Refresh(r float64) Option {
return s, fmt.Errorf("invalid refresh period: %g", r)
}
refOptions := []int{250, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000}
s.refresh = strconv.Itoa(refOptions[closestValIdx(int(r*1000), refOptions)])
refOptions := []uint{250, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000}
s.refresh = strconv.Itoa(int(refOptions[closestValIdx(uint(r*1000), refOptions)]))
return s, nil
}
}

View File

@ -33,42 +33,42 @@ import (
func TestClosestValIdx(t *testing.T) {
tests := []struct {
l []int
v int
want int
l []uint
v uint
want uint
}{
{
l: []int{2, 5, 8, 11, 14},
l: []uint{2, 5, 8, 11, 14},
v: 6,
want: 1,
},
{
l: []int{2, 5, 8, 11, 14},
l: []uint{2, 5, 8, 11, 14},
v: 12,
want: 3,
},
{
l: []int{2, 5, 8, 11, 14},
l: []uint{2, 5, 8, 11, 14},
v: 13,
want: 4,
},
{
l: []int{2, 5, 8, 11, 14},
l: []uint{2, 5, 8, 11, 14},
v: 0,
want: 0,
},
{
l: []int{2, 5, 8, 11, 14},
l: []uint{2, 5, 8, 11, 14},
v: 17,
want: 4,
},
{
l: []int{2, 5, 8, 11, 15},
l: []uint{2, 5, 8, 11, 15},
v: 13,
want: 3,
},
{
l: []int{},
l: []uint{},
v: 17,
want: 0,
},
@ -84,22 +84,22 @@ func TestClosestValIdx(t *testing.T) {
func TestConvRate(t *testing.T) {
tests := []struct {
l []int
v int
l []uint
v uint
want string
}{
{
l: []int{512, 1024, 2048, 3072},
l: []uint{512, 1024, 2048, 3072},
v: 1400,
want: "1024000",
},
{
l: []int{512, 1024, 2048, 3072},
l: []uint{512, 1024, 2048, 3072},
v: 1900,
want: "2048000",
},
{
l: []int{512, 1024, 2048, 3072},
l: []uint{512, 1024, 2048, 3072},
v: 4000,
want: "3072000",
},
@ -180,7 +180,7 @@ func TestCodecOut(t *testing.T) {
func TestHeight(t *testing.T) {
tests := []struct {
s settings
h int
h uint
want settings
err error
}{
@ -232,7 +232,7 @@ func TestHeight(t *testing.T) {
func TestVBRBitrate(t *testing.T) {
tests := []struct {
r int
r uint
in settings
want settings
}{
@ -264,7 +264,7 @@ func TestVBRBitrate(t *testing.T) {
func TestCBRBitrate(t *testing.T) {
tests := []struct {
r int
r uint
in settings
want settings
}{

View File

@ -145,7 +145,7 @@ func submitSettings(c *http.Client, id, host string, s settings) error {
req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3")
req.Header.Set("Referer", "http://"+host+"/ssi.cgi/VideoSettingSub.htm?cam="+strconv.Itoa(s.ch))
req.Header.Set("Referer", "http://"+host+"/ssi.cgi/VideoSettingSub.htm?cam="+strconv.Itoa(int(s.ch)))
req.Header.Set("Accept-Encoding", "gzip, deflate")
req.Header.Set("Accept-Language", "en-GB,en-US;q=0.9,en;q=0.8")
req.Header.Set("Cookie", "CLIENT_ID="+id)

View File

@ -67,7 +67,7 @@ type settings struct {
vbrBitrate string
cbrBitrate string
refresh string
ch int
ch uint8
}
// newSetting will return a settings with default values.
@ -94,20 +94,20 @@ func md5Hex(s string) string {
// closestValIdx will return the index of the value in l that is closest to the
// value v.
func closestValIdx(v int, l []int) int {
func closestValIdx(v uint, l []uint) uint {
var idx int
for i := range l {
if math.Abs(float64(l[i]-v)) < math.Abs(float64(l[idx]-v)) {
if math.Abs(float64(int(l[i])-int(v))) < math.Abs(float64(int(l[idx])-int(v))) {
idx = i
}
}
return idx
return uint(idx)
}
// convRate is used to firstly find a value in l closest to the bitrate v (in
// kbps), convert from kbps to bps, and the convert to string.
func convRate(v int, l []int) string {
return strconv.Itoa(l[closestValIdx(v, l)] * 1000)
func convRate(v uint, l []uint) string {
return strconv.Itoa(int(l[closestValIdx(v, l)] * 1000))
}
// populateForm will populate the settings form using the passed settings struct

View File

@ -179,8 +179,8 @@ func (g *GeoVision) Set(c avconfig.Config) error {
codecutil.MJPEG: gvconfig.CodecMJPEG,
}[g.cfg.InputCodec],
),
gvconfig.Height(int(g.cfg.Height)),
gvconfig.FrameRate(int(g.cfg.FrameRate)),
gvconfig.Height(g.cfg.Height),
gvconfig.FrameRate(g.cfg.FrameRate),
gvconfig.VariableBitrate(!g.cfg.CBR),
gvconfig.VBRQuality(
map[avconfig.Quality]gvconfig.Quality{
@ -192,7 +192,7 @@ func (g *GeoVision) Set(c avconfig.Config) error {
}[g.cfg.VBRQuality],
),
gvconfig.VBRBitrate(g.cfg.VBRBitrate),
gvconfig.CBRBitrate(int(g.cfg.Bitrate)),
gvconfig.CBRBitrate(g.cfg.Bitrate),
gvconfig.Refresh(float64(g.cfg.MinFrames)/float64(g.cfg.FrameRate)),
)
if err != nil {

View File

@ -39,9 +39,9 @@ import (
func main() {
var inPath = *flag.String("in", "data.pcm", "file path of input data")
var outPath = *flag.String("out", "resampled.pcm", "file path of output")
var from = *flag.Int("from", 48000, "sample rate of input file")
var to = *flag.Int("to", 8000, "sample rate of output file")
var channels = *flag.Int("ch", 1, "number of channels in input file")
var from = *flag.Uint("from", 48000, "sample rate of input file")
var to = *flag.Uint("to", 8000, "sample rate of output file")
var channels = *flag.Uint("ch", 1, "number of channels in input file")
var SFString = *flag.String("sf", "S16_LE", "sample format of input audio, eg. S16_LE")
flag.Parse()

View File

@ -53,11 +53,11 @@ type Basic struct {
img image.Image
bg [][]pixel
bwImg *image.Gray
thresh int
pix int
thresh float64
pix uint
w int
h int
motion int
motion uint
}
// NewBasic returns a pointer to a new Basic filter struct.
@ -75,7 +75,7 @@ func NewBasic(dst io.WriteCloser, c config.Config) *Basic {
return &Basic{
dst: dst,
thresh: int(c.MotionThreshold),
thresh: c.MotionThreshold,
pix: c.MotionPixels,
debugging: newWindows("BASIC"),
}
@ -159,7 +159,7 @@ func (bf *Basic) process(j int, wg *sync.WaitGroup) {
diff := diffR + diffG + diffB
if diff > bf.thresh {
if diff > int(bf.thresh) {
bf.motion++
bf.bwImg.SetGray(i, j, color.Gray{0xff})
} else {

View File

@ -87,7 +87,7 @@ func NewMotion(dst io.WriteCloser, alg MotionAlgorithm, c config.Config) *Motion
scale: 1 / float64(c.MotionDownscaling),
sample: uint(c.MotionInterval),
padding: c.MotionPadding,
frames: make(chan []byte, c.MotionInterval+int(c.MotionPadding)),
frames: make(chan []byte, c.MotionInterval+c.MotionPadding),
}
}

View File

@ -36,10 +36,10 @@ import (
)
func (r *Revid) setupAudio() error {
mts.Meta.Add("sampleRate", strconv.Itoa(r.cfg.SampleRate))
mts.Meta.Add("channels", strconv.Itoa(r.cfg.Channels))
mts.Meta.Add("sampleRate", strconv.Itoa(int(r.cfg.SampleRate)))
mts.Meta.Add("channels", strconv.Itoa(int(r.cfg.Channels)))
mts.Meta.Add("period", fmt.Sprintf("%.6f", r.cfg.RecPeriod))
mts.Meta.Add("bitDepth", strconv.Itoa(r.cfg.BitDepth))
mts.Meta.Add("bitDepth", strconv.Itoa(int(r.cfg.BitDepth)))
switch r.cfg.InputCodec {
case codecutil.PCM:

View File

@ -205,10 +205,10 @@ type Config struct {
// VBRBitrate describes maximal bitrate for the GeoVision camera when under
// variable bitrate.
VBRBitrate int
VBRBitrate uint
// This is the channel we're using for the GeoVision camera.
CameraChan int
CameraChan uint8
// 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
@ -241,10 +241,10 @@ type Config struct {
AutoWhiteBalance string
// Audio
SampleRate int // Samples a second (Hz).
SampleRate uint // Samples a second (Hz).
RecPeriod float64 // How many seconds to record at a time.
Channels int // Number of audio channels, 1 for mono, 2 for stereo.
BitDepth int // Sample bit depth.
Channels uint // Number of audio channels, 1 for mono, 2 for stereo.
BitDepth uint // Sample bit depth.
RTPAddress string // RTPAddress defines the RTP output destination.
BurstPeriod uint // BurstPeriod defines the revid burst period in seconds.
@ -255,8 +255,8 @@ type Config struct {
HorizontalFlip bool // HorizontalFlip flips video horizontally for Raspivid input.
VerticalFlip bool // VerticalFlip flips video vertically for Raspivid input.
Filters []int // Defines the methods of filtering to be used in between lexing and encoding.
PSITime int // Sets the time between a packet being sent.
Filters []uint8 // Defines the methods of filtering to be used in between lexing and encoding.
PSITime uint // Sets the time between a packet being sent.
// Ring buffer parameters.
RBCapacity uint // The number of bytes the ring buffer will occupy.
@ -265,21 +265,21 @@ type Config struct {
// Motion filter parameters.
// Some parameters can be used with any filter, while others can only be used by a few.
MinFPS float64 // The reduced framerate of the video when there is no motion.
MotionInterval int // Sets the number of frames that are held before the filter is used (on the nth frame).
MotionDownscaling int // Downscaling factor of frames used for motion detection.
MotionInterval uint // Sets the number of frames that are held before the filter is used (on the nth frame).
MotionDownscaling uint // Downscaling factor of frames used for motion detection.
MotionMinArea float64 // Used to ignore small areas of motion detection (KNN & MOG only).
MotionThreshold float64 // Intensity value that is considered motion.
MotionHistory uint // Length of filter's history (KNN & MOG only).
MotionKernel uint // Size of kernel used for filling holes and removing noise (KNN only).
MotionPixels int // Number of pixels with motion that is needed for a whole frame to be considered as moving (Basic only).
MotionPixels uint // Number of pixels with motion that is needed for a whole frame to be considered as moving (Basic only).
MotionPadding uint // Number of frames to keep before and after motion detected.
// If true will restart reading of input after an io.EOF.
Loop bool
// Defines the rate at which frames from a file source are processed.
FileFPS int
FileFPS uint
}
// TypeData contains information about all of the variables that

View File

@ -707,13 +707,13 @@ func (r *Revid) Update(vars map[string]string) error {
case "Filters":
filters := strings.Split(value, ",")
m := map[string]int{"NoOp": config.FilterNoOp, "MOG": config.FilterMOG, "VariableFPS": config.FilterVariableFPS, "KNN": config.FilterKNN, "Difference": config.FilterDiff, "Basic": config.FilterBasic}
r.cfg.Filters = make([]int, len(filters))
r.cfg.Filters = make([]uint8, len(filters))
for i, filter := range filters {
v, ok := m[filter]
if !ok {
r.cfg.Logger.Log(logger.Warning, "invalid Filters param", "value", value)
}
r.cfg.Filters[i] = v
r.cfg.Filters[i] = uint8(v)
}
case "PSITime":
v, err := strconv.Atoi(value)
@ -721,7 +721,7 @@ func (r *Revid) Update(vars map[string]string) error {
r.cfg.Logger.Log(logger.Warning, "invalid PSITime var", "value", value)
break
}
r.cfg.PSITime = v
r.cfg.PSITime = uint(v)
case "BurstPeriod":
v, err := strconv.Atoi(value)
if err != nil {
@ -780,14 +780,14 @@ func (r *Revid) Update(vars map[string]string) error {
r.cfg.Logger.Log(logger.Warning, "invalid VBRBitrate var", "value", value)
break
}
r.cfg.VBRBitrate = v
r.cfg.VBRBitrate = uint(v)
case "CameraChan":
v, err := strconv.Atoi(value)
if err != nil || (v != 1 && v != 2) {
r.cfg.Logger.Log(logger.Warning, "invalid CameraChan var", "value", value)
break
}
r.cfg.CameraChan = v
r.cfg.CameraChan = uint8(v)
case "MinFPS":
v, err := strconv.ParseFloat(value, 64)
if err != nil {
@ -836,28 +836,28 @@ func (r *Revid) Update(vars map[string]string) error {
r.cfg.Logger.Log(logger.Warning, "invalid MotionPixels var", "value", value)
break
}
r.cfg.MotionPixels = v
r.cfg.MotionPixels = uint(v)
case "MotionDownscaling":
v, err := strconv.Atoi(value)
if err != nil {
r.cfg.Logger.Log(logger.Warning, "invalid MotionDownscaling var", "value", value)
break
}
r.cfg.MotionDownscaling = v
r.cfg.MotionDownscaling = uint(v)
case "MotionInterval":
v, err := strconv.Atoi(value)
if err != nil || v < 0 {
r.cfg.Logger.Log(logger.Warning, "invalid MotionInterval var", "value", value)
break
}
r.cfg.MotionInterval = v
r.cfg.MotionInterval = uint(v)
case "FileFPS":
v, err := strconv.Atoi(value)
if err != nil {
r.cfg.Logger.Log(logger.Warning, "invalid FileFPS var", "value", value)
break
}
r.cfg.FileFPS = v
r.cfg.FileFPS = uint(v)
case "mode":
r.cfg.Loop = false
if value == "Loop" {