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{ cf := pcm.BufferFormat{
SFormat: sf, SFormat: sf,
Channels: ab.Format.Channels, Channels: uint(ab.Format.Channels),
Rate: ab.Format.Rate, Rate: uint(ab.Format.Rate),
} }
ac.pb = pcm.Buffer{ ac.pb = pcm.Buffer{
Format: cf, Format: cf,
Data: ab.Data, 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 rbLen := rbDuration / ac.period
ac.rb = ring.NewBuffer(rbLen, cs, rbTimeout) ac.rb = ring.NewBuffer(int(rbLen), cs, rbTimeout)
go ac.input() go ac.input()
@ -386,7 +392,7 @@ func (ac *audioClient) input() {
// This function also handles NetReceiver configuration requests and updating of NetReceiver vars. // This function also handles NetReceiver configuration requests and updating of NetReceiver vars.
func (ac *audioClient) output() { func (ac *audioClient) output() {
// Calculate the size of the output data based on wanted channels and rate. // 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) 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) 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() ac.mu.Unlock()
// If nothing needs to be changed, return the original. // 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 return ac.pb
} }
formatted := pcm.Buffer{Format: ac.pb.Format} formatted := pcm.Buffer{Format: ac.pb.Format}
bufCopied := false bufCopied := false
if ac.pb.Format.Channels != wantChannels { if int(ac.pb.Format.Channels) != wantChannels {
// Convert channels. // Convert channels.
if ac.pb.Format.Channels == 2 && wantChannels == 1 { 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. // Convert rate.
if bufCopied { if bufCopied {
formatted, err = pcm.Resample(formatted, wantRate) formatted, err = pcm.Resample(formatted, uint(wantRate))
} else { } else {
formatted, err = pcm.Resample(ac.pb, wantRate) formatted, err = pcm.Resample(ac.pb, uint(wantRate))
} }
if err != nil { if err != nil {
log.Log(logger.Warning, "rate conversion failed, audio has remained original rate", "error", err.Error()) log.Log(logger.Warning, "rate conversion failed, audio has remained original rate", "error", err.Error())
} else { } else {
formatted.Format.Rate = wantRate formatted.Format.Rate = uint(wantRate)
} }
} }
return formatted return formatted

View File

@ -57,8 +57,8 @@ const (
// BufferFormat contains the format for a PCM Buffer. // BufferFormat contains the format for a PCM Buffer.
type BufferFormat struct { type BufferFormat struct {
SFormat SampleFormat SFormat SampleFormat
Rate int Rate uint
Channels int Channels uint
} }
// Buffer contains a buffer of PCM data and the format that it is in. // 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. // 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) s := int(float64(channels) * float64(rate) * float64(bitDepth/8) * period)
if codec == codecutil.ADPCM { if codec == codecutil.ADPCM {
s = adpcm.EncBytes(s) 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. // - 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 // - 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. // 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 { if c.Format.Rate == rate {
return c, nil return c, nil
} }
@ -96,9 +96,9 @@ func Resample(c Buffer, rate int) (Buffer, error) {
var sampleLen int var sampleLen int
switch c.Format.SFormat { switch c.Format.SFormat {
case S32_LE: case S32_LE:
sampleLen = 4 * c.Format.Channels sampleLen = int(4 * c.Format.Channels)
case S16_LE: case S16_LE:
sampleLen = 2 * c.Format.Channels sampleLen = int(2 * c.Format.Channels)
default: default:
return Buffer{}, fmt.Errorf("Unhandled ALSA format: %v", c.Format.SFormat) 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. // Calculate sample rate ratio ratioFrom:ratioTo.
rateGcd := gcd(rate, c.Format.Rate) rateGcd := gcd(rate, c.Format.Rate)
ratioFrom := c.Format.Rate / rateGcd ratioFrom := int(c.Format.Rate / rateGcd)
ratioTo := rate / rateGcd ratioTo := int(rate / rateGcd)
// ratioTo = 1 is the only number that will result in an even sampling. // ratioTo = 1 is the only number that will result in an even sampling.
if ratioTo != 1 { 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. // gcd is used for calculating the greatest common divisor of two positive integers, a and b.
// assumes given a and b are positive. // assumes given a and b are positive.
func gcd(a, b int) int { func gcd(a, b uint) uint {
for b != 0 { for b != 0 {
a, b = b, a%b a, b = b, a%b
} }

View File

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

View File

@ -37,12 +37,12 @@ func main() {
var ( var (
hostPtr = flag.String("host", "192.168.1.50", "IP of GeoVision camera.") hostPtr = flag.String("host", "192.168.1.50", "IP of GeoVision camera.")
codecPtr = flag.String("codec", "", "h264, h265 or mjpeg") codecPtr = flag.String("codec", "", "h264, h265 or mjpeg")
heightPtr = flag.Int("height", 0, "256, 360 or 720") heightPtr = flag.Uint("height", 0, "256, 360 or 720")
fpsPtr = flag.Int("fps", 0, "Frame rate in frames per second.") fpsPtr = flag.Uint("fps", 0, "Frame rate in frames per second.")
vbrPtr = flag.Bool("vbr", false, "If true, variable bitrate.") vbrPtr = flag.Bool("vbr", false, "If true, variable bitrate.")
vbrQualityPtr = flag.Int("quality", -1, "General quality under variable bitrate, 0 to 4 inclusive.") 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.") vbrRatePtr = flag.Uint("vbr-rate", 0, "Variable bitrate maximal bitrate in kbps.")
cbrRatePtr = flag.Int("cbr-rate", 0, "Constant bitrate, bitrate in kbps.") cbrRatePtr = flag.Uint("cbr-rate", 0, "Constant bitrate, bitrate in kbps.")
refreshPtr = flag.Float64("refresh", 0, "Inter refresh period in seconds.") refreshPtr = flag.Float64("refresh", 0, "Inter refresh period in seconds.")
) )
flag.Parse() 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. // 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) { return func(s settings) (settings, error) {
if c != 1 && c != 2 { if c != 1 && c != 2 {
return s, errors.New("invalid channel") 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 // Height will set the height component of the video resolution. Available
// heights are 256, 360 and 720. // heights are 256, 360 and 720.
func Height(h int) Option { func Height(h uint) Option {
return func(s settings) (settings, error) { return func(s settings) (settings, error) {
var m map[int]string var m map[uint]string
switch s.ch { switch s.ch {
case 1: case 1:
// TODO: add other resolutions supported by channel 1. // TODO: add other resolutions supported by channel 1.
m = map[int]string{1080: res1080} m = map[uint]string{1080: res1080}
case 2: 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] v, ok := m[h]
if !ok { 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 // 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. // 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) { return func(s settings) (settings, error) {
if 1 > f || f > 30 { if 1 > f || f > 30 {
return s, fmt.Errorf("invalid frame rate: %d", f) 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 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. // 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 // If the passed rate does not match one of these values, the closest value is
// selected. // selected.
func VBRBitrate(r int) Option { func VBRBitrate(r uint) Option {
return func(s settings) (settings, error) { 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" { if s.vbr == "1" {
s.vbrBitrate = convRate(r, vbrRates) s.vbrBitrate = convRate(r, vbrRates)
return s, nil return s, nil
@ -239,13 +239,13 @@ func VBRBitrate(r int) Option {
// 720p: 1024, 2048, 4096, 6144 // 720p: 1024, 2048, 4096, 6144
// If the passed rate does not align with one of these values, the closest // If the passed rate does not align with one of these values, the closest
// value is selected. // value is selected.
func CBRBitrate(r int) Option { func CBRBitrate(r uint) Option {
return func(s settings) (settings, error) { return func(s settings) (settings, error) {
v, ok := map[string]string{ v, ok := map[string]string{
res1080: convRate(r, []int{2048, 4096, 6144, 8192}), res1080: convRate(r, []uint{2048, 4096, 6144, 8192}),
res720: convRate(r, []int{1024, 2048, 4096, 6144}), res720: convRate(r, []uint{1024, 2048, 4096, 6144}),
res360: convRate(r, []int{512, 1024, 2048, 3072}), res360: convRate(r, []uint{512, 1024, 2048, 3072}),
res256: convRate(r, []int{128, 256, 512, 1024}), res256: convRate(r, []uint{128, 256, 512, 1024}),
}[s.res] }[s.res]
if !ok { if !ok {
panic("bad resolution") panic("bad resolution")
@ -269,8 +269,8 @@ func Refresh(r float64) Option {
return s, fmt.Errorf("invalid refresh period: %g", r) return s, fmt.Errorf("invalid refresh period: %g", r)
} }
refOptions := []int{250, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000} refOptions := []uint{250, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000}
s.refresh = strconv.Itoa(refOptions[closestValIdx(int(r*1000), refOptions)]) s.refresh = strconv.Itoa(int(refOptions[closestValIdx(uint(r*1000), refOptions)]))
return s, nil return s, nil
} }
} }

View File

@ -33,42 +33,42 @@ import (
func TestClosestValIdx(t *testing.T) { func TestClosestValIdx(t *testing.T) {
tests := []struct { tests := []struct {
l []int l []uint
v int v uint
want int want uint
}{ }{
{ {
l: []int{2, 5, 8, 11, 14}, l: []uint{2, 5, 8, 11, 14},
v: 6, v: 6,
want: 1, want: 1,
}, },
{ {
l: []int{2, 5, 8, 11, 14}, l: []uint{2, 5, 8, 11, 14},
v: 12, v: 12,
want: 3, want: 3,
}, },
{ {
l: []int{2, 5, 8, 11, 14}, l: []uint{2, 5, 8, 11, 14},
v: 13, v: 13,
want: 4, want: 4,
}, },
{ {
l: []int{2, 5, 8, 11, 14}, l: []uint{2, 5, 8, 11, 14},
v: 0, v: 0,
want: 0, want: 0,
}, },
{ {
l: []int{2, 5, 8, 11, 14}, l: []uint{2, 5, 8, 11, 14},
v: 17, v: 17,
want: 4, want: 4,
}, },
{ {
l: []int{2, 5, 8, 11, 15}, l: []uint{2, 5, 8, 11, 15},
v: 13, v: 13,
want: 3, want: 3,
}, },
{ {
l: []int{}, l: []uint{},
v: 17, v: 17,
want: 0, want: 0,
}, },
@ -84,22 +84,22 @@ func TestClosestValIdx(t *testing.T) {
func TestConvRate(t *testing.T) { func TestConvRate(t *testing.T) {
tests := []struct { tests := []struct {
l []int l []uint
v int v uint
want string want string
}{ }{
{ {
l: []int{512, 1024, 2048, 3072}, l: []uint{512, 1024, 2048, 3072},
v: 1400, v: 1400,
want: "1024000", want: "1024000",
}, },
{ {
l: []int{512, 1024, 2048, 3072}, l: []uint{512, 1024, 2048, 3072},
v: 1900, v: 1900,
want: "2048000", want: "2048000",
}, },
{ {
l: []int{512, 1024, 2048, 3072}, l: []uint{512, 1024, 2048, 3072},
v: 4000, v: 4000,
want: "3072000", want: "3072000",
}, },
@ -180,7 +180,7 @@ func TestCodecOut(t *testing.T) {
func TestHeight(t *testing.T) { func TestHeight(t *testing.T) {
tests := []struct { tests := []struct {
s settings s settings
h int h uint
want settings want settings
err error err error
}{ }{
@ -232,7 +232,7 @@ func TestHeight(t *testing.T) {
func TestVBRBitrate(t *testing.T) { func TestVBRBitrate(t *testing.T) {
tests := []struct { tests := []struct {
r int r uint
in settings in settings
want settings want settings
}{ }{
@ -264,7 +264,7 @@ func TestVBRBitrate(t *testing.T) {
func TestCBRBitrate(t *testing.T) { func TestCBRBitrate(t *testing.T) {
tests := []struct { tests := []struct {
r int r uint
in settings in settings
want 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("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("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("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-Encoding", "gzip, deflate")
req.Header.Set("Accept-Language", "en-GB,en-US;q=0.9,en;q=0.8") req.Header.Set("Accept-Language", "en-GB,en-US;q=0.9,en;q=0.8")
req.Header.Set("Cookie", "CLIENT_ID="+id) req.Header.Set("Cookie", "CLIENT_ID="+id)

View File

@ -67,7 +67,7 @@ type settings struct {
vbrBitrate string vbrBitrate string
cbrBitrate string cbrBitrate string
refresh string refresh string
ch int ch uint8
} }
// newSetting will return a settings with default values. // 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 // closestValIdx will return the index of the value in l that is closest to the
// value v. // value v.
func closestValIdx(v int, l []int) int { func closestValIdx(v uint, l []uint) uint {
var idx int var idx int
for i := range l { 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 idx = i
} }
} }
return idx return uint(idx)
} }
// convRate is used to firstly find a value in l closest to the bitrate v (in // 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. // kbps), convert from kbps to bps, and the convert to string.
func convRate(v int, l []int) string { func convRate(v uint, l []uint) string {
return strconv.Itoa(l[closestValIdx(v, l)] * 1000) return strconv.Itoa(int(l[closestValIdx(v, l)] * 1000))
} }
// populateForm will populate the settings form using the passed settings struct // 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, codecutil.MJPEG: gvconfig.CodecMJPEG,
}[g.cfg.InputCodec], }[g.cfg.InputCodec],
), ),
gvconfig.Height(int(g.cfg.Height)), gvconfig.Height(g.cfg.Height),
gvconfig.FrameRate(int(g.cfg.FrameRate)), gvconfig.FrameRate(g.cfg.FrameRate),
gvconfig.VariableBitrate(!g.cfg.CBR), gvconfig.VariableBitrate(!g.cfg.CBR),
gvconfig.VBRQuality( gvconfig.VBRQuality(
map[avconfig.Quality]gvconfig.Quality{ map[avconfig.Quality]gvconfig.Quality{
@ -192,7 +192,7 @@ func (g *GeoVision) Set(c avconfig.Config) error {
}[g.cfg.VBRQuality], }[g.cfg.VBRQuality],
), ),
gvconfig.VBRBitrate(g.cfg.VBRBitrate), 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)), gvconfig.Refresh(float64(g.cfg.MinFrames)/float64(g.cfg.FrameRate)),
) )
if err != nil { if err != nil {

View File

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

View File

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

View File

@ -87,7 +87,7 @@ func NewMotion(dst io.WriteCloser, alg MotionAlgorithm, c config.Config) *Motion
scale: 1 / float64(c.MotionDownscaling), scale: 1 / float64(c.MotionDownscaling),
sample: uint(c.MotionInterval), sample: uint(c.MotionInterval),
padding: c.MotionPadding, 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 { func (r *Revid) setupAudio() error {
mts.Meta.Add("sampleRate", strconv.Itoa(r.cfg.SampleRate)) mts.Meta.Add("sampleRate", strconv.Itoa(int(r.cfg.SampleRate)))
mts.Meta.Add("channels", strconv.Itoa(r.cfg.Channels)) mts.Meta.Add("channels", strconv.Itoa(int(r.cfg.Channels)))
mts.Meta.Add("period", fmt.Sprintf("%.6f", r.cfg.RecPeriod)) 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 { switch r.cfg.InputCodec {
case codecutil.PCM: case codecutil.PCM:

View File

@ -205,10 +205,10 @@ type Config struct {
// VBRBitrate describes maximal bitrate for the GeoVision camera when under // VBRBitrate describes maximal bitrate for the GeoVision camera when under
// variable bitrate. // variable bitrate.
VBRBitrate int VBRBitrate uint
// This is the channel we're using for the GeoVision camera. // 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 // 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 // number of NAL units. This will also determine the frequency of PSI if the
@ -241,10 +241,10 @@ type Config struct {
AutoWhiteBalance string AutoWhiteBalance string
// Audio // Audio
SampleRate int // Samples a second (Hz). SampleRate uint // Samples a second (Hz).
RecPeriod float64 // How many seconds to record at a time. RecPeriod float64 // How many seconds to record at a time.
Channels int // Number of audio channels, 1 for mono, 2 for stereo. Channels uint // Number of audio channels, 1 for mono, 2 for stereo.
BitDepth int // Sample bit depth. BitDepth uint // Sample bit depth.
RTPAddress string // RTPAddress defines the RTP output destination. RTPAddress string // RTPAddress defines the RTP output destination.
BurstPeriod uint // BurstPeriod defines the revid burst period in seconds. 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. HorizontalFlip bool // HorizontalFlip flips video horizontally for Raspivid input.
VerticalFlip bool // VerticalFlip flips video vertically 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. Filters []uint8 // Defines the methods of filtering to be used in between lexing and encoding.
PSITime int // Sets the time between a packet being sent. PSITime uint // Sets the time between a packet being sent.
// Ring buffer parameters. // Ring buffer parameters.
RBCapacity uint // The number of bytes the ring buffer will occupy. RBCapacity uint // The number of bytes the ring buffer will occupy.
@ -265,21 +265,21 @@ type Config struct {
// Motion filter parameters. // Motion filter parameters.
// Some parameters can be used with any filter, while others can only be used by a few. // 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. 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). MotionInterval uint // 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. MotionDownscaling uint // Downscaling factor of frames used for motion detection.
MotionMinArea float64 // Used to ignore small areas of motion detection (KNN & MOG only). MotionMinArea float64 // Used to ignore small areas of motion detection (KNN & MOG only).
MotionThreshold float64 // Intensity value that is considered motion. MotionThreshold float64 // Intensity value that is considered motion.
MotionHistory uint // Length of filter's history (KNN & MOG only). MotionHistory uint // Length of filter's history (KNN & MOG only).
MotionKernel uint // Size of kernel used for filling holes and removing noise (KNN 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. MotionPadding uint // Number of frames to keep before and after motion detected.
// If true will restart reading of input after an io.EOF. // If true will restart reading of input after an io.EOF.
Loop bool Loop bool
// Defines the rate at which frames from a file source are processed. // 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 // 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": case "Filters":
filters := strings.Split(value, ",") 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} 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 { for i, filter := range filters {
v, ok := m[filter] v, ok := m[filter]
if !ok { if !ok {
r.cfg.Logger.Log(logger.Warning, "invalid Filters param", "value", value) r.cfg.Logger.Log(logger.Warning, "invalid Filters param", "value", value)
} }
r.cfg.Filters[i] = v r.cfg.Filters[i] = uint8(v)
} }
case "PSITime": case "PSITime":
v, err := strconv.Atoi(value) 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) r.cfg.Logger.Log(logger.Warning, "invalid PSITime var", "value", value)
break break
} }
r.cfg.PSITime = v r.cfg.PSITime = uint(v)
case "BurstPeriod": case "BurstPeriod":
v, err := strconv.Atoi(value) v, err := strconv.Atoi(value)
if err != nil { 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) r.cfg.Logger.Log(logger.Warning, "invalid VBRBitrate var", "value", value)
break break
} }
r.cfg.VBRBitrate = v r.cfg.VBRBitrate = uint(v)
case "CameraChan": case "CameraChan":
v, err := strconv.Atoi(value) v, err := strconv.Atoi(value)
if err != nil || (v != 1 && v != 2) { if err != nil || (v != 1 && v != 2) {
r.cfg.Logger.Log(logger.Warning, "invalid CameraChan var", "value", value) r.cfg.Logger.Log(logger.Warning, "invalid CameraChan var", "value", value)
break break
} }
r.cfg.CameraChan = v r.cfg.CameraChan = uint8(v)
case "MinFPS": case "MinFPS":
v, err := strconv.ParseFloat(value, 64) v, err := strconv.ParseFloat(value, 64)
if err != nil { 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) r.cfg.Logger.Log(logger.Warning, "invalid MotionPixels var", "value", value)
break break
} }
r.cfg.MotionPixels = v r.cfg.MotionPixels = uint(v)
case "MotionDownscaling": case "MotionDownscaling":
v, err := strconv.Atoi(value) v, err := strconv.Atoi(value)
if err != nil { if err != nil {
r.cfg.Logger.Log(logger.Warning, "invalid MotionDownscaling var", "value", value) r.cfg.Logger.Log(logger.Warning, "invalid MotionDownscaling var", "value", value)
break break
} }
r.cfg.MotionDownscaling = v r.cfg.MotionDownscaling = uint(v)
case "MotionInterval": case "MotionInterval":
v, err := strconv.Atoi(value) v, err := strconv.Atoi(value)
if err != nil || v < 0 { if err != nil || v < 0 {
r.cfg.Logger.Log(logger.Warning, "invalid MotionInterval var", "value", value) r.cfg.Logger.Log(logger.Warning, "invalid MotionInterval var", "value", value)
break break
} }
r.cfg.MotionInterval = v r.cfg.MotionInterval = uint(v)
case "FileFPS": case "FileFPS":
v, err := strconv.Atoi(value) v, err := strconv.Atoi(value)
if err != nil { if err != nil {
r.cfg.Logger.Log(logger.Warning, "invalid FileFPS var", "value", value) r.cfg.Logger.Log(logger.Warning, "invalid FileFPS var", "value", value)
break break
} }
r.cfg.FileFPS = v r.cfg.FileFPS = uint(v)
case "mode": case "mode":
r.cfg.Loop = false r.cfg.Loop = false
if value == "Loop" { if value == "Loop" {