diff --git a/HikBallCamera.go b/HikBallCamera.go new file mode 100644 index 0000000..538ba8f --- /dev/null +++ b/HikBallCamera.go @@ -0,0 +1,159 @@ +package HikNetSDK + +import ( + "fmt" + "sync" + "unsafe" +) + +type HIKBallCamera struct { + core unsafe.Pointer + State bool + BallCameraCfg BallCamera + mux sync.RWMutex +} + +func NewHIKBallCamera(BallCameraCfg BallCamera) *HIKBallCamera { + return &HIKBallCamera{ + core: newHIKBallCamera(), + BallCameraCfg: BallCameraCfg, + State: false, + mux: sync.RWMutex{}, + } +} + +func (hikBC *HIKBallCamera) Login() bool { + hikBC.mux.Lock() + hikBC.State = initBallCamera(hikBC.core, hikBC.BallCameraCfg.Ip, hikBC.BallCameraCfg.Port, hikBC.BallCameraCfg.User, hikBC.BallCameraCfg.Password, hikBC.BallCameraCfg.Type) + hikBC.mux.Unlock() + return hikBC.State +} + +func (hikBC *HIKBallCamera) opt(action func() bool) bool { + hikBC.mux.RLock() + if hikBC.State { + hikBC.mux.RUnlock() + hikBC.mux.Lock() + hikBC.State = action() + hikBC.mux.Unlock() + } else { + hikBC.mux.RUnlock() + } + return hikBC.State +} + +func (hikBC *HIKBallCamera) PTZGet(P, T, Z *float32) bool { + return hikBC.opt(func() bool { + return ptzGet(hikBC.core, unsafe.Pointer(P), unsafe.Pointer(T), unsafe.Pointer(Z)) + }) +} + +func (hikBC *HIKBallCamera) PtzTo(Action int, P, T, Z float32) bool { + return hikBC.opt(func() bool { + return ptzTo(hikBC.core, Action, P, T, Z) + }) +} + +func (hikBC *HIKBallCamera) StartBus(Direction, Speed int) bool { + return hikBC.opt(func() bool { + return startBus(hikBC.core, Direction, Speed) + }) +} + +func (hikBC *HIKBallCamera) StopBus(Direction int) bool { + return hikBC.opt(func() bool { + return stopBus(hikBC.core, Direction) + }) +} + +func (hikBC *HIKBallCamera) OneClickToSeeInFullView(point Point) bool { + TransPoint := hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.Matrix, point) + return hikBC.opt(func() bool { + return hikBC.PtzTo(5, + float32(hikBC.mapping(hikBC.BallCameraCfg.Matrix.PStart, hikBC.BallCameraCfg.Matrix.PMax, TransPoint.X, hikBC.BallCameraCfg.Matrix.PPositiveDirection, "inv")), + float32(hikBC.mapping(hikBC.BallCameraCfg.Matrix.TStart, hikBC.BallCameraCfg.Matrix.TMax, TransPoint.Y, hikBC.BallCameraCfg.Matrix.TPositiveDirection, "inv")), + 0.0, + ) + }) + +} + +func (hikBC *HIKBallCamera) PTZ2FullView() (Point, error) { + var ptz PTZ + if !hikBC.opt(func() bool { + return hikBC.PTZGet(&ptz.P, &ptz.T, &ptz.Z) + }) { + return Point{}, fmt.Errorf("PTZ Get Error") + } + return hikBC.WarpingPtByHomography(hikBC.BallCameraCfg.Matrix.InvMatrix, Point{ + X: hikBC.mapping(hikBC.BallCameraCfg.Matrix.PStart, hikBC.BallCameraCfg.Matrix.PMax, float64(ptz.P), hikBC.BallCameraCfg.Matrix.PPositiveDirection, ""), + Y: hikBC.mapping(hikBC.BallCameraCfg.Matrix.TStart, hikBC.BallCameraCfg.Matrix.TMax, float64(ptz.T), hikBC.BallCameraCfg.Matrix.TPositiveDirection, "")}), nil +} + +func (hikBC *HIKBallCamera) WarpingPtByHomography(matrix []float64, p Point) Point { + var x, y, z float64 + x = matrix[0]*p.X + matrix[1]*p.Y + 1.*matrix[2] + y = matrix[3]*p.X + matrix[4]*p.Y + 1.*matrix[5] + z = matrix[6]*p.X + matrix[7]*p.Y + 1.*matrix[8] + + x /= z + y /= z + return Point{X: x, Y: y} +} + +func (hikBC *HIKBallCamera) Invert3x3() bool { + + a := hikBC.BallCameraCfg.Matrix.Matrix[0] + b := hikBC.BallCameraCfg.Matrix.Matrix[1] + c := hikBC.BallCameraCfg.Matrix.Matrix[2] + d := hikBC.BallCameraCfg.Matrix.Matrix[3] + e := hikBC.BallCameraCfg.Matrix.Matrix[4] + f := hikBC.BallCameraCfg.Matrix.Matrix[5] + g := hikBC.BallCameraCfg.Matrix.Matrix[6] + h := hikBC.BallCameraCfg.Matrix.Matrix[7] + i := hikBC.BallCameraCfg.Matrix.Matrix[8] + + det := a*(e*i-f*h) - b*(d*i-f*g) + c*(d*h-e*g) + + if det == 0 { + return false + } + + invDet := 1.0 / det + hikBC.BallCameraCfg.Matrix.InvMatrix = []float64{ + (e*i - f*h) * invDet, + (c*h - b*i) * invDet, + (b*f - c*e) * invDet, + (f*g - d*i) * invDet, + (a*i - c*g) * invDet, + (c*d - a*f) * invDet, + (d*h - e*g) * invDet, + (b*g - a*h) * invDet, + (a*e - b*d) * invDet, + } + return true +} + +func (hikBC *HIKBallCamera) mapping(startV float64, max float64, value float64, direction string, method string) float64 { + if direction == "+" { + if method == "inv" { + if value > (max - startV) { + return value - (max - startV) + } else { + return startV + value // 映射 + } + } else { + if value > startV { + return value - startV + } else { + return (max - startV) + value // 映射 + } + } + } else { + if value > startV { + return startV + max - value + } else { + return startV - value + } + } +} diff --git a/HikNvr.go b/HikNvr.go new file mode 100644 index 0000000..2d036c7 --- /dev/null +++ b/HikNvr.go @@ -0,0 +1,101 @@ +package HikNetSDK + +import ( + "sync" + "unsafe" +) + +type HIKNvr struct { + core unsafe.Pointer + State bool + NvrConfig Nvr + mux sync.RWMutex +} + +func NewHIKNvr(nvrConfig Nvr) *HIKNvr { + return &HIKNvr{ + core: newHIKNvr(), + NvrConfig: nvrConfig, + State: false, + mux: sync.RWMutex{}, + } +} + +func (h *HIKNvr) opt(action func() bool) bool { + h.mux.RLock() + if h.State { + h.mux.RUnlock() + h.mux.Lock() + h.State = action() + h.mux.Unlock() + } + h.mux.RUnlock() + return h.State +} + +func (h *HIKNvr) Login() bool { + h.mux.Lock() + h.State = initNvr(h.core, h.NvrConfig.Ip, h.NvrConfig.Port, h.NvrConfig.User, h.NvrConfig.Password, h.NvrConfig.Channel) + h.mux.Unlock() + return h.State +} + +func (h *HIKNvr) CheckTimeRegionWithMonth(year int, month int) string { + h.mux.RLock() + if h.State { + h.mux.RUnlock() + if checkTimeRegionWithMonth(h.core, year, month) == "" { + h.mux.Lock() + h.State = false + h.mux.Unlock() + } else { + h.mux.Lock() + h.State = true + h.mux.Unlock() + } + } else { + h.mux.RUnlock() + } + return "" +} + +func (h *HIKNvr) CheckTimeRegionWithDay(year int, month int, day int) string { + h.mux.RLock() + if h.State { + h.mux.RUnlock() + data := checkTimeRegionWithDay(h.core, year, month, day) + if data == "" { + h.mux.Lock() + h.State = false + h.mux.Unlock() + } else { + h.mux.Lock() + h.State = true + h.mux.Unlock() + return data + } + } else { + h.mux.RUnlock() + } + return "" +} +func (h *HIKNvr) UTCDiff() int { + h.mux.RLock() + if h.State { + data := nvrUTCDiff(h.core) + h.mux.RUnlock() + if nvrUTCDiff(h.core) == 500 { + h.mux.Lock() + h.State = false + h.mux.Unlock() + } else { + h.mux.Lock() + h.State = true + h.mux.Unlock() + return data + } + } else { + h.mux.RUnlock() + } + return 1000 +} diff --git a/Hikvision.go b/Hikvision.go index a3cdb00..d76944b 100644 --- a/Hikvision.go +++ b/Hikvision.go @@ -10,7 +10,7 @@ import ( var libc uintptr var ( - DVR_Init func() bool + DvrInit func() bool newHIKBallCamera func() unsafe.Pointer initBallCamera func(core unsafe.Pointer, ip string, port string, username string, password string, BallMachineType string) bool @@ -33,7 +33,7 @@ func init() { panic(err) } - purego.RegisterLibFunc(&DVR_Init, libc, "DVR_Init") + purego.RegisterLibFunc(&DvrInit, libc, "DVR_Init") purego.RegisterLibFunc(&newHIKBallCamera, libc, "NewHIKBallCamera") purego.RegisterLibFunc(&initBallCamera, libc, "InitBallCamera") @@ -64,144 +64,3 @@ func getSystemLibrary() string { panic(fmt.Errorf("GOOS=%s is not supported", runtime.GOOS)) } } - -type HIKBallCamera struct { - core unsafe.Pointer - BallCameraCfg BallCamera -} - -func NewHIKBallCamera(BallCameraCfg BallCamera) *HIKBallCamera { - return &HIKBallCamera{ - core: newHIKBallCamera(), - BallCameraCfg: BallCameraCfg, - } -} - -func (h *HIKBallCamera) Login() bool { - return initBallCamera(h.core, h.BallCameraCfg.Ip, h.BallCameraCfg.Port, h.BallCameraCfg.User, h.BallCameraCfg.Password, h.BallCameraCfg.Type) -} -func (h *HIKBallCamera) PtzTo(Action int, P, T, Z float32) bool { - return ptzTo(h.core, Action, P, T, Z) -} -func (h *HIKBallCamera) PTZGet(P, T, Z *float32) bool { - return ptzGet(h.core, unsafe.Pointer(P), unsafe.Pointer(T), unsafe.Pointer(Z)) -} -func (h *HIKBallCamera) StopBus(Direction int) bool { - return stopBus(h.core, Direction) -} -func (h *HIKBallCamera) StartBus(Direction, Speed int) bool { - return startBus(h.core, Direction, Speed) -} - -type HIKNvr struct { - core unsafe.Pointer - NvrConfig Nvr -} - -func NewHIKNvr(nvrConfig Nvr) *HIKNvr { - return &HIKNvr{ - core: newHIKNvr(), - NvrConfig: nvrConfig, - } -} - -func (h *HIKNvr) Login() bool { - return initNvr(h.core, h.NvrConfig.Ip, h.NvrConfig.Port, h.NvrConfig.User, h.NvrConfig.Password, h.NvrConfig.Channel) -} - -func (h *HIKNvr) CheckTimeRegionWithMonth(year int, month int) string { - return checkTimeRegionWithMonth(h.core, year, month) -} -func (h *HIKNvr) CheckTimeRegionWithDay(year int, month int, day int) string { - return checkTimeRegionWithDay(h.core, year, month, day) -} -func (h *HIKNvr) UTCDiff() int { - return nvrUTCDiff(h.core) -} - -func (h *HIKBallCamera) WarpingPtByHomography(matrix []float64, p Point) Point { - var x, y, z float64 - x = matrix[0]*p.X + matrix[1]*p.Y + 1.*matrix[2] - y = matrix[3]*p.X + matrix[4]*p.Y + 1.*matrix[5] - z = matrix[6]*p.X + matrix[7]*p.Y + 1.*matrix[8] - - x /= z - y /= z - return Point{X: x, Y: y} -} - -func (h *HIKBallCamera) mapping(startV float64, max float64, value float64, direction string, method string) float64 { - if direction == "+" { - if method == "inv" { - if value > (max - startV) { - return value - (max - startV) - } else { - return startV + value // 映射 - } - } else { - if value > startV { - return value - startV - } else { - return (max - startV) + value // 映射 - } - } - } else { - if value > startV { - return startV + max - value - } else { - return startV - value - } - } -} - -func (h *HIKBallCamera) OneClickToSeeInFullView(point Point) bool { - TransPoint := h.WarpingPtByHomography(h.BallCameraCfg.Matrix.Matrix, point) - return h.PtzTo(5, - float32(h.mapping(h.BallCameraCfg.Matrix.PStart, h.BallCameraCfg.Matrix.PMax, TransPoint.X, h.BallCameraCfg.Matrix.PPositiveDirection, "inv")), - float32(h.mapping(h.BallCameraCfg.Matrix.TStart, h.BallCameraCfg.Matrix.TMax, TransPoint.Y, h.BallCameraCfg.Matrix.TPositiveDirection, "inv")), - 0.0, - ) -} - -func (h *HIKBallCamera) PTZ2FullView() (Point, error) { - var ptz PTZ - if !h.PTZGet(&ptz.P, &ptz.T, &ptz.Z) { - return Point{}, fmt.Errorf("PTZ Get Error") - } - return h.WarpingPtByHomography(h.BallCameraCfg.Matrix.InvMatrix, Point{ - X: h.mapping(h.BallCameraCfg.Matrix.PStart, h.BallCameraCfg.Matrix.PMax, float64(ptz.P), h.BallCameraCfg.Matrix.PPositiveDirection, ""), - Y: h.mapping(h.BallCameraCfg.Matrix.TStart, h.BallCameraCfg.Matrix.TMax, float64(ptz.T), h.BallCameraCfg.Matrix.TPositiveDirection, "")}), nil -} - -func (hikBC *HIKBallCamera) Invert3x3() bool { - - a := hikBC.BallCameraCfg.Matrix.Matrix[0] - b := hikBC.BallCameraCfg.Matrix.Matrix[1] - c := hikBC.BallCameraCfg.Matrix.Matrix[2] - d := hikBC.BallCameraCfg.Matrix.Matrix[3] - e := hikBC.BallCameraCfg.Matrix.Matrix[4] - f := hikBC.BallCameraCfg.Matrix.Matrix[5] - g := hikBC.BallCameraCfg.Matrix.Matrix[6] - h := hikBC.BallCameraCfg.Matrix.Matrix[7] - i := hikBC.BallCameraCfg.Matrix.Matrix[8] - - det := a*(e*i-f*h) - b*(d*i-f*g) + c*(d*h-e*g) - - if det == 0 { - return false - } - - invDet := 1.0 / det - hikBC.BallCameraCfg.Matrix.InvMatrix = []float64{ - (e*i - f*h) * invDet, - (c*h - b*i) * invDet, - (b*f - c*e) * invDet, - (f*g - d*i) * invDet, - (a*i - c*g) * invDet, - (c*d - a*f) * invDet, - (d*h - e*g) * invDet, - (b*g - a*h) * invDet, - (a*e - b*d) * invDet, - } - return true -}