diff --git a/revid/geovision.go b/revid/geovision.go index bc24c478..f801dc50 100644 --- a/revid/geovision.go +++ b/revid/geovision.go @@ -24,24 +24,105 @@ LICENSE package revid -import () +import ( + "errors" + "fmt" -type GeoVision struct {} + "bitbucket.org/ausocean/av/codec/codecutil" + "bitbucket.org/ausocean/av/input/gvctrl" +) + +const ( + gvDefaultCameraIP = "192.168.1.50" + gvDefaultCodec = codecutil.H264 + gvDefaultHeight = 720 + gvDefaultFrameRate = 25 + gvDefaultBitrate = 400 + gvDefaultVBRBitrate = 400 + gvDefaultMinFrames = 100 + gvDefaultVBRQuality = "standard" +) + +var ( + errGVBadCameraIP = errors.New("camera IP bad or unset, defaulting") + errGVBadCodec = errors.New("codec bad or unset, defaulting") + errGVBadFrameRate = errors.New("frame rate bad or unset, defaulting") + errGVBadBitrate = errors.New("bitrate bad or unset, defaulting") + errGVBadVBRQuality = errors.New("VBR quality bad or unset, defaulting") + errGVBadHeight = errors.New("height bad or unset, defaulting") + errGVBadMinFrames = errors.New("min frames bad or unset, defaulting") +) + +type GeoVision struct { + cfg Config +} func (g *GeoVision) Set(c Config) error { - err := gvctrl.Set( - r.config.CameraIP, - gvctrl.Channel(r.config.CameraChan), + var errs multiError + if c.CameraIP == "" { + errs = append(errs, errGVBadCameraIP) + c.CameraIP = gvDefaultCameraIP + } + + switch c.InputCodec { + case codecutil.H264, codecutil.H265, codecutil.MJPEG: + default: + errs = append(errs, errGVBadCodec) + c.InputCodec = gvDefaultCodec + } + + if c.Height <= 0 { + errs = append(errs, errGVBadHeight) + c.Height = gvDefaultHeight + } + + if c.FrameRate <= 0 { + errs = append(errs, errGVBadFrameRate) + c.FrameRate = gvDefaultFrameRate + } + + if c.Bitrate <= 0 { + errs = append(errs, errGVBadBitrate) + c.Bitrate = gvDefaultBitrate + } + + if c.MinFrames <= 0 { + errs = append(errs, errGVBadMinFrames) + c.MinFrames = gvDefaultMinFrames + } + + switch c.VBRQuality { + case qualityStandard, qualityFair, qualityGood, qualityGreat, qualityExcellent: + default: + errs = append(errs, errGVBadVBRQuality) + c.VBRQuality = defaultVBRQuality + } + + if c.VBRBitrate <= 0 { + errs = append(errs, errGVBadVBRQuality) + c.VBRBitrate = defaultVBRBitrate + } + + if c.CameraChan != 1 && c.CameraChan != 2 { + errs = append(errs, errGVBadVBRQuality) + c.CameraChan = defaultCameraChan + } + + g.cfg = c + + err := gvctrl.Set( + g.cfg.CameraIP, + gvctrl.Channel(g.cfg.CameraChan), gvctrl.CodecOut( map[uint8]gvctrl.Codec{ codecutil.H264: gvctrl.CodecH264, codecutil.H265: gvctrl.CodecH265, codecutil.MJPEG: gvctrl.CodecMJPEG, - }[r.config.InputCodec], + }[g.cfg.InputCodec], ), - gvctrl.Height(int(r.config.Height)), - gvctrl.FrameRate(int(r.config.FrameRate)), - gvctrl.VariableBitrate(r.config.VBR), + gvctrl.Height(int(g.cfg.Height)), + gvctrl.FrameRate(int(g.cfg.FrameRate)), + gvctrl.VariableBitrate(g.cfg.VBR), gvctrl.VBRQuality( map[quality]gvctrl.Quality{ qualityStandard: gvctrl.QualityStandard, @@ -49,14 +130,14 @@ func (g *GeoVision) Set(c Config) error { qualityGood: gvctrl.QualityGood, qualityGreat: gvctrl.QualityGreat, qualityExcellent: gvctrl.QualityExcellent, - }[r.config.VBRQuality], + }[g.cfg.VBRQuality], ), - gvctrl.VBRBitrate(r.config.VBRBitrate), - gvctrl.CBRBitrate(int(r.config.Bitrate)), - gvctrl.Refresh(float64(r.config.MinFrames)/float64(r.config.FrameRate)), + gvctrl.VBRBitrate(g.cfg.VBRBitrate), + gvctrl.CBRBitrate(int(g.cfg.Bitrate)), + gvctrl.Refresh(float64(g.cfg.MinFrames)/float64(g.cfg.FrameRate)), ) if err != nil { - return nil, fmt.Errorf("could not set IPCamera settings: %w", err) + return fmt.Errorf("could not set IPCamera settings: %w", err) } - return nil + return multiError(errs) }