av/input/gvctrl/utils.go

172 lines
3.9 KiB
Go

/*
DESCRIPTION
utils.go provides helper functions for functionality found in both gvctrl.go
request.go.
AUTHORS
Saxon A. Nelson-Milton <saxon@ausocean.org>
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 gvctrl
import (
"crypto/md5"
"encoding/hex"
"math"
"net/url"
"strconv"
"strings"
)
const (
res256 = "4480256"
res360 = "6400360"
res720 = "12800720"
)
const (
defaultCodec = CodecH264
defaultRes = "6400360" // 360p
defaultFrameRate = "25000" // 25 fps
defaultVBR = "0" // Variable bitrate off
defaultQuality = QualityGood
defaultVBRBitRate = "250000" // 512 kbps (lowest with 360p)
defaultCBRBitRate = "512000"
defaultRefresh = "2000" // 2 seconds
)
type settings struct {
codec Codec
res string
frameRate string
vbr string
quality Quality
vbrBitRate string
cbrBitRate string
refresh string
}
func newSettings() settings {
return settings{
codec: defaultCodec,
res: defaultRes,
frameRate: defaultFrameRate,
vbr: defaultVBR,
quality: defaultQuality,
vbrBitRate: defaultVBRBitRate,
cbrBitRate: defaultCBRBitRate,
refresh: defaultRefresh,
}
}
func md5Hex(s string) string {
h := md5.New()
h.Write([]byte(s))
return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
}
func closestValIdx(v int, l []int) int {
var idx int
for i := range l {
if math.Abs(float64(l[i]-v)) < math.Abs(float64(l[idx]-v)) {
idx = i
}
}
return idx
}
func convRate(v int, l []int) string {
return strconv.Itoa(l[closestValIdx(v, l)] * 1000)
}
func populateForm(s settings) url.Values {
f := url.Values{}
f.Set("dwConnType", "5")
f.Set("mpeg_type", string(s.codec))
f.Set("dwflicker_hz", "0")
f.Set("szResolution", s.res)
f.Set("dwFrameRate", s.frameRate)
f.Set("custom_qp_init", "25")
if s.codec == CodecMJPEG {
f.Set("vbr_enable", "1")
f.Set("dwVbrQuality", string(s.quality))
switch s.res {
case res256:
f.Set("vbrmaxbitrate", "250000")
case res360:
f.Set("vbrmaxbitrate", "500000")
case res720:
f.Set("vbrmaxbitrate", "750000")
default:
panic("invalid resolution")
}
} else {
switch s.vbr {
case "0":
f.Set("vbr_enable", "0")
f.Set("max_bit_rate", s.cbrBitRate)
case "1":
f.Set("vbr_enable", "1")
f.Set("dwVbrQuality", string(s.quality))
f.Set("vbrmaxbitrate", s.vbrBitRate)
default:
panic("invalid vbrEnable parameter")
}
f.Set("custom_rate_control_type", "0")
f.Set("custom_bitrate", "0")
f.Set("custom_qp_min", "10")
f.Set("custom_qp_max", "40")
}
f.Set("gop_N", s.refresh)
if s.codec == CodecMJPEG {
f.Set("gop_N", "1500")
}
if s.codec == CodecH264 || s.codec == CodecH265 {
f.Set("dwEncProfile", "1")
f.Set("dwEncLevel", "31")
f.Set("dwEntropy", "0")
}
f.Set("u8PreAlarmBuf", "1")
f.Set("u32PostAlarmBuf2Disk", "1")
f.Set("u8SplitInterval", "5")
f.Set("bEnableIO", "1")
f.Set("bEbIoIn", "1")
f.Set("bEbIoIn1", "1")
f.Set("bOSDFontSize", "0")
f.Set("bEnableOSDCameraName", "1")
f.Set("bCamNamePos", "2")
f.Set("bEnableOSDDate", "1")
f.Set("bDatePos", "2")
f.Set("bEnableOSDTime", "1")
f.Set("bTimePos", "2")
f.Set("szOsdCamName", "Camera")
f.Set("u16PostAlarmBuf", "1")
f.Set("dwCameraId", "1") // Channel=1 => cameraID=0 and chanel=2 => cameraID=1
f.Set("LangCode", "undefined")
f.Set("Recflag", "0")
f.Set("submit", "Apply")
return f
}