added video buffer and improved logging

This commit is contained in:
Russell Stanley 2022-02-03 09:56:04 +10:30
parent 18b9a3dbab
commit 014230a274
2 changed files with 16 additions and 9 deletions

View File

@ -55,6 +55,7 @@ USAGE
package main package main
import ( import (
"bytes"
"io" "io"
"os" "os"
"runtime/pprof" "runtime/pprof"
@ -72,7 +73,6 @@ import (
"bitbucket.org/ausocean/av/turbidity" "bitbucket.org/ausocean/av/turbidity"
"bitbucket.org/ausocean/iot/pi/netlogger" "bitbucket.org/ausocean/iot/pi/netlogger"
"bitbucket.org/ausocean/iot/pi/netsender" "bitbucket.org/ausocean/iot/pi/netsender"
"bitbucket.org/ausocean/iot/pi/sds"
"bitbucket.org/ausocean/utils/logger" "bitbucket.org/ausocean/utils/logger"
) )
@ -135,6 +135,7 @@ type turbidityProbe struct {
ticker time.Ticker ticker time.Ticker
ts *turbidity.TurbiditySensor ts *turbidity.TurbiditySensor
log logger.Logger log logger.Logger
buffer *bytes.Buffer
} }
// NewTurbidityProbe returns a new turbidity probe. // NewTurbidityProbe returns a new turbidity probe.
@ -143,6 +144,7 @@ func NewTurbidityProbe(log logger.Logger, delay time.Duration) (*turbidityProbe,
tp.log = log tp.log = log
tp.delay = delay tp.delay = delay
tp.ticker = *time.NewTicker(delay) tp.ticker = *time.NewTicker(delay)
tp.buffer = bytes.NewBuffer(*new([]byte))
// Create the turbidity sensor. // Create the turbidity sensor.
standard := gocv.IMRead("../../turbidity/images/template.jpg", gocv.IMReadGrayScale) standard := gocv.IMRead("../../turbidity/images/template.jpg", gocv.IMReadGrayScale)
@ -158,6 +160,7 @@ func NewTurbidityProbe(log logger.Logger, delay time.Duration) (*turbidityProbe,
// Write, reads input h264 frames in the form of a byte stream and writes the the sharpness and contrast // Write, reads input h264 frames in the form of a byte stream and writes the the sharpness and contrast
// scores of a video to the the turbidity probe. // scores of a video to the the turbidity probe.
func (tp *turbidityProbe) Write(p []byte) (int, error) { func (tp *turbidityProbe) Write(p []byte) (int, error) {
tp.buffer.Write(p)
select { select {
case <-tp.ticker.C: case <-tp.ticker.C:
var imgs []gocv.Mat var imgs []gocv.Mat
@ -170,12 +173,12 @@ func (tp *turbidityProbe) Write(p []byte) (int, error) {
return len(p), err return len(p), err
} }
defer os.Remove(file.Name()) defer os.Remove(file.Name())
_, err = file.Write(p) _, err = file.Write(tp.buffer.Bytes())
if err != nil { if err != nil {
tp.log.Error("failed to write to temporary file", "error", err.Error()) tp.log.Error("failed to write to temporary file", "error", err.Error())
return len(p), err return len(p), err
} }
tp.buffer.Reset()
// Read the file and store each frame. // Read the file and store each frame.
vc, err := gocv.VideoCaptureFile(file.Name()) vc, err := gocv.VideoCaptureFile(file.Name())
if err != nil { if err != nil {
@ -185,11 +188,15 @@ func (tp *turbidityProbe) Write(p []byte) (int, error) {
for vc.Read(&img) && len(imgs) < maxImages { for vc.Read(&img) && len(imgs) < maxImages {
imgs = append(imgs, img.Clone()) imgs = append(imgs, img.Clone())
} }
if len(imgs) <= 0 {
tp.log.Log(logger.Info, "no frames found")
return len(p), nil
}
// Process video data to get saturation and contrast scores. // Process video data to get saturation and contrast scores.
res, err := tp.ts.Evaluate(imgs) res, err := tp.ts.Evaluate(imgs)
if err != nil { if err != nil {
tp.log.Error("evaluate failed", "errror", err.Error()) tp.log.Error("evaluate failed", "error", err.Error())
return len(p), err return len(p), err
} }
tp.contrast = stat.Mean(res.Contrast, nil) tp.contrast = stat.Mean(res.Contrast, nil)
@ -236,7 +243,7 @@ func main() {
p, err := NewTurbidityProbe(*log, 60*time.Second) p, err := NewTurbidityProbe(*log, 60*time.Second)
log.Log(logger.Debug, "initialising netsender client") log.Log(logger.Debug, "initialising netsender client")
ns, err := netsender.New(log, nil, readPin(p, rv), nil, createVarMap()) ns, err := netsender.New(log, nil, readPin(p, rv, log), nil, createVarMap())
if err != nil { if err != nil {
log.Log(logger.Fatal, pkg+"could not initialise netsender client: "+err.Error()) log.Log(logger.Fatal, pkg+"could not initialise netsender client: "+err.Error())
} }
@ -375,7 +382,7 @@ func sleep(ns *netsender.Sender, l *logger.Logger) {
// readPin provides a callback function of consistent signature for use by // readPin provides a callback function of consistent signature for use by
// netsender to retrieve software defined pin values e.g. revid bitrate. // netsender to retrieve software defined pin values e.g. revid bitrate.
func readPin(p *turbidityProbe, rv *revid.Revid) func(pin *netsender.Pin) error { func readPin(p *turbidityProbe, rv *revid.Revid, l *logger.Logger) func(pin *netsender.Pin) error {
return func(pin *netsender.Pin) error { return func(pin *netsender.Pin) error {
switch { switch {
case pin.Name == bitratePin: case pin.Name == bitratePin:
@ -383,16 +390,16 @@ func readPin(p *turbidityProbe, rv *revid.Revid) func(pin *netsender.Pin) error
if rv != nil { if rv != nil {
pin.Value = rv.Bitrate() pin.Value = rv.Bitrate()
} }
case pin.Name[0] == 'X':
return sds.ReadSystem(pin)
case pin.Name == sharpnessPin: case pin.Name == sharpnessPin:
pin.Value = -1 pin.Value = -1
if p != nil { if p != nil {
l.Debug("setting sharpness value", "sharpness", p.sharpness*1000)
pin.Value = int(p.sharpness * 1000) pin.Value = int(p.sharpness * 1000)
} }
case pin.Name == contrastPin: case pin.Name == contrastPin:
pin.Value = -1 pin.Value = -1
if p != nil { if p != nil {
l.Debug("setting contrast pin", "contrast", p.contrast)
pin.Value = int(p.contrast * 100) pin.Value = int(p.contrast * 100)
} }
default: default:

View File

@ -1,6 +1,6 @@
/* /*
NAME NAME
audio_OSX.go audio_darwin.go
AUTHORS AUTHORS
Russell Stanley <russell@ausocean.org> Russell Stanley <russell@ausocean.org>