mirror of https://bitbucket.org/ausocean/av.git
221 lines
5.5 KiB
Go
221 lines
5.5 KiB
Go
|
/*
|
||
|
DESCRIPTION
|
||
|
utils.go provides general constants, structs and helper functions for use in
|
||
|
this package.
|
||
|
|
||
|
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 config
|
||
|
|
||
|
import (
|
||
|
"crypto/md5"
|
||
|
"encoding/hex"
|
||
|
"math"
|
||
|
"net/url"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// The strings used in encoding the settings form to indicate resultion.
|
||
|
const (
|
||
|
res256 = "4480256" // 480x256
|
||
|
res360 = "6400360" // 640x360
|
||
|
res720 = "12800720" // 1280x720
|
||
|
res1080 = "19201080" // 1920x1080
|
||
|
)
|
||
|
|
||
|
// Default values for fields in the settings struct when the newSettings
|
||
|
// constructor is used.
|
||
|
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
|
||
|
defaultChan = 2
|
||
|
)
|
||
|
|
||
|
// settings holds string representations required by the settings form for each
|
||
|
// of the parameters configurable through this API.
|
||
|
type settings struct {
|
||
|
codec Codec
|
||
|
res string
|
||
|
frameRate string
|
||
|
vbr string
|
||
|
quality Quality
|
||
|
vbrBitrate string
|
||
|
cbrBitrate string
|
||
|
refresh string
|
||
|
ch uint8
|
||
|
}
|
||
|
|
||
|
// newSetting will return a settings with default values.
|
||
|
func newSettings() settings {
|
||
|
return settings{
|
||
|
codec: defaultCodec,
|
||
|
res: defaultRes,
|
||
|
frameRate: defaultFrameRate,
|
||
|
vbr: defaultVBR,
|
||
|
quality: defaultQuality,
|
||
|
vbrBitrate: defaultVBRBitrate,
|
||
|
cbrBitrate: defaultCBRBitrate,
|
||
|
refresh: defaultRefresh,
|
||
|
ch: defaultChan,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// md5Hex returns the md5 hex string of s with alphanumerics as upper case.
|
||
|
func md5Hex(s string) string {
|
||
|
h := md5.New()
|
||
|
h.Write([]byte(s))
|
||
|
return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
|
||
|
}
|
||
|
|
||
|
// closestValIdx will return the index of the value in l that is closest to the
|
||
|
// value v.
|
||
|
func closestValIdx(v uint, l []uint) uint {
|
||
|
var idx int
|
||
|
for i := range l {
|
||
|
if math.Abs(float64(int(l[i])-int(v))) < math.Abs(float64(int(l[idx])-int(v))) {
|
||
|
idx = i
|
||
|
}
|
||
|
}
|
||
|
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 uint, l []uint) string {
|
||
|
return strconv.Itoa(int(l[closestValIdx(v, l)] * 1000))
|
||
|
}
|
||
|
|
||
|
// populateForm will populate the settings form using the passed settings struct
|
||
|
// s and return as a url.Values.
|
||
|
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.ch == 1 {
|
||
|
f.Set("dwflicker_less", "1")
|
||
|
f.Set("bSliceMode", "4")
|
||
|
f.Set("dwCameraId", "0")
|
||
|
f.Set("szCamName", "Camera")
|
||
|
f.Set("bAudioCodec", "7")
|
||
|
f.Set("bTVoutFormat", "2")
|
||
|
f.Set("bReadyLed", "0")
|
||
|
f.Set("bLedLan", "0")
|
||
|
f.Set("bLedWan", "0")
|
||
|
f.Set("bLedMonitor", "0")
|
||
|
f.Set("bAlarmLedAutoLevel", "5")
|
||
|
f.Set("bAlarmLedAutoDuration", "60")
|
||
|
f.Set("bAlarmLed", "1")
|
||
|
f.Set("face_detect_level", "1")
|
||
|
f.Set("bDayNight", "0")
|
||
|
f.Set("bDayNightAutoLevel", "3")
|
||
|
f.Set("bIRout", "0")
|
||
|
f.Set("bAutoIris", "0")
|
||
|
f.Set("IrisType", "1")
|
||
|
f.Set("bBLC", "0")
|
||
|
f.Set("bIR", "1")
|
||
|
f.Set("bNSR", "0")
|
||
|
f.Set("ReplaceHomePreset1", "0")
|
||
|
f.Set("webpageEncoding", "windows-1252")
|
||
|
} else if s.ch == 2 {
|
||
|
f.Set("dwCameraId", "1")
|
||
|
} else {
|
||
|
panic("invalid channel")
|
||
|
}
|
||
|
|
||
|
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 {
|
||
|
if s.ch == 1 {
|
||
|
f.Set("dwEncProfile", "3")
|
||
|
} else {
|
||
|
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("bEbIoIn", "1")
|
||
|
f.Set("bEbIoIn1", "1")
|
||
|
f.Set("szOsdCamName", "Camera")
|
||
|
f.Set("bOSDFontSize", "0")
|
||
|
f.Set("bCamNamePos", "2")
|
||
|
f.Set("bDatePos", "2")
|
||
|
f.Set("bTimePos", "2")
|
||
|
f.Set("u16PostAlarmBuf", "1")
|
||
|
f.Set("LangCode", "undefined")
|
||
|
f.Set("Recflag", "0")
|
||
|
f.Set("submit", "Apply")
|
||
|
|
||
|
return f
|
||
|
}
|