device/raspistill & revid/config: PR problem fixes run 1

This commit is contained in:
Saxon Nelson-Milton 2021-01-27 13:41:29 +10:30
parent 8a792099a5
commit c18e263d95
5 changed files with 43 additions and 49 deletions

View File

@ -81,7 +81,7 @@ func (r *Raspistill) start() error {
"--rotation", fmt.Sprint(r.cfg.Rotation), "--rotation", fmt.Sprint(r.cfg.Rotation),
"--timeout", fmt.Sprint(r.cfg.TimelapseDuration), "--timeout", fmt.Sprint(r.cfg.TimelapseDuration),
"--timelapse", fmt.Sprint(r.cfg.TimelapseInterval), "--timelapse", fmt.Sprint(r.cfg.TimelapseInterval),
"--quality", fmt.Sprint(r.cfg.SnapQuality), "--quality", fmt.Sprint(r.cfg.JPEGQuality),
} }
r.log.Info(pkg+"raspistill args", "args", strings.Join(args, " ")) r.log.Info(pkg+"raspistill args", "args", strings.Join(args, " "))

View File

@ -4,7 +4,7 @@
DESCRIPTION DESCRIPTION
test.go provides test implementations of the raspistill methods when the test.go provides test implementations of the raspistill methods when the
"test" build tag is specified. In this mode, raspistill simply provides "test" build tag is specified. In this mode, raspistill simply provides
arbitrary loaded JPEG images when Raspistill.Read() is called. specific test JPEG images when Raspistill.Read() is called.
AUTHORS AUTHORS
Saxon Nelson-Milton <saxon@ausocean.org> Saxon Nelson-Milton <saxon@ausocean.org>
@ -29,10 +29,9 @@ LICENSE
package raspistill package raspistill
import ( import (
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "path/filepath"
"strconv" "strconv"
"sync" "sync"
"time" "time"
@ -41,22 +40,23 @@ import (
) )
const ( const (
noOfImages = 6 // TODO(Saxon): find nImages programmatically ?
imgDir = "/go/src/bitbucket.org/ausocean/test/test-data/av/input/jpeg/" nImages = 6
jpgExt = ".jpg"
imgPath = "../../../test/test-data/av/input/jpeg/"
jpgExt = ".jpg"
) )
type raspistill struct { type raspistill struct {
images [nImages][]byte
imgCnt int // Number of images that have been loaded thus far.
durTicker *time.Ticker // Tracks timelapse duration.
intvlTicker *time.Ticker // Tracks current interval in the timelapse.
log config.Logger log config.Logger
cfg config.Config cfg config.Config
isRunning bool isRunning bool
images [noOfImages][]byte buf []byte // Holds frame data to be read.
imgCnt int term chan struct{} // Signals termination when close() is called.
durTicker *time.Ticker
intvlTicker *time.Ticker
buf []byte
init bool
term chan struct{}
mu sync.Mutex mu sync.Mutex
} }
@ -65,18 +65,13 @@ func new(l config.Logger) raspistill {
r := raspistill{log: l} r := raspistill{log: l}
// Get to the right file location of the JPEG images.
home, err := os.UserHomeDir()
if err != nil {
panic(fmt.Sprintf("could not get home directory: %v", err))
}
// Load the test images into the images slice. // Load the test images into the images slice.
// We expect the 6 images test images to be named 0.jpg through to 5.jpg. // We expect the 6 images test images to be named 0.jpg through to 5.jpg.
r.log.Debug("loading test JPEG images") r.log.Debug("loading test JPEG images")
for i, _ := range r.images { for i, _ := range r.images {
path := imgDir + strconv.Itoa(i) + jpgExt absPath, err := filepath.Abs(imgPath)
r.images[i], err = ioutil.ReadFile(home + imgDir + strconv.Itoa(i) + jpgExt) path := absPath + "/" + strconv.Itoa(i) + jpgExt
r.images[i], err = ioutil.ReadFile(path)
if err != nil { if err != nil {
r.log.Fatal("error loading test image", "imageNum", i, "error", err) r.log.Fatal("error loading test image", "imageNum", i, "error", err)
@ -86,16 +81,16 @@ func new(l config.Logger) raspistill {
return r return r
} }
// stop sets isRunning flag to false, indicating no further captures. Calls on // stop sets isRunning flag to false, indicating no further captures. Future
// Raspistill.read return error. // calls on Raspistill.read will return an error.
func (r *Raspistill) stop() error { func (r *Raspistill) stop() error {
r.log.Debug("stopping test raspistill") r.log.Debug("stopping test raspistill")
r.isRunning = false r.setRunning(false)
return nil return nil
} }
// start creates the timelapse interval and duration tickers i.e. also starting // start creates and starts the timelapse and duration tickers and sets
// them and sets isRunning flag to true indicating that raspistill is capturing. // isRunning flag to true indicating that raspistill is capturing.
func (r *Raspistill) start() error { func (r *Raspistill) start() error {
r.log.Debug("starting test raspistill") r.log.Debug("starting test raspistill")
r.durTicker = time.NewTicker(r.cfg.TimelapseDuration) r.durTicker = time.NewTicker(r.cfg.TimelapseDuration)
@ -113,8 +108,8 @@ func (r *Raspistill) start() error {
} }
func (r *Raspistill) loadImg() { func (r *Raspistill) loadImg() {
r.log.Debug("appending new image on to buffer and copying next image p", "imgCnt", r.imgCnt) r.log.Debug("appending new image on to buffer and copying next image p", "nImg", r.imgCnt)
imgBytes := r.images[r.imgCnt%noOfImages] imgBytes := r.images[r.imgCnt%nImages]
if len(imgBytes) == 0 { if len(imgBytes) == 0 {
panic("length of image bytes should not be 0") panic("length of image bytes should not be 0")
} }
@ -122,7 +117,7 @@ func (r *Raspistill) loadImg() {
r.mu.Lock() r.mu.Lock()
r.buf = append(r.buf, imgBytes...) r.buf = append(r.buf, imgBytes...)
r.log.Debug("added img to buf", "len(imgBytes)", len(imgBytes)) r.log.Debug("added image to buf", "nBytes", len(imgBytes))
r.mu.Unlock() r.mu.Unlock()
} }
@ -161,7 +156,6 @@ func (r *Raspistill) read(p []byte) (int, error) {
return 0, io.EOF return 0, io.EOF
} }
n := copy(p, r.buf) n := copy(p, r.buf)
r.log.Debug("copied", "p[:2]", p[:2], "p[n-2:n]", p[n-2:n])
r.buf = r.buf[n:] r.buf = r.buf[n:]
return n, nil return n, nil

View File

@ -49,27 +49,27 @@ const (
maxTimelapseInterval = 86400 * time.Second // s = 24 hours maxTimelapseInterval = 86400 * time.Second // s = 24 hours
) )
// Raspivid configuration defaults. // Raspistill configuration defaults.
const ( const (
defaultRotation = 0 // degrees defaultRotation = 0 // degrees
defaultWidth = 1280 // pixels defaultWidth = 1280 // pixels
defaultHeight = 720 // pixels defaultHeight = 720 // pixels
defaultSnapQuality = 75 // % defaultJPEGQuality = 75 // %
defaultTimelapseDuration = maxTimelapseDuration // ms defaultTimelapseDuration = maxTimelapseDuration // ms
defaultTimelapseInterval = 3600 * time.Second // ms defaultTimelapseInterval = 3600 * time.Second // ms
) )
// Configuration errors. // Configuration errors.
var ( var (
errBadRotation = fmt.Errorf("rotation bad or unset, defaulting to: %v", defaultRotation) errBadRotation = fmt.Errorf("Rotation bad or unset, defaulting to: %v", defaultRotation)
errBadWidth = fmt.Errorf("width bad or unset, defaulting to: %v", defaultWidth) errBadWidth = fmt.Errorf("Width bad or unset, defaulting to: %v", defaultWidth)
errBadHeight = fmt.Errorf("height bad or unset, defaulting to: %v", defaultHeight) errBadHeight = fmt.Errorf("Height bad or unset, defaulting to: %v", defaultHeight)
errBadSnapQuality = fmt.Errorf("SnapQuality bad or unset, defaulting to: %v", defaultSnapQuality) errBadJPEGQuality = fmt.Errorf("JPEGQuality bad or unset, defaulting to: %v", defaultJPEGQuality)
errBadTimelapseDuration = fmt.Errorf("TimelapseDuration bad or unset, defaulting to: %v", defaultTimelapseDuration) errBadTimelapseDuration = fmt.Errorf("TimelapseDuration bad or unset, defaulting to: %v", defaultTimelapseDuration)
errBadTimelapseInterval = fmt.Errorf("TimelapseInterval bad or unset, defaulting to: %v", defaultTimelapseInterval) errBadTimelapseInterval = fmt.Errorf("TimelapseInterval bad or unset, defaulting to: %v", defaultTimelapseInterval)
) )
// Misc erros. // Misc errors.
var errNotStarted = errors.New("cannot read, raspistill not started") var errNotStarted = errors.New("cannot read, raspistill not started")
// Raspistill is an implementation of AVDevice that provides control over the // Raspistill is an implementation of AVDevice that provides control over the
@ -77,7 +77,7 @@ var errNotStarted = errors.New("cannot read, raspistill not started")
// singular images. // singular images.
type Raspistill struct{ raspistill } type Raspistill struct{ raspistill }
// New returns a new Raspivid. // New returns a new Raspistill.
func New(l config.Logger) *Raspistill { return &Raspistill{raspistill: new(l)} } func New(l config.Logger) *Raspistill { return &Raspistill{raspistill: new(l)} }
// Start will prepare the arguments for the raspistill command using the // Start will prepare the arguments for the raspistill command using the
@ -119,9 +119,9 @@ func (r *Raspistill) Set(c config.Config) error {
errs = append(errs, errBadHeight) errs = append(errs, errBadHeight)
} }
if c.SnapQuality < 0 || c.SnapQuality > 100 { if c.JPEGQuality < 0 || c.JPEGQuality > 100 {
c.SnapQuality = defaultSnapQuality c.JPEGQuality = defaultJPEGQuality
errs = append(errs, errBadSnapQuality) errs = append(errs, errBadJPEGQuality)
} }
if c.TimelapseDuration > maxTimelapseDuration || c.TimelapseDuration < minTimelapseDuration { if c.TimelapseDuration > maxTimelapseDuration || c.TimelapseDuration < minTimelapseDuration {

View File

@ -234,14 +234,14 @@ type Config struct {
SampleRate uint // Samples a second (Hz). SampleRate uint // Samples a second (Hz).
Saturation int Saturation int
// SnapQuality is a value 0-100 inclusive, controlling JPEG compression of the // JPEGQuality is a value 0-100 inclusive, controlling JPEG compression of the
// timelapse snaps. 100 represents minimal compression and 0 represents the most // timelapse snaps. 100 represents minimal compression and 0 represents the most
// compression. // compression.
SnapQuality int JPEGQuality int
Suppress bool // Holds logger suppression state. Suppress bool // Holds logger suppression state.
// TimelapseInterval defines the interval between timelapse snaps when using // TimelapseInterval defines the interval between timelapse images when using
// raspistill input. // raspistill input.
TimelapseInterval time.Duration TimelapseInterval time.Duration

View File

@ -86,7 +86,7 @@ const (
KeyRTPAddress = "RTPAddress" KeyRTPAddress = "RTPAddress"
KeySampleRate = "SampleRate" KeySampleRate = "SampleRate"
KeySaturation = "Saturation" KeySaturation = "Saturation"
KeySnapQuality = "SnapQuality" KeyJPEGQuality = "JPEGQuality"
KeySuppress = "Suppress" KeySuppress = "Suppress"
KeyTimelapseDuration = "TimelapseDuration" KeyTimelapseDuration = "TimelapseDuration"
KeyTimelapseInterval = "TimelapseInterval" KeyTimelapseInterval = "TimelapseInterval"
@ -578,14 +578,14 @@ var Variables = []struct {
}, },
}, },
{ {
Name: KeySnapQuality, Name: KeyJPEGQuality,
Type_: typeUint, Type_: typeUint,
Update: func(c *Config, v string) { Update: func(c *Config, v string) {
_v, err := strconv.Atoi(v) _v, err := strconv.Atoi(v)
if err != nil { if err != nil {
c.Logger.Log(logger.Warning, "invalid SnapQuality param", "value", v) c.Logger.Log(logger.Warning, "invalid JPEGQuality param", "value", v)
} }
c.SnapQuality = _v c.JPEGQuality = _v
}, },
}, },
{ {