cmd/revid-cli,revid: reduce stringly typing in config/flags

This commit is contained in:
Dan Kortschak 2018-12-10 09:39:20 +10:30
parent 5a181f3576
commit 1e3b4b1ab8
4 changed files with 129 additions and 230 deletions

View File

@ -33,6 +33,7 @@ import (
"os" "os"
"runtime/pprof" "runtime/pprof"
"strconv" "strconv"
"strings"
"time" "time"
"bitbucket.org/ausocean/av/revid" "bitbucket.org/ausocean/av/revid"
@ -101,22 +102,21 @@ func handleFlags() revid.Config {
output2Ptr = flag.String("Output2", "", "The second output type: Http, Rtmp, File, Udp, Rtp") output2Ptr = flag.String("Output2", "", "The second output type: Http, Rtmp, File, Udp, Rtp")
rtmpMethodPtr = flag.String("RtmpMethod", "", "The method used to send over rtmp: Ffmpeg, Librtmp") rtmpMethodPtr = flag.String("RtmpMethod", "", "The method used to send over rtmp: Ffmpeg, Librtmp")
packetizationPtr = flag.String("Packetization", "", "The method of data packetisation: Flv, Mpegts, None") packetizationPtr = flag.String("Packetization", "", "The method of data packetisation: Flv, Mpegts, None")
quantizationModePtr = flag.String("QuantizationMode", "", "Whether quantization if on or off (variable bitrate): On, Off") quantizePtr = flag.Bool("Quantize", false, "Quantize input (non-variable bitrate)")
verbosityPtr = flag.String("Verbosity", "", "Verbosity: Info, Warning, Error, Fatal") verbosityPtr = flag.String("Verbosity", "", "Verbosity: Info, Warning, Error, Fatal")
framesPerClipPtr = flag.String("FramesPerClip", "", "Number of frames per clip sent") framesPerClipPtr = flag.Uint("FramesPerClip", 0, "Number of frames per clip sent")
rtmpUrlPtr = flag.String("RtmpUrl", "", "Url of rtmp endpoint") rtmpUrlPtr = flag.String("RtmpUrl", "", "Url of rtmp endpoint")
bitratePtr = flag.String("Bitrate", "", "Bitrate of recorded video") bitratePtr = flag.Uint("Bitrate", 0, "Bitrate of recorded video")
outputFileNamePtr = flag.String("OutputFileName", "", "The directory of the output file") outputFileNamePtr = flag.String("OutputFileName", "", "The directory of the output file")
inputFileNamePtr = flag.String("InputFileName", "", "The directory of the input file") inputFileNamePtr = flag.String("InputFileName", "", "The directory of the input file")
heightPtr = flag.String("Height", "", "Height in pixels") heightPtr = flag.Uint("Height", 0, "Height in pixels")
widthPtr = flag.String("Width", "", "Width in pixels") widthPtr = flag.Uint("Width", 0, "Width in pixels")
frameRatePtr = flag.String("FrameRate", "", "Frame rate of captured video") frameRatePtr = flag.Uint("FrameRate", 0, "Frame rate of captured video")
httpAddressPtr = flag.String("HttpAddress", "", "Destination address of http posts") httpAddressPtr = flag.String("HttpAddress", "", "Destination address of http posts")
quantizationPtr = flag.String("Quantization", "", "Desired quantization value: 0-40") quantizationPtr = flag.Uint("Quantization", 0, "Desired quantization value: 0-40")
timeoutPtr = flag.String("Timeout", "", "Http timeout in seconds") intraRefreshPeriodPtr = flag.Uint("IntraRefreshPeriod", 0, "The IntraRefreshPeriod i.e. how many keyframes we send")
intraRefreshPeriodPtr = flag.String("IntraRefreshPeriod", "", "The IntraRefreshPeriod i.e. how many keyframes we send") verticalFlipPtr = flag.Bool("VerticalFlip", false, "Flip video vertically: Yes, No")
verticalFlipPtr = flag.String("VerticalFlip", "", "Flip video vertically: Yes, No") horizontalFlipPtr = flag.Bool("HorizontalFlip", false, "Flip video horizontally: Yes, No")
horizontalFlipPtr = flag.String("HorizontalFlip", "", "Flip video horizontally: Yes, No")
logPathPtr = flag.String("LogPath", defaultLogPath, "Path for logging files (default is /var/log/netsender/)") logPathPtr = flag.String("LogPath", defaultLogPath, "Path for logging files (default is /var/log/netsender/)")
rtpAddrPtr = flag.String("RtpAddr", "", "Rtp destination address: <IP>:<port> (port is generally 6970-6999)") rtpAddrPtr = flag.String("RtpAddr", "", "Rtp destination address: <IP>:<port> (port is generally 6970-6999)")
) )
@ -218,16 +218,6 @@ func handleFlags() revid.Config {
logger.Log(smartlogger.Error, pkg+"bad packetization argument") logger.Log(smartlogger.Error, pkg+"bad packetization argument")
} }
switch *quantizationModePtr {
case "QuantizationOn":
cfg.QuantizationMode = revid.QuantizationOn
case "QuantizationOff":
cfg.QuantizationMode = revid.QuantizationOff
case "":
default:
logger.Log(smartlogger.Error, pkg+"bad quantization mode argument")
}
switch *verbosityPtr { switch *verbosityPtr {
case "No": case "No":
cfg.LogLevel = smartlogger.Fatal cfg.LogLevel = smartlogger.Fatal
@ -239,32 +229,10 @@ func handleFlags() revid.Config {
logger.Log(smartlogger.Error, pkg+"bad verbosity argument") logger.Log(smartlogger.Error, pkg+"bad verbosity argument")
} }
switch *horizontalFlipPtr { cfg.Quantize = *quantizePtr
case "No": cfg.FlipHorizontal = *horizontalFlipPtr
cfg.FlipHorizontal = false cfg.FlipVertical = *verticalFlipPtr
case "Yes": cfg.FramesPerClip = *framesPerClipPtr
cfg.FlipHorizontal = true
case "":
cfg.FlipHorizontal = false
default:
logger.Log(smartlogger.Error, pkg+"bad horizontal flip option")
}
switch *verticalFlipPtr {
case "No":
cfg.FlipVertical = false
case "Yes":
cfg.FlipVertical = true
case "":
cfg.FlipVertical = false
default:
logger.Log(smartlogger.Error, pkg+"bad vertical flip option")
}
fpc, err := strconv.Atoi(*framesPerClipPtr)
if err == nil && fpc > 0 {
cfg.FramesPerClip = fpc
}
cfg.RtmpUrl = *rtmpUrlPtr cfg.RtmpUrl = *rtmpUrlPtr
cfg.Bitrate = *bitratePtr cfg.Bitrate = *bitratePtr
cfg.OutputFileName = *outputFileNamePtr cfg.OutputFileName = *outputFileNamePtr
@ -274,7 +242,6 @@ func handleFlags() revid.Config {
cfg.FrameRate = *frameRatePtr cfg.FrameRate = *frameRatePtr
cfg.HttpAddress = *httpAddressPtr cfg.HttpAddress = *httpAddressPtr
cfg.Quantization = *quantizationPtr cfg.Quantization = *quantizationPtr
cfg.Timeout = *timeoutPtr
cfg.IntraRefreshPeriod = *intraRefreshPeriodPtr cfg.IntraRefreshPeriod = *intraRefreshPeriodPtr
cfg.RtpAddress = *rtpAddrPtr cfg.RtpAddress = *rtpAddrPtr
@ -406,79 +373,76 @@ func updateRevid(ns *netsender.Sender, rv *revid.Revid, cfg revid.Config, vars m
continue continue
} }
case "FramesPerClip": case "FramesPerClip":
fpc, err := strconv.Atoi(value) f, err := strconv.ParseUint(value, 10, 0)
if fpc > 0 && err == nil { if err != nil {
cfg.FramesPerClip = fpc logger.Log(smartlogger.Warning, pkg+"invalid framesperclip param", "value", value)
} else { break
logger.Log(smartlogger.Warning, pkg+"invalid FramesPerClip param", "value", value)
} }
cfg.FramesPerClip = uint(f)
case "RtmpUrl": case "RtmpUrl":
cfg.RtmpUrl = value cfg.RtmpUrl = value
case "Bitrate": case "Bitrate":
asInt, err := strconv.Atoi(value) r, err := strconv.ParseUint(value, 10, 0)
if asInt > 0 && err == nil { if err != nil {
cfg.Bitrate = value logger.Log(smartlogger.Warning, pkg+"invalid framerate param", "value", value)
} else { break
logger.Log(smartlogger.Warning, pkg+"invalid Bitrate param", "value", value)
} }
cfg.Bitrate = uint(r)
case "OutputFileName": case "OutputFileName":
cfg.OutputFileName = value cfg.OutputFileName = value
case "InputFileName": case "InputFileName":
cfg.InputFileName = value cfg.InputFileName = value
case "Height": case "Height":
asInt, err := strconv.Atoi(value) h, err := strconv.ParseUint(value, 10, 0)
if asInt > 0 && err == nil { if err != nil {
cfg.Height = value logger.Log(smartlogger.Warning, pkg+"invalid height param", "value", value)
} else { break
logger.Log(smartlogger.Warning, pkg+"invalid Height param", "value", value)
} }
cfg.Height = uint(h)
case "Width": case "Width":
asInt, err := strconv.Atoi(value) w, err := strconv.ParseUint(value, 10, 0)
if asInt > 0 && err == nil { if err != nil {
cfg.Width = value logger.Log(smartlogger.Warning, pkg+"invalid width param", "value", value)
} else { break
logger.Log(smartlogger.Warning, pkg+"invalid Width param", "value", value)
} }
cfg.Width = uint(w)
case "FrameRate": case "FrameRate":
asInt, err := strconv.Atoi(value) r, err := strconv.ParseUint(value, 10, 0)
if asInt > 0 && err == nil { if err != nil {
cfg.FrameRate = value logger.Log(smartlogger.Warning, pkg+"invalid framerate param", "value", value)
} else { break
logger.Log(smartlogger.Warning, pkg+"invalid FrameRate param", "value", value)
} }
cfg.FrameRate = uint(r)
case "HttpAddress": case "HttpAddress":
cfg.HttpAddress = value cfg.HttpAddress = value
case "Quantization": case "Quantization":
asInt, err := strconv.Atoi(value) q, err := strconv.ParseUint(value, 10, 0)
if asInt > 0 && err == nil { if err != nil {
cfg.Quantization = value logger.Log(smartlogger.Warning, pkg+"invalid quantization param", "value", value)
} else { break
logger.Log(smartlogger.Warning, pkg+"invalid Quantization param", "value", value)
}
case "Timeout":
asInt, err := strconv.Atoi(value)
if asInt > 0 && err == nil {
cfg.Timeout = value
} }
cfg.Quantization = uint(q)
case "IntraRefreshPeriod": case "IntraRefreshPeriod":
asInt, err := strconv.Atoi(value) p, err := strconv.ParseUint(value, 10, 0)
if asInt > 0 && err == nil { if err != nil {
cfg.IntraRefreshPeriod = value logger.Log(smartlogger.Warning, pkg+"invalid intrarefreshperiod param", "value", value)
break
} }
cfg.IntraRefreshPeriod = uint(p)
case "HorizontalFlip": case "HorizontalFlip":
switch value { switch strings.ToLower(value) {
case "Yes": case "true":
cfg.FlipHorizontal = true cfg.FlipHorizontal = true
case "No": case "false":
cfg.FlipHorizontal = false cfg.FlipHorizontal = false
default: default:
logger.Log(smartlogger.Warning, pkg+"invalid HorizontalFlip param", "value", value) logger.Log(smartlogger.Warning, pkg+"invalid HorizontalFlip param", "value", value)
} }
case "VerticalFlip": case "VerticalFlip":
switch value { switch strings.ToLower(value) {
case "Yes": case "true":
cfg.FlipVertical = true cfg.FlipVertical = true
case "No": case "false":
cfg.FlipVertical = false cfg.FlipVertical = false
default: default:
logger.Log(smartlogger.Warning, pkg+"invalid VerticalFlip param", "value", value) logger.Log(smartlogger.Warning, pkg+"invalid VerticalFlip param", "value", value)

View File

@ -29,7 +29,6 @@ package revid
import ( import (
"errors" "errors"
"strconv"
"bitbucket.org/ausocean/utils/smartlogger" "bitbucket.org/ausocean/utils/smartlogger"
) )
@ -37,32 +36,36 @@ import (
// Config provides parameters relevant to a revid instance. A new config must // Config provides parameters relevant to a revid instance. A new config must
// be passed to the constructor. // be passed to the constructor.
type Config struct { type Config struct {
LogLevel int8
Input uint8 Input uint8
InputCodec uint8 InputCodec uint8
Output1 uint8 Output1 uint8
Output2 uint8 Output2 uint8
RtmpMethod uint8 RtmpMethod uint8
Packetization uint8 Packetization uint8
QuantizationMode uint8
LogLevel int8 // Quantize specifies whether the input to
// revid will have constant or variable
// bitrate.
Quantize bool
// FlipHorizonatla and FlipVertical specify // FlipHorizonatla and FlipVertical specify
// whether video frames should be flipped. // whether video frames should be flipped.
FlipHorizontal bool FlipHorizontal bool
FlipVertical bool FlipVertical bool
FramesPerClip int FramesPerClip uint
RtmpUrl string RtmpUrl string
Bitrate string Bitrate uint
OutputFileName string OutputFileName string
InputFileName string InputFileName string
Height string Height uint
Width string Width uint
FrameRate string FrameRate uint
HttpAddress string HttpAddress string
Quantization string Quantization uint
Timeout string IntraRefreshPeriod uint
IntraRefreshPeriod string
RtpAddress string RtpAddress string
Logger Logger Logger Logger
SendRetry bool SendRetry bool
@ -98,20 +101,18 @@ const (
defaultInput = Raspivid defaultInput = Raspivid
defaultOutput = Http defaultOutput = Http
defaultPacketization = Flv defaultPacketization = Flv
defaultFrameRate = "25" defaultFrameRate = 25
defaultWidth = "1280" defaultWidth = 1280
defaultHeight = "720" defaultHeight = 720
defaultIntraRefreshPeriod = "100" defaultIntraRefreshPeriod = 100
defaultTimeout = "0" defaultTimeout = 0
defaultQuantization = "40" defaultQuantization = 40
defaultBitrate = "400000" defaultBitrate = 400000
defaultQuantizationMode = QuantizationOff defaultQuantizationMode = QuantizationOff
defaultFramesPerClip = 1 defaultFramesPerClip = 1
defaultVerticalFlip = No
defaultHorizontalFlip = No
httpFramesPerClip = 560 httpFramesPerClip = 560
defaultInputCodec = H264 defaultInputCodec = H264
defaultVerbosity = No defaultVerbosity = No // FIXME(kortschak): This makes no sense whatsoever. No is currently 15.
defaultRtpAddr = "localhost:6970" defaultRtpAddr = "localhost:6970"
) )
@ -129,17 +130,6 @@ func (c *Config) Validate(r *Revid) error {
return errors.New("bad LogLevel defined in config") return errors.New("bad LogLevel defined in config")
} }
switch c.QuantizationMode {
case QuantizationOn:
case QuantizationOff:
case NothingDefined:
c.Logger.Log(smartlogger.Warning, pkg+"no quantization mode defined, defaulting",
"quantizationMode", QuantizationOff)
c.QuantizationMode = QuantizationOff
default:
return errors.New("bad QuantizationMode defined in config")
}
switch c.Input { switch c.Input {
case Raspivid: case Raspivid:
case File: case File:
@ -153,29 +143,23 @@ func (c *Config) Validate(r *Revid) error {
switch c.InputCodec { switch c.InputCodec {
case H264: case H264:
if c.Bitrate != "" && c.Quantization != "" { // FIXME(kortschak): This is not really what we want.
bitrate, err := strconv.Atoi(c.Bitrate) // Configuration really needs to be rethought here.
if err != nil { if c.Quantize && c.Quantization == 0 {
return errors.New("bitrate not an integer") c.Quantization = defaultQuantization
} else {
c.Bitrate = defaultBitrate
} }
quantization, err := strconv.Atoi(c.Quantization)
if err != nil { if (c.Bitrate > 0 && c.Quantization > 0) || (c.Bitrate == 0 && c.Quantization == 0) {
return errors.New("quantization not an integer")
}
if (bitrate > 0 && quantization > 0) || (bitrate == 0 && quantization == 0) {
return errors.New("bad bitrate and quantization combination for H264 input") return errors.New("bad bitrate and quantization combination for H264 input")
} }
}
case Mjpeg: case Mjpeg:
if c.Quantization != "" { if c.Quantization > 0 || c.Bitrate == 0 {
quantization, err := strconv.Atoi(c.Quantization)
if err != nil {
return errors.New("quantization not an integer")
}
if quantization > 0 || c.Bitrate == "" {
return errors.New("bad bitrate or quantization for mjpeg input") return errors.New("bad bitrate or quantization for mjpeg input")
} }
}
case NothingDefined: case NothingDefined:
c.Logger.Log(smartlogger.Warning, pkg+"no input codec defined, defaulting", c.Logger.Log(smartlogger.Warning, pkg+"no input codec defined, defaulting",
"inputCodec", defaultInputCodec) "inputCodec", defaultInputCodec)
@ -183,6 +167,7 @@ func (c *Config) Validate(r *Revid) error {
c.Logger.Log(smartlogger.Warning, pkg+"defaulting quantization", "quantization", c.Logger.Log(smartlogger.Warning, pkg+"defaulting quantization", "quantization",
defaultQuantization) defaultQuantization)
c.Quantization = defaultQuantization c.Quantization = defaultQuantization
default: default:
return errors.New("bad input codec defined in config") return errors.New("bad input codec defined in config")
} }
@ -234,73 +219,36 @@ func (c *Config) Validate(r *Revid) error {
c.FramesPerClip = defaultFramesPerClip c.FramesPerClip = defaultFramesPerClip
} }
if c.Width == "" { if c.Width == 0 {
c.Logger.Log(smartlogger.Warning, pkg+"no width defined, defaulting", "width", c.Logger.Log(smartlogger.Warning, pkg+"no width defined, defaulting", "width", defaultWidth)
defaultWidth)
c.Width = defaultWidth c.Width = defaultWidth
} else {
if integer, err := strconv.Atoi(c.Width); integer < 0 || err != nil {
return errors.New("width not unsigned integer")
}
} }
if c.Height == "" { if c.Height == 0 {
c.Logger.Log(smartlogger.Warning, pkg+"no height defined, defaulting", "height", c.Logger.Log(smartlogger.Warning, pkg+"no height defined, defaulting", "height", defaultHeight)
defaultHeight)
c.Height = defaultHeight c.Height = defaultHeight
} else {
if integer, err := strconv.Atoi(c.Height); integer < 0 || err != nil {
return errors.New("height not unsigned integer")
}
} }
if c.FrameRate == "" { if c.FrameRate == 0 {
c.Logger.Log(smartlogger.Warning, pkg+"no frame rate defined, defaulting", "fps", c.Logger.Log(smartlogger.Warning, pkg+"no frame rate defined, defaulting", "fps", defaultFrameRate)
defaultFrameRate)
c.FrameRate = defaultFrameRate c.FrameRate = defaultFrameRate
} else {
if integer, err := strconv.Atoi(c.FrameRate); integer < 0 || err != nil {
return errors.New("frame rate not unsigned integer")
}
} }
if c.Bitrate == "" { if c.Bitrate == 0 {
c.Logger.Log(smartlogger.Warning, pkg+"no bitrate defined, defaulting", "bitrate", c.Logger.Log(smartlogger.Warning, pkg+"no bitrate defined, defaulting", "bitrate", defaultBitrate)
defaultBitrate)
c.Bitrate = defaultBitrate c.Bitrate = defaultBitrate
} else {
if integer, err := strconv.Atoi(c.Bitrate); integer < 0 || err != nil {
return errors.New("bitrate not unsigned integer")
}
} }
if c.Timeout == "" { if c.IntraRefreshPeriod == 0 {
c.Logger.Log(smartlogger.Warning, pkg+"no timeout defined, defaulting", "timeout", defaultTimeout) c.Logger.Log(smartlogger.Warning, pkg+"no intra refresh defined, defaulting", "intraRefresh", defaultIntraRefreshPeriod)
c.Timeout = defaultTimeout
} else {
if integer, err := strconv.Atoi(c.Timeout); integer < 0 || err != nil {
return errors.New("timeout not unsigned integer")
}
}
if c.IntraRefreshPeriod == "" {
c.Logger.Log(smartlogger.Warning, pkg+"no intra refresh defined, defaulting", "intraRefresh",
defaultIntraRefreshPeriod)
c.IntraRefreshPeriod = defaultIntraRefreshPeriod c.IntraRefreshPeriod = defaultIntraRefreshPeriod
} else {
if integer, err := strconv.Atoi(c.IntraRefreshPeriod); integer < 0 || err != nil {
return errors.New("intra refresh not unsigned integer")
}
} }
if c.Quantization == "" { if c.Quantization == 0 {
c.Logger.Log(smartlogger.Warning, pkg+"no quantization defined, defaulting", "quantization", c.Logger.Log(smartlogger.Warning, pkg+"no quantization defined, defaulting", "quantization", defaultQuantization)
defaultQuantization)
c.Quantization = defaultQuantization c.Quantization = defaultQuantization
} else { } else if c.Quantization > 51 {
if integer, err := strconv.Atoi(c.Quantization); integer < 0 || integer > 51 || err != nil { return errors.New("quantisation is over threshold")
return errors.New("quantisation not unsigned integer or is over threshold")
}
} }
if c.RtpAddress == "" { if c.RtpAddress == "" {

View File

@ -133,7 +133,7 @@ var prevTime = now
type packer struct { type packer struct {
owner *Revid owner *Revid
packetCount int packetCount uint
} }
// Write implements the io.Writer interface. // Write implements the io.Writer interface.
@ -227,7 +227,7 @@ func (r *Revid) reset(config Config) error {
} }
r.destination[outNo] = s r.destination[outNo] = s
case FfmpegRtmp: case FfmpegRtmp:
s, err := newFfmpegSender(config.RtmpUrl, r.config.FrameRate) s, err := newFfmpegSender(config.RtmpUrl, fmt.Sprint(r.config.FrameRate))
if err != nil { if err != nil {
return err return err
} }
@ -247,10 +247,7 @@ func (r *Revid) reset(config Config) error {
} }
r.destination[outNo] = s r.destination[outNo] = s
case Rtp: case Rtp:
// TODO: framerate in config should probably be an int, make conversions early s, err := newRtpSender(r.config.RtpAddress, r.config.Logger.Log, r.config.FrameRate)
// when setting config fields in revid-cli
fps, _ := strconv.Atoi(r.config.FrameRate)
s, err := newRtpSender(r.config.RtpAddress, r.config.Logger.Log, fps)
if err != nil { if err != nil {
return err return err
} }
@ -292,12 +289,10 @@ func (r *Revid) reset(config Config) error {
r.encoder = stream.NopEncoder(&r.packer) r.encoder = stream.NopEncoder(&r.packer)
case Mpegts: case Mpegts:
r.config.Logger.Log(smartlogger.Info, pkg+"using MPEGTS packetisation") r.config.Logger.Log(smartlogger.Info, pkg+"using MPEGTS packetisation")
frameRate, _ := strconv.ParseFloat(r.config.FrameRate, 64) r.encoder = mts.NewEncoder(&r.packer, float64(r.config.FrameRate))
r.encoder = mts.NewEncoder(&r.packer, frameRate)
case Flv: case Flv:
r.config.Logger.Log(smartlogger.Info, pkg+"using FLV packetisation") r.config.Logger.Log(smartlogger.Info, pkg+"using FLV packetisation")
frameRate, _ := strconv.Atoi(r.config.FrameRate) r.encoder, err = flv.NewEncoder(&r.packer, true, true, int(r.config.FrameRate))
r.encoder, err = flv.NewEncoder(&r.packer, true, true, frameRate)
if err != nil { if err != nil {
return err return err
} }
@ -447,10 +442,10 @@ func (r *Revid) startRaspivid() error {
"--output", "-", "--output", "-",
"--nopreview", "--nopreview",
"--timeout", disabled, "--timeout", disabled,
"--width", r.config.Width, "--width", fmt.Sprint(r.config.Width),
"--height", r.config.Height, "--height", fmt.Sprint(r.config.Height),
"--bitrate", r.config.Bitrate, "--bitrate", fmt.Sprint(r.config.Bitrate),
"--framerate", r.config.FrameRate, "--framerate", fmt.Sprint(r.config.FrameRate),
} }
if r.config.FlipHorizontal { if r.config.FlipHorizontal {
args = append(args, "--hflip") args = append(args, "--hflip")
@ -465,10 +460,10 @@ func (r *Revid) startRaspivid() error {
args = append(args, args = append(args,
"--codec", "H264", "--codec", "H264",
"--inline", "--inline",
"--intra", r.config.IntraRefreshPeriod, "--intra", fmt.Sprint(r.config.IntraRefreshPeriod),
) )
if r.config.QuantizationMode == QuantizationOn { if r.config.Quantize {
args = append(args, "-qp", r.config.Quantization) args = append(args, "-qp", fmt.Sprint(r.config.Quantization))
} }
case Mjpeg: case Mjpeg:
args = append(args, "--codec", "MJPEG") args = append(args, "--codec", "MJPEG")
@ -476,11 +471,6 @@ func (r *Revid) startRaspivid() error {
r.config.Logger.Log(smartlogger.Info, pkg+"raspivid args", "raspividArgs", strings.Join(args, " ")) r.config.Logger.Log(smartlogger.Info, pkg+"raspivid args", "raspividArgs", strings.Join(args, " "))
r.cmd = exec.Command("raspivid", args...) r.cmd = exec.Command("raspivid", args...)
d, err := strconv.Atoi(r.config.FrameRate)
if err != nil {
return err
}
delay := time.Second / time.Duration(d)
stdout, err := r.cmd.StdoutPipe() stdout, err := r.cmd.StdoutPipe()
if err != nil { if err != nil {
return err return err
@ -491,6 +481,7 @@ func (r *Revid) startRaspivid() error {
} }
r.config.Logger.Log(smartlogger.Info, pkg+"reading camera data") r.config.Logger.Log(smartlogger.Info, pkg+"reading camera data")
delay := time.Second / time.Duration(r.config.FrameRate)
err = r.lexTo(r.encoder, stdout, delay) err = r.lexTo(r.encoder, stdout, delay)
r.config.Logger.Log(smartlogger.Info, pkg+"finished reading camera data") r.config.Logger.Log(smartlogger.Info, pkg+"finished reading camera data")
return err return err
@ -498,11 +489,7 @@ func (r *Revid) startRaspivid() error {
// setupInputForFile sets things up for getting input from a file // setupInputForFile sets things up for getting input from a file
func (r *Revid) setupInputForFile() error { func (r *Revid) setupInputForFile() error {
fps, err := strconv.Atoi(r.config.FrameRate) delay := time.Second / time.Duration(r.config.FrameRate)
if err != nil {
return err
}
delay := time.Second / time.Duration(fps)
f, err := os.Open(r.config.InputFileName) f, err := os.Open(r.config.InputFileName)
if err != nil { if err != nil {

View File

@ -371,14 +371,14 @@ type rtpSender struct {
encoder *rtp.Encoder encoder *rtp.Encoder
} }
func newRtpSender(addr string, log func(lvl int8, msg string, args ...interface{}), fps int) (*rtpSender, error) { func newRtpSender(addr string, log func(lvl int8, msg string, args ...interface{}), fps uint) (*rtpSender, error) {
conn, err := net.Dial("udp", addr) conn, err := net.Dial("udp", addr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
s := &rtpSender{ s := &rtpSender{
log: log, log: log,
encoder: rtp.NewEncoder(conn, fps), encoder: rtp.NewEncoder(conn, int(fps)),
} }
return s, nil return s, nil
} }