revid/pipeline.go: improved handling of undefined pipeline permutations

We no longer panic for undefined pipeline permutations that have got past config package validation i.e. it's not possible to crash revid from setting things remotely incorrectly
This commit is contained in:
Saxon Nelson-Milton 2020-12-16 15:16:38 +10:30
parent 2f75e6a291
commit e42b0ea428
1 changed files with 22 additions and 16 deletions

View File

@ -69,7 +69,7 @@ func (r *Revid) reset(c config.Config) error {
r.cfg.Logger.Log(logger.Debug, "setting config") r.cfg.Logger.Log(logger.Debug, "setting config")
err := r.setConfig(c) err := r.setConfig(c)
if err != nil { if err != nil {
return err return fmt.Errorf("could not set config: %w",err)
} }
r.cfg.Logger.Log(logger.Info, "config set") r.cfg.Logger.Log(logger.Info, "config set")
@ -85,7 +85,7 @@ func (r *Revid) reset(c config.Config) error {
switch r.cfg.InputCodec { switch r.cfg.InputCodec {
case codecutil.H265: case codecutil.H265:
if r.cfg.Input != config.InputRTSP { if r.cfg.Input != config.InputRTSP {
panic("H265 codec valid only for InputRTSP") return nil, errors.New("h.265 codec valid only for InputRTSP")
} }
st = mts.EncodeH265 st = mts.EncodeH265
case codecutil.H264: case codecutil.H264:
@ -94,8 +94,10 @@ func (r *Revid) reset(c config.Config) error {
st = mts.EncodeMJPEG st = mts.EncodeMJPEG
encOptions = append(encOptions, mts.TimeBasedPSI(time.Duration(r.cfg.PSITime)*time.Second)) encOptions = append(encOptions, mts.TimeBasedPSI(time.Duration(r.cfg.PSITime)*time.Second))
r.cfg.CBR = true r.cfg.CBR = true
case codecutil.PCM, codecutil.ADPCM:
return nil, errors.New(fmt.Sprintf("invalid input codec: %v for input: %v",r.cfg.InputCodec,r.cfg.Input))
default: default:
panic("unknown input codec for Raspivid, File, V4l or RTSP input") panic("unknown input codec")
} }
case config.InputAudio: case config.InputAudio:
st = mts.EncodeAudio st = mts.EncodeAudio
@ -115,7 +117,7 @@ func (r *Revid) reset(c config.Config) error {
r.cfg.Logger.Log(logger.Info, "finished setting pipeline") r.cfg.Logger.Log(logger.Info, "finished setting pipeline")
if err != nil { if err != nil {
return err return fmt.Errorf("could not set up pipeline: %w",err)
} }
return nil return nil
@ -246,46 +248,47 @@ func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate float64) (io.
r.cfg.Logger.Log(logger.Debug, "using go difference filter") r.cfg.Logger.Log(logger.Debug, "using go difference filter")
r.filters[i] = filter.NewBasic(dst, r.cfg) r.filters[i] = filter.NewBasic(dst, r.cfg)
default: default:
panic("Undefined Filter") panic("unknown filter")
} }
dst = r.filters[i] dst = r.filters[i]
} }
r.cfg.Logger.Log(logger.Info, "filters set up") r.cfg.Logger.Log(logger.Info, "filters set up")
} }
var err error
switch r.cfg.Input { switch r.cfg.Input {
case config.InputRaspivid: case config.InputRaspivid:
r.cfg.Logger.Log(logger.Debug, "using raspivid input") r.cfg.Logger.Log(logger.Debug, "using raspivid input")
r.input = raspivid.New(r.cfg.Logger) r.input = raspivid.New(r.cfg.Logger)
r.setLexer(r.cfg.InputCodec, false) err = r.setLexer(r.cfg.InputCodec, false)
case config.InputV4L: case config.InputV4L:
r.cfg.Logger.Log(logger.Debug, "using V4L input") r.cfg.Logger.Log(logger.Debug, "using V4L input")
r.input = webcam.New(r.cfg.Logger) r.input = webcam.New(r.cfg.Logger)
r.setLexer(r.cfg.InputCodec, false) err = r.setLexer(r.cfg.InputCodec, false)
case config.InputFile: case config.InputFile:
r.cfg.Logger.Log(logger.Debug, "using file input") r.cfg.Logger.Log(logger.Debug, "using file input")
r.input = file.New() r.input = file.New()
r.setLexer(r.cfg.InputCodec, false) err = r.setLexer(r.cfg.InputCodec, false)
case config.InputRTSP: case config.InputRTSP:
r.cfg.Logger.Log(logger.Debug, "using RTSP input") r.cfg.Logger.Log(logger.Debug, "using RTSP input")
r.input = geovision.New(r.cfg.Logger) r.input = geovision.New(r.cfg.Logger)
r.setLexer(r.cfg.InputCodec, true) err = r.setLexer(r.cfg.InputCodec, true)
case config.InputAudio: case config.InputAudio:
r.cfg.Logger.Log(logger.Debug, "using audio input") r.cfg.Logger.Log(logger.Debug, "using audio input")
err := r.setupAudio() err = r.setupAudio()
if err != nil { }
return err if err != nil {
} return fmt.Errorf("could not set lexer: %w",err)
} }
// Configure the input device. We know that defaults are set, so no need to // Configure the input device. We know that defaults are set, so no need to
// return error, but we should log. // return error, but we should log.
r.cfg.Logger.Log(logger.Debug, "configuring input device") r.cfg.Logger.Log(logger.Debug, "configuring input device")
err := r.input.Set(r.cfg) err = r.input.Set(r.cfg)
if err != nil { if err != nil {
r.cfg.Logger.Log(logger.Warning, "errors from configuring input device", "errors", err) r.cfg.Logger.Log(logger.Warning, "errors from configuring input device", "errors", err)
} }
@ -296,7 +299,7 @@ func (r *Revid) setupPipeline(mtsEnc func(dst io.WriteCloser, rate float64) (io.
// setLexer sets the revid input lexer based on input codec and whether input // setLexer sets the revid input lexer based on input codec and whether input
// is RTSP or not, in which case an RTP/<codec> extractor is used. // is RTSP or not, in which case an RTP/<codec> extractor is used.
func (r *Revid) setLexer(c uint8, isRTSP bool) { func (r *Revid) setLexer(c uint8, isRTSP bool) error {
switch c { switch c {
case codecutil.H264: case codecutil.H264:
r.cfg.Logger.Log(logger.Debug, "using H.264 codec") r.cfg.Logger.Log(logger.Debug, "using H.264 codec")
@ -308,7 +311,7 @@ func (r *Revid) setLexer(c uint8, isRTSP bool) {
r.cfg.Logger.Log(logger.Debug, "using H.265 codec") r.cfg.Logger.Log(logger.Debug, "using H.265 codec")
r.lexTo = h265.NewExtractor(false).Extract r.lexTo = h265.NewExtractor(false).Extract
if !isRTSP { if !isRTSP {
panic("byte stream H.265 lexing not implemented") return errors.New("byte stream h.265 lexing not implemented")
} }
case codecutil.MJPEG: case codecutil.MJPEG:
r.cfg.Logger.Log(logger.Debug, "using MJPEG codec") r.cfg.Logger.Log(logger.Debug, "using MJPEG codec")
@ -316,9 +319,12 @@ func (r *Revid) setLexer(c uint8, isRTSP bool) {
if isRTSP { if isRTSP {
r.lexTo = mjpeg.NewExtractor().Extract r.lexTo = mjpeg.NewExtractor().Extract
} }
case codecutil.PCM, codecutil.ADPCM:
return errors.New("invalid codec for this selected input")
default: default:
panic("unrecognised codec") panic("unrecognised codec")
} }
return nil
} }
// processFrom is run as a routine to read from a input data source, lex and // processFrom is run as a routine to read from a input data source, lex and