From ed4d97f893414b3d1f19edc305e4e82c382eaf73 Mon Sep 17 00:00:00 2001 From: saxon Date: Thu, 31 Jan 2019 15:03:50 +1030 Subject: [PATCH] stream/mts: patch for revid.Start() no exit bug --- revid/revid.go | 51 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index 9de472e1..df1e111a 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -120,6 +120,8 @@ type Revid struct { // isRunning is a loaded and cocked foot-gun. isRunning bool + + err chan error } // packer takes data segments and packs them into clips @@ -176,13 +178,29 @@ func (p *packer) Write(frame []byte) (int, error) { // New returns a pointer to a new Revid with the desired configuration, and/or // an error if construction of the new instance was not successful. func New(c Config, ns *netsender.Sender) (*Revid, error) { - r := Revid{ns: ns} + r := Revid{ns: ns, err: make(chan error)} r.buffer = ring.NewBuffer(ringBufferSize, ringBufferElementSize, writeTimeout) r.packer.owner = &r err := r.reset(c) if err != nil { return nil, err } + go func() { + for { + err := <-r.err + if err != nil { + r.config.Logger.Log(logger.Error, pkg+"async error", "error", err.Error()) + err = r.Stop() + if err != nil { + r.config.Logger.Log(logger.Fatal, pkg+"failed to stop", "error", err.Error()) + } + r.Start() + if err != nil { + r.config.Logger.Log(logger.Fatal, pkg+"failed to restart", "error", err.Error()) + } + } + } + }() return &r, nil } @@ -312,8 +330,8 @@ func (r *Revid) Start() error { r.config.Logger.Log(logger.Info, pkg+"starting output routine") go r.outputClips() r.config.Logger.Log(logger.Info, pkg+"setting up input and receiving content") - err := r.setupInput() - return err + go r.setupInput() + return nil } // Stop halts any processing of video data from a camera or file @@ -474,11 +492,13 @@ func (r *Revid) startRaspivid() error { r.config.Logger.Log(logger.Fatal, pkg+"cannot start raspivid", "error", err.Error()) } - r.config.Logger.Log(logger.Info, pkg+"reading camera data") - delay := time.Second / time.Duration(r.config.FrameRate) - err = r.lexTo(r.encoder, stdout, delay) - r.config.Logger.Log(logger.Info, pkg+"finished reading camera data") - return err + go func() { + r.config.Logger.Log(logger.Info, pkg+"reading camera data") + delay := time.Second / time.Duration(r.config.FrameRate) + r.err <- r.lexTo(r.encoder, stdout, delay) + r.config.Logger.Log(logger.Info, pkg+"finished reading camera data") + }() + return nil } func (r *Revid) startV4L() error { @@ -526,10 +546,12 @@ func (r *Revid) startV4L() error { return err } - r.config.Logger.Log(logger.Info, pkg+"reading camera data") - err = r.lexTo(r.encoder, stdout, delay) - r.config.Logger.Log(logger.Info, pkg+"finished reading camera data") - return err + go func() { + r.config.Logger.Log(logger.Info, pkg+"reading camera data") + r.err <- r.lexTo(r.encoder, stdout, delay) + r.config.Logger.Log(logger.Info, pkg+"finished reading camera data") + }() + return nil } // setupInputForFile sets things up for getting input from a file @@ -544,5 +566,8 @@ func (r *Revid) setupInputForFile() error { defer f.Close() // TODO(kortschak): Maybe we want a context.Context-aware parser that we can stop. - return r.lexTo(r.encoder, f, delay) + go func() { + r.err <- r.lexTo(r.encoder, f, delay) + }() + return nil }