From ab71c2cb06f490b50678bec7aaa498a6f440788b Mon Sep 17 00:00:00 2001 From: Saxon Date: Sun, 13 Oct 2019 21:47:50 +1030 Subject: [PATCH] input/gvctrl/gvctrl-cli/main.go: added sub package gvctrl-cli under gvctrl gvctrl-cli provides a command line interface for controlling the geovision camera. Good for testing purposes. --- input/gvctrl/gvctrl-cli/main.go | 96 +++++++++++++++++++++++++++++++++ input/gvctrl/gvctrl.go | 32 +++++------ input/gvctrl/request.go | 21 ++++---- 3 files changed, 123 insertions(+), 26 deletions(-) create mode 100644 input/gvctrl/gvctrl-cli/main.go diff --git a/input/gvctrl/gvctrl-cli/main.go b/input/gvctrl/gvctrl-cli/main.go new file mode 100644 index 00000000..489c6bbc --- /dev/null +++ b/input/gvctrl/gvctrl-cli/main.go @@ -0,0 +1,96 @@ +/* +DESCRIPTION + See package description. + +AUTHORS + Saxon A. Nelson-Milton + +LICENSE + Copyright (C) 2019 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 + in gpl.txt. If not, see http://www.gnu.org/licenses. +*/ + +package main + +import ( + "flag" + "fmt" + "strconv" + + "bitbucket.org/ausocean/av/input/gvctrl" +) + +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.") + 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.") + refreshPtr = flag.Float64("refresh", 0, "Inter refresh period in seconds.") + ) + flag.Parse() + + var options []gvctrl.Option + + if *codecPtr != "" { + var c gvctrl.Codec + switch *codecPtr { + case "h264": + c = gvctrl.CodecH264 + case "h265": + c = gvctrl.CodecH265 + case "mjpeg": + c = gvctrl.CodecMJPEG + default: + panic(fmt.Sprintf("invalid codec: %s", *codecPtr)) + } + options = append(options, gvctrl.CodecOut(c)) + } + + if *heightPtr != 0 { + options = append(options, gvctrl.Height(*heightPtr)) + } + + if *fpsPtr != 0 { + options = append(options, gvctrl.FrameRate(*fpsPtr)) + } + + options = append(options, gvctrl.VariableBitRate(*vbrPtr)) + + if *vbrQualityPtr != -1 { + options = append(options, gvctrl.VBRQuality(gvctrl.Quality(strconv.Itoa(*vbrQualityPtr)))) + } + + if *vbrRatePtr != 0 { + options = append(options, gvctrl.VBRBitRate(*vbrRatePtr)) + } + + if *cbrRatePtr != 0 { + options = append(options, gvctrl.CBRBitRate(*cbrRatePtr)) + } + + if *refreshPtr != 0 { + options = append(options, gvctrl.Refresh(*refreshPtr)) + } + + err := gvctrl.Set(*hostPtr, options...) + if err != nil { + panic(fmt.Sprintf("error from gvctrl.Set: %v", err)) + } +} diff --git a/input/gvctrl/gvctrl.go b/input/gvctrl/gvctrl.go index 818cf1cd..45685154 100644 --- a/input/gvctrl/gvctrl.go +++ b/input/gvctrl/gvctrl.go @@ -12,7 +12,7 @@ LICENSE 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. + 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 @@ -34,9 +34,9 @@ import ( "time" ) -type option func(s settings) (settings, error) +type Option func(s settings) (settings, error) -func Set(host string, options ...option) error { +func Set(host string, options ...Option) error { // Randomly generate an ID our client will use. const ( minID = 10000 @@ -73,7 +73,7 @@ func Set(host string, options ...option) error { for _, op := range options { s, err = op(s) if err != nil { - return fmt.Errorf("could not action option: %v", err) + return fmt.Errorf("could not action Option: %v", err) } } @@ -93,7 +93,7 @@ const ( CodecMJPEG Codec = "4" ) -func CodecOut(c Codec) option { +func CodecOut(c Codec) Option { return func(s settings) (settings, error) { switch c { case CodecH265, CodecH264, CodecMJPEG: @@ -105,7 +105,7 @@ func CodecOut(c Codec) option { } } -func Height(h int) option { +func Height(h int) Option { return func(s settings) (settings, error) { v, ok := map[int]string{256: res256, 360: res360, 720: res720}[h] if !ok { @@ -116,7 +116,7 @@ func Height(h int) option { } } -func FrameRate(f int) option { +func FrameRate(f int) Option { return func(s settings) (settings, error) { if 1 > f || f > 30 { return s, fmt.Errorf("invalid frame rate: %d", f) @@ -126,7 +126,7 @@ func FrameRate(f int) option { } } -func VariableBitRate(b bool) option { +func VariableBitRate(b bool) Option { return func(s settings) (settings, error) { s.vbr = "0" if b { @@ -139,14 +139,14 @@ func VariableBitRate(b bool) option { type Quality string const ( - QualityStandard Quality = "0" - QualityFair Quality = "1" + QualityStandard Quality = "4" + QualityFair Quality = "3" QualityGood Quality = "2" - QualityGreat Quality = "3" - QualityExcellent Quality = "4" + QualityGreat Quality = "1" + QualityExcellent Quality = "0" ) -func VBRQuality(q Quality) option { +func VBRQuality(q Quality) Option { return func(s settings) (settings, error) { switch q { case QualityStandard, QualityFair, QualityGood, QualityGreat, QualityExcellent: @@ -158,7 +158,7 @@ func VBRQuality(q Quality) option { } } -func VBRBitRate(r int) option { +func VBRBitRate(r int) Option { return func(s settings) (settings, error) { var vbrRates = []int{250, 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500} if s.vbr == "1" { @@ -169,7 +169,7 @@ func VBRBitRate(r int) option { } } -func CBRBitRate(r int) option { +func CBRBitRate(r int) Option { return func(s settings) (settings, error) { var ( cbrRates256 = []int{128, 256, 512, 1024} @@ -191,7 +191,7 @@ func CBRBitRate(r int) option { } } -func Refresh(r float64) option { +func Refresh(r float64) Option { return func(s settings) (settings, error) { const ( maxRefreshPeriod = 5 diff --git a/input/gvctrl/request.go b/input/gvctrl/request.go index 288e898e..807df136 100644 --- a/input/gvctrl/request.go +++ b/input/gvctrl/request.go @@ -42,6 +42,7 @@ const ( settingsURL = baseURL + "/VideoSetting.cgi" ) +// TODO: make this configurable. const ( user = "admin" pass = "admin" @@ -83,17 +84,17 @@ func genLogIn(c *http.Client, id, host string) (string, error) { cc[i] = exp[5 : len(exp)-1] } - var data url.Values - data.Set("grp", "-1") - data.Set("username", "") - data.Set("password", "") - data.Set("Apply", "Apply") - data.Set("umd5", md5Hex(cc[0]+user+cc[1])) - data.Set("pmd5", md5Hex(cc[1]+pass+cc[0])) - data.Set("browser", "1") - data.Set("is_check_OCX_OK", "0") + f := url.Values{} + f.Set("grp", "-1") + f.Set("username", "") + f.Set("password", "") + f.Set("Apply", "Apply") + f.Set("umd5", md5Hex(cc[0]+user+cc[1])) + f.Set("pmd5", md5Hex(cc[1]+pass+cc[0])) + f.Set("browser", "1") + f.Set("is_check_OCX_OK", "0") - return data.Encode(), nil + return f.Encode(), nil } func logIn(c *http.Client, id, host, b string) error {