mirror of https://bitbucket.org/ausocean/av.git
revid: clean up input handling
This commit is contained in:
parent
4fc6e69b12
commit
647641bed6
108
revid/revid.go
108
revid/revid.go
|
@ -36,7 +36,6 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
|
@ -88,7 +87,6 @@ type Revid struct {
|
|||
ringBuffer *ring.Buffer
|
||||
config Config
|
||||
isRunning bool
|
||||
inputFile *os.File
|
||||
generator generator.Generator
|
||||
parser parser.Parser
|
||||
cmd *exec.Cmd
|
||||
|
@ -172,7 +170,7 @@ func (r *Revid) reset(config Config) error {
|
|||
|
||||
switch r.config.Input {
|
||||
case Raspivid:
|
||||
r.setupInput = r.setupInputForRaspivid
|
||||
r.setupInput = r.startRaspivid
|
||||
case File:
|
||||
r.setupInput = r.setupInputForFile
|
||||
}
|
||||
|
@ -432,13 +430,14 @@ func (r *Revid) outputClips() {
|
|||
}
|
||||
}
|
||||
|
||||
// setupInputForRaspivid sets up things for input from raspivid i.e. starts
|
||||
// startRaspivid sets up things for input from raspivid i.e. starts
|
||||
// a raspivid process and pipes it's data output.
|
||||
func (r *Revid) setupInputForRaspivid() error {
|
||||
func (r *Revid) startRaspivid() error {
|
||||
r.Log(Info, "Starting raspivid!")
|
||||
switch r.config.InputCodec {
|
||||
case H264:
|
||||
arguments := []string{"-cd", "H264",
|
||||
args := []string{
|
||||
"-cd", "H264",
|
||||
"-o", "-",
|
||||
"-n",
|
||||
"-t", r.config.Timeout,
|
||||
|
@ -449,33 +448,18 @@ func (r *Revid) setupInputForRaspivid() error {
|
|||
"-ih",
|
||||
"-g", r.config.IntraRefreshPeriod,
|
||||
}
|
||||
|
||||
if r.config.QuantizationMode == QuantizationOn {
|
||||
arguments = append(arguments, "-qp")
|
||||
arguments = append(arguments, r.config.Quantization)
|
||||
args = append(args, "-qp", r.config.Quantization)
|
||||
}
|
||||
|
||||
if r.config.HorizontalFlip == Yes {
|
||||
arguments = append(arguments, "-hf")
|
||||
args = append(args, "-hf")
|
||||
}
|
||||
if r.config.VerticalFlip == Yes {
|
||||
args = append(args, "-vf")
|
||||
}
|
||||
|
||||
if r.config.VerticalFlip == Yes {
|
||||
arguments = append(arguments, "-vf")
|
||||
}
|
||||
name := "raspivid"
|
||||
r.cmd = &exec.Cmd{
|
||||
Path: name,
|
||||
Args: append([]string{name}, arguments...),
|
||||
}
|
||||
r.Log(Info, fmt.Sprintf("Startin raspivid with args: %v", r.cmd.Args))
|
||||
if filepath.Base(name) == name {
|
||||
if lp, err := exec.LookPath(name); err != nil {
|
||||
r.Log(Error, err.Error())
|
||||
return err
|
||||
} else {
|
||||
r.cmd.Path = lp
|
||||
}
|
||||
}
|
||||
r.Log(Info, fmt.Sprintf("Starting raspivid with args: %v", args))
|
||||
r.cmd = exec.Command("raspivid", args...)
|
||||
|
||||
case Mjpeg:
|
||||
r.cmd = exec.Command("raspivid",
|
||||
|
@ -486,31 +470,29 @@ func (r *Revid) setupInputForRaspivid() error {
|
|||
"-fps", r.config.FrameRate,
|
||||
)
|
||||
}
|
||||
stdout, _ := r.cmd.StdoutPipe()
|
||||
go r.cmd.Run()
|
||||
stdout, err := r.cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = r.cmd.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.inputReader = bufio.NewReader(stdout)
|
||||
go r.readCamera()
|
||||
return nil
|
||||
}
|
||||
|
||||
// setupInputForFile sets things up for getting input from a file
|
||||
func (r *Revid) setupInputForFile() error {
|
||||
fps, _ := strconv.Atoi(r.config.FrameRate)
|
||||
r.parser.SetDelay(uint(float64(1000) / float64(fps)))
|
||||
r.readFile()
|
||||
return nil
|
||||
}
|
||||
|
||||
// readCamera reads data from the defined camera while the Revid is running.
|
||||
// TODO: use ringbuffer here instead of allocating mem every time!
|
||||
func (r *Revid) readCamera() {
|
||||
r.Log(Info, "Reading camera data!")
|
||||
for r.isRunning {
|
||||
data := make([]byte, 1)
|
||||
_, err := io.ReadFull(r.inputReader, data)
|
||||
var data [1]byte
|
||||
_, err := io.ReadFull(r.inputReader, data[:])
|
||||
switch {
|
||||
// We know this means we're getting nothing from the cam
|
||||
case (err != nil && err.Error() == "EOF" && r.isRunning) || (err != nil && r.isRunning):
|
||||
case err != nil && r.isRunning:
|
||||
r.Log(Error, "No data from camera!")
|
||||
time.Sleep(cameraRetryPeriod)
|
||||
default:
|
||||
|
@ -520,31 +502,39 @@ func (r *Revid) readCamera() {
|
|||
r.Log(Info, "Not trying to read from camera anymore!")
|
||||
}
|
||||
|
||||
// setupInputForFile sets things up for getting input from a file
|
||||
func (r *Revid) setupInputForFile() error {
|
||||
fps, err := strconv.Atoi(r.config.FrameRate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.parser.SetDelay(uint(float64(1000) / float64(fps)))
|
||||
return r.readFile()
|
||||
}
|
||||
|
||||
// readFile reads data from the defined file while the Revid is running.
|
||||
func (r *Revid) readFile() error {
|
||||
var err error
|
||||
r.inputFile, err = os.Open(r.config.InputFileName)
|
||||
f, err := os.Open(r.config.InputFileName)
|
||||
if err != nil {
|
||||
r.Log(Error, err.Error())
|
||||
r.Stop()
|
||||
return err
|
||||
}
|
||||
stats, err := r.inputFile.Stat()
|
||||
if err != nil {
|
||||
r.Log(Error, "Could not get input file stats!")
|
||||
r.Stop()
|
||||
return err
|
||||
defer f.Close()
|
||||
var buf [1 << 12]byte
|
||||
for {
|
||||
n, err := f.Read(buf[:])
|
||||
for _, b := range buf[:n] {
|
||||
r.parser.InputChan() <- b
|
||||
}
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
r.Log(Error, err.Error())
|
||||
r.Stop()
|
||||
return err
|
||||
}
|
||||
}
|
||||
data := make([]byte, stats.Size())
|
||||
_, err = r.inputFile.Read(data)
|
||||
if err != nil {
|
||||
r.Log(Error, err.Error())
|
||||
r.Stop()
|
||||
return err
|
||||
}
|
||||
for i := range data {
|
||||
r.parser.InputChan() <- data[i]
|
||||
}
|
||||
r.inputFile.Close()
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue