mirror of https://bitbucket.org/ausocean/av.git
revid: avoid monomorphic interface
This commit is contained in:
parent
709de3f119
commit
3881cb9712
|
@ -95,7 +95,7 @@ const (
|
|||
|
||||
// Globals
|
||||
var (
|
||||
revidInst revid.Revid
|
||||
revidInst *revid.Revid
|
||||
config revid.Config
|
||||
)
|
||||
|
||||
|
@ -341,7 +341,7 @@ func startRevid() {
|
|||
func createRevidInstance() {
|
||||
// Try to create the revid instance with the given config
|
||||
var err error
|
||||
for revidInst, err = revid.NewRevid(config); err != nil; {
|
||||
for revidInst, err = revid.New(config); err != nil; {
|
||||
// If the config does have a logger, use it to output error, otherwise
|
||||
// just output to std output
|
||||
if config.Logger != nil {
|
||||
|
|
102
revid/config.go
102
revid/config.go
|
@ -104,46 +104,46 @@ const (
|
|||
|
||||
// Validate checks for any errors in the config fields and defaults settings
|
||||
// if particular parameters have not been defined.
|
||||
func (config *Config) Validate(r *revid) error {
|
||||
switch config.Verbosity {
|
||||
func (c *Config) Validate(r *Revid) error {
|
||||
switch c.Verbosity {
|
||||
case Yes:
|
||||
case No:
|
||||
case NothingDefined:
|
||||
config.Verbosity = Yes
|
||||
c.Verbosity = Yes
|
||||
r.Log(Warning, "No verbosity mode defined, defaulting to no Verbosity!")
|
||||
default:
|
||||
return errors.New("Bad Verbosity defined in config!")
|
||||
}
|
||||
|
||||
switch config.QuantizationMode {
|
||||
switch c.QuantizationMode {
|
||||
case QuantizationOn:
|
||||
case QuantizationOff:
|
||||
case NothingDefined:
|
||||
r.Log(Warning, "No quantization mode defined, defaulting to QuantizationOff!")
|
||||
config.QuantizationMode = QuantizationOff
|
||||
c.QuantizationMode = QuantizationOff
|
||||
default:
|
||||
return errors.New("Bad QuantizationMode defined in config!")
|
||||
}
|
||||
|
||||
switch config.Input {
|
||||
switch c.Input {
|
||||
case Rtp:
|
||||
case Raspivid:
|
||||
case File:
|
||||
case NothingDefined:
|
||||
r.Log(Warning, "No input type defined, defaulting to raspivid!")
|
||||
config.Input = defaultInput
|
||||
c.Input = defaultInput
|
||||
default:
|
||||
return errors.New("Bad input type defined in config!")
|
||||
}
|
||||
|
||||
switch config.InputCodec {
|
||||
switch c.InputCodec {
|
||||
case H264:
|
||||
if config.Bitrate != "" && config.Quantization != "" {
|
||||
bitrate, err := strconv.Atoi(config.Bitrate)
|
||||
if c.Bitrate != "" && c.Quantization != "" {
|
||||
bitrate, err := strconv.Atoi(c.Bitrate)
|
||||
if err != nil {
|
||||
return errors.New("Something is wrong with bitrate in conig!")
|
||||
}
|
||||
quantization, err := strconv.Atoi(config.Quantization)
|
||||
quantization, err := strconv.Atoi(c.Quantization)
|
||||
if err != nil {
|
||||
return errors.New("Something is wrong with quantization in config!")
|
||||
}
|
||||
|
@ -152,141 +152,141 @@ func (config *Config) Validate(r *revid) error {
|
|||
}
|
||||
}
|
||||
case Mjpeg:
|
||||
if config.Quantization != "" {
|
||||
quantization, err := strconv.Atoi(config.Quantization)
|
||||
if c.Quantization != "" {
|
||||
quantization, err := strconv.Atoi(c.Quantization)
|
||||
if err != nil {
|
||||
return errors.New("Something is wrong with quantization in config!")
|
||||
}
|
||||
if quantization > 0 || config.Bitrate == "" {
|
||||
if quantization > 0 || c.Bitrate == "" {
|
||||
return errors.New("Bad bitrate or quantization for mjpeg input!")
|
||||
}
|
||||
}
|
||||
case NothingDefined:
|
||||
r.Log(Warning, "No input codec defined, defaulting to h264!")
|
||||
config.InputCodec = H264
|
||||
c.InputCodec = H264
|
||||
r.Log(Warning, "Defaulting bitrate to 0 and quantization to 35!")
|
||||
config.Quantization = defaultQuantization
|
||||
c.Quantization = defaultQuantization
|
||||
default:
|
||||
return errors.New("Bad input codec defined in config!")
|
||||
}
|
||||
|
||||
switch config.Output {
|
||||
switch c.Output {
|
||||
case Http:
|
||||
case File:
|
||||
case NativeRtmp, FfmpegRtmp:
|
||||
if config.RtmpUrl == "" {
|
||||
if c.RtmpUrl == "" {
|
||||
r.Log(Info, "No RTMP URL: falling back to HTTP")
|
||||
config.Output = Http
|
||||
c.Output = Http
|
||||
break
|
||||
}
|
||||
r.Log(Info, "Defaulting frames per clip to 1 for rtmp output!")
|
||||
config.FramesPerClip = "1"
|
||||
c.FramesPerClip = "1"
|
||||
case NothingDefined:
|
||||
r.Log(Warning, "No output defined, defaulting to httpOut!")
|
||||
config.Output = defaultOutput
|
||||
c.Output = defaultOutput
|
||||
default:
|
||||
return errors.New("Bad output type defined in config!")
|
||||
}
|
||||
|
||||
switch config.Packetization {
|
||||
switch c.Packetization {
|
||||
case None:
|
||||
case Mpegts:
|
||||
case Flv:
|
||||
case NothingDefined:
|
||||
r.Log(Warning, "No packetization option defined, defaulting to none!")
|
||||
config.Packetization = Flv
|
||||
c.Packetization = Flv
|
||||
default:
|
||||
return errors.New("Bad packetization option defined in config!")
|
||||
}
|
||||
|
||||
switch config.HorizontalFlip {
|
||||
switch c.HorizontalFlip {
|
||||
case Yes:
|
||||
case No:
|
||||
case NothingDefined:
|
||||
r.Log(Warning, "No horizontal flip option defined, defaulting to not flipped!")
|
||||
config.HorizontalFlip = defaultHorizontalFlip
|
||||
c.HorizontalFlip = defaultHorizontalFlip
|
||||
default:
|
||||
return errors.New("Bad horizontal flip option defined in config!")
|
||||
}
|
||||
|
||||
switch config.VerticalFlip {
|
||||
switch c.VerticalFlip {
|
||||
case Yes:
|
||||
case No:
|
||||
case NothingDefined:
|
||||
r.Log(Warning, "No vertical flip option defined, defaulting to not flipped!")
|
||||
config.VerticalFlip = defaultVerticalFlip
|
||||
c.VerticalFlip = defaultVerticalFlip
|
||||
default:
|
||||
return errors.New("Bad vertical flip option defined in config!")
|
||||
}
|
||||
|
||||
if config.FramesPerClip == "" {
|
||||
if c.FramesPerClip == "" {
|
||||
r.Log(Warning, "No FramesPerClip defined defined, defaulting to 1!")
|
||||
config.Width = defaultFramesPerClip
|
||||
c.Width = defaultFramesPerClip
|
||||
} else {
|
||||
if integer, err := strconv.Atoi(config.FramesPerClip); integer <= 0 || err != nil {
|
||||
if integer, err := strconv.Atoi(c.FramesPerClip); integer <= 0 || err != nil {
|
||||
return errors.New("Bad width defined in config!")
|
||||
}
|
||||
}
|
||||
|
||||
if config.Width == "" {
|
||||
if c.Width == "" {
|
||||
r.Log(Warning, "No width defined, defaulting to 1280!")
|
||||
config.Width = defaultWidth
|
||||
c.Width = defaultWidth
|
||||
} else {
|
||||
if integer, err := strconv.Atoi(config.Width); integer < 0 || err != nil {
|
||||
if integer, err := strconv.Atoi(c.Width); integer < 0 || err != nil {
|
||||
return errors.New("Bad width defined in config!")
|
||||
}
|
||||
}
|
||||
|
||||
if config.Height == "" {
|
||||
if c.Height == "" {
|
||||
r.Log(Warning, "No height defined, defaulting to 720!")
|
||||
config.Height = defaultHeight
|
||||
c.Height = defaultHeight
|
||||
} else {
|
||||
if integer, err := strconv.Atoi(config.Height); integer < 0 || err != nil {
|
||||
if integer, err := strconv.Atoi(c.Height); integer < 0 || err != nil {
|
||||
return errors.New("Bad height defined in config!")
|
||||
}
|
||||
}
|
||||
|
||||
if config.FrameRate == "" {
|
||||
if c.FrameRate == "" {
|
||||
r.Log(Warning, "No frame rate defined, defaulting to 25!")
|
||||
config.FrameRate = defaultFrameRate
|
||||
c.FrameRate = defaultFrameRate
|
||||
} else {
|
||||
if integer, err := strconv.Atoi(config.FrameRate); integer < 0 || err != nil {
|
||||
if integer, err := strconv.Atoi(c.FrameRate); integer < 0 || err != nil {
|
||||
return errors.New("Bad frame rate defined in config!")
|
||||
}
|
||||
}
|
||||
|
||||
if config.Bitrate == "" {
|
||||
if c.Bitrate == "" {
|
||||
r.Log(Warning, "No bitrate defined, defaulting!")
|
||||
config.Bitrate = defaultBitrate
|
||||
c.Bitrate = defaultBitrate
|
||||
} else {
|
||||
if integer, err := strconv.Atoi(config.Bitrate); integer < 0 || err != nil {
|
||||
if integer, err := strconv.Atoi(c.Bitrate); integer < 0 || err != nil {
|
||||
return errors.New("Bad bitrate defined in config!")
|
||||
}
|
||||
}
|
||||
|
||||
if config.Timeout == "" {
|
||||
if c.Timeout == "" {
|
||||
r.Log(Warning, "No timeout defined, defaulting to 0!")
|
||||
config.Timeout = defaultTimeout
|
||||
c.Timeout = defaultTimeout
|
||||
} else {
|
||||
if integer, err := strconv.Atoi(config.Timeout); integer < 0 || err != nil {
|
||||
if integer, err := strconv.Atoi(c.Timeout); integer < 0 || err != nil {
|
||||
return errors.New("Bad timeout defined in config!")
|
||||
}
|
||||
}
|
||||
|
||||
if config.IntraRefreshPeriod == "" {
|
||||
if c.IntraRefreshPeriod == "" {
|
||||
r.Log(Warning, "No intra refresh defined, defaulting to 100!")
|
||||
config.IntraRefreshPeriod = defaultIntraRefreshPeriod
|
||||
c.IntraRefreshPeriod = defaultIntraRefreshPeriod
|
||||
} else {
|
||||
if integer, err := strconv.Atoi(config.IntraRefreshPeriod); integer < 0 || err != nil {
|
||||
if integer, err := strconv.Atoi(c.IntraRefreshPeriod); integer < 0 || err != nil {
|
||||
return errors.New("Bad intra refresh defined in config!")
|
||||
}
|
||||
}
|
||||
|
||||
if config.Quantization == "" {
|
||||
if c.Quantization == "" {
|
||||
r.Log(Warning, "No quantization defined, defaulting to 35!")
|
||||
config.Quantization = defaultQuantization
|
||||
c.Quantization = defaultQuantization
|
||||
} else {
|
||||
if integer, err := strconv.Atoi(config.Quantization); integer < 0 || integer > 51 || err != nil {
|
||||
if integer, err := strconv.Atoi(c.Quantization); integer < 0 || integer > 51 || err != nil {
|
||||
return errors.New("Bad quantization defined in config!")
|
||||
}
|
||||
}
|
||||
|
|
105
revid/revid.go
105
revid/revid.go
|
@ -86,18 +86,7 @@ const (
|
|||
|
||||
// Revid provides methods to control a revid session; providing methods
|
||||
// to start, stop and change the state of an instance using the Config struct.
|
||||
type Revid interface {
|
||||
Start()
|
||||
Stop()
|
||||
changeState(newconfig Config) error
|
||||
GetConfigRef() *Config
|
||||
Log(logType, m string)
|
||||
IsRunning() bool
|
||||
GetBitrate() int64
|
||||
}
|
||||
|
||||
// The revid struct provides fields to describe the state of a Revid.
|
||||
type revid struct {
|
||||
type Revid struct {
|
||||
ffmpegPath string
|
||||
tempDir string
|
||||
ringBuffer *ring.Buffer
|
||||
|
@ -122,38 +111,34 @@ type revid struct {
|
|||
currentBitrate int64
|
||||
}
|
||||
|
||||
// NewRevid returns a pointer to a new revid with the desired
|
||||
// NewRevid returns a pointer to a new Revid with the desired
|
||||
// configuration, and/or an error if construction of the new instant was not
|
||||
// successful.
|
||||
func NewRevid(config Config) (r *revid, err error) {
|
||||
r = new(revid)
|
||||
r.mutex = sync.Mutex{}
|
||||
r.sendMutex = sync.Mutex{}
|
||||
r.ringBuffer = ring.NewBuffer(ringBufferSize, ringBufferElementSize, writeTimeout)
|
||||
err = r.changeState(config)
|
||||
func New(c Config) (*Revid, error) {
|
||||
var r Revid
|
||||
err := r.reset(c)
|
||||
if err != nil {
|
||||
r = nil
|
||||
return
|
||||
return nil, err
|
||||
}
|
||||
r.ringBuffer = ring.NewBuffer(ringBufferSize, ringBufferElementSize, writeTimeout)
|
||||
r.outputChan = make(chan []byte, outputChanSize)
|
||||
r.isRunning = false
|
||||
return
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
// Returns the currently saved bitrate from the most recent bitrate check
|
||||
// check bitrate output delay in consts for this period
|
||||
func (r *revid) GetBitrate() int64 {
|
||||
func (r *Revid) GetBitrate() int64 {
|
||||
return r.currentBitrate
|
||||
}
|
||||
|
||||
// GetConfigRef returns a pointer to the revidInst's Config struct object
|
||||
func (r *revid) GetConfigRef() *Config {
|
||||
func (r *Revid) GetConfigRef() *Config {
|
||||
return &r.config
|
||||
}
|
||||
|
||||
// changeState swaps the current config of a revid with the passed
|
||||
// reset swaps the current config of a Revid with the passed
|
||||
// configuration; checking validity and returning errors if not valid.
|
||||
func (r *revid) changeState(config Config) error {
|
||||
func (r *Revid) reset(config Config) error {
|
||||
r.config.Logger = config.Logger
|
||||
err := config.Validate(r)
|
||||
if err != nil {
|
||||
|
@ -214,25 +199,25 @@ noPacketizationSetup:
|
|||
return nil
|
||||
}
|
||||
|
||||
// ChangeConfig changes the current configuration of the revid instance.
|
||||
func (r *revid) ChangeConfig(config Config) (err error) {
|
||||
// ChangeConfig changes the current configuration of the Revid instance.
|
||||
func (r *Revid) ChangeConfig(c Config) error {
|
||||
// FIXME(kortschak): This is reimplemented in cmd/revid-cli/main.go.
|
||||
// The implementation in the command is used and this is not.
|
||||
// Decide on one or the other.
|
||||
|
||||
r.Stop()
|
||||
r, err = NewRevid(config)
|
||||
r, err := New(c)
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
r.Start()
|
||||
return
|
||||
return err
|
||||
}
|
||||
|
||||
// Log takes a logtype and message and tries to send this information to the
|
||||
// logger provided in the revid config - if there is one, otherwise the message
|
||||
// is sent to stdout
|
||||
func (r *revid) Log(logType, m string) {
|
||||
func (r *Revid) Log(logType, m string) {
|
||||
if r.config.Verbosity == Yes {
|
||||
if r.config.Logger != nil {
|
||||
r.config.Logger.Log("revid", logType, m)
|
||||
|
@ -243,17 +228,17 @@ func (r *revid) Log(logType, m string) {
|
|||
}
|
||||
|
||||
// IsRunning returns true if the revid is currently running and false otherwise
|
||||
func (r *revid) IsRunning() bool {
|
||||
func (r *Revid) IsRunning() bool {
|
||||
return r.isRunning
|
||||
}
|
||||
|
||||
// Start invokes a revid to start processing video from a defined input
|
||||
// Start invokes a Revid to start processing video from a defined input
|
||||
// and packetising (if theres packetization) to a defined output.
|
||||
func (r *revid) Start() {
|
||||
func (r *Revid) Start() {
|
||||
r.mutex.Lock()
|
||||
defer r.mutex.Unlock()
|
||||
if r.isRunning {
|
||||
r.Log(Warning, "revid.Start() called but revid already running!")
|
||||
r.Log(Warning, "Revid.Start() called but revid already running!")
|
||||
return
|
||||
}
|
||||
r.Log(Info, "Starting Revid!")
|
||||
|
@ -279,12 +264,12 @@ func (r *revid) Start() {
|
|||
}
|
||||
|
||||
// Stop halts any processing of video data from a camera or file
|
||||
func (r *revid) Stop() {
|
||||
func (r *Revid) Stop() {
|
||||
r.mutex.Lock()
|
||||
defer r.mutex.Unlock()
|
||||
|
||||
if !r.isRunning {
|
||||
r.Log(Warning, "revid.Stop() called but revid not running!")
|
||||
r.Log(Warning, "Revid.Stop() called but revid not running!")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -315,18 +300,18 @@ func (r *revid) Stop() {
|
|||
|
||||
// getFrameNoPacketization gets a frame directly from the revid output chan
|
||||
// as we don't need to go through the generator with no packetization settings
|
||||
func (r *revid) getFrameNoPacketization() []byte {
|
||||
func (r *Revid) getFrameNoPacketization() []byte {
|
||||
return <-r.outputChan
|
||||
}
|
||||
|
||||
// getFramePacketization gets a frame from the generators output chan - the
|
||||
// the generator being an mpegts or flv generator depending on the config
|
||||
func (r *revid) getFramePacketization() []byte {
|
||||
func (r *Revid) getFramePacketization() []byte {
|
||||
return <-(r.generator.GetOutputChan())
|
||||
}
|
||||
|
||||
// flushDataPacketization removes data from the revid inst's coutput chan
|
||||
func (r *revid) flushData() {
|
||||
// flushDataPacketization removes data from the Revid inst's coutput chan
|
||||
func (r *Revid) flushData() {
|
||||
switch r.config.Packetization {
|
||||
case Flv:
|
||||
for {
|
||||
|
@ -342,7 +327,7 @@ done:
|
|||
|
||||
// packClips takes data segments; whether that be tsPackets or mjpeg frames and
|
||||
// packs them into clips consisting of the amount frames specified in the config
|
||||
func (r *revid) packClips() {
|
||||
func (r *Revid) packClips() {
|
||||
clipSize := 0
|
||||
packetCount := 0
|
||||
for r.isRunning {
|
||||
|
@ -384,7 +369,7 @@ func (r *revid) packClips() {
|
|||
|
||||
// outputClips takes the clips produced in the packClips method and outputs them
|
||||
// to the desired output defined in the revid config
|
||||
func (r *revid) outputClips() {
|
||||
func (r *Revid) outputClips() {
|
||||
now := time.Now()
|
||||
prevTime := now
|
||||
bytes := 0
|
||||
|
@ -458,7 +443,7 @@ func (r *revid) outputClips() {
|
|||
}
|
||||
|
||||
// senClipToFile writes the passed clip to a file
|
||||
func (r *revid) sendClipToFile(clip *ring.Chunk) error {
|
||||
func (r *Revid) sendClipToFile(clip *ring.Chunk) error {
|
||||
r.sendMutex.Lock()
|
||||
_, err := clip.WriteTo(r.outputFile)
|
||||
r.sendMutex.Unlock()
|
||||
|
@ -466,7 +451,7 @@ func (r *revid) sendClipToFile(clip *ring.Chunk) error {
|
|||
}
|
||||
|
||||
// sendClipToHTTP takes a clip and an output url and posts through http.
|
||||
func (r *revid) sendClipToHTTP(clip *ring.Chunk) error {
|
||||
func (r *Revid) sendClipToHTTP(clip *ring.Chunk) error {
|
||||
defer r.sendMutex.Unlock()
|
||||
r.sendMutex.Lock()
|
||||
|
||||
|
@ -479,7 +464,7 @@ func (r *revid) sendClipToHTTP(clip *ring.Chunk) error {
|
|||
// use a method value for dispatching the sendClip work.
|
||||
// So to save work in this case, sendClip should be made
|
||||
// a proper method with a behaviour switch based on a
|
||||
// revid field so that we can prepare these bytes only
|
||||
// Revid field so that we can prepare these bytes only
|
||||
// once for each clip (reusing a buffer field? or tt
|
||||
// might be work using a sync.Pool for the bodies).
|
||||
post := bytes.NewBuffer(make([]byte, 0, clip.Len()))
|
||||
|
@ -507,7 +492,7 @@ func (r *revid) sendClipToHTTP(clip *ring.Chunk) error {
|
|||
|
||||
// sendClipToFfmpegRtmp sends the clip over the current rtmp connection using
|
||||
// an ffmpeg process.
|
||||
func (r *revid) sendClipToFfmpegRtmp(clip *ring.Chunk) error {
|
||||
func (r *Revid) sendClipToFfmpegRtmp(clip *ring.Chunk) error {
|
||||
r.sendMutex.Lock()
|
||||
_, err := clip.WriteTo(r.ffmpegStdin)
|
||||
r.sendMutex.Unlock()
|
||||
|
@ -516,7 +501,7 @@ func (r *revid) sendClipToFfmpegRtmp(clip *ring.Chunk) error {
|
|||
|
||||
// sendClipToLibRtmp send the clip over the current rtmp connection using the
|
||||
// c based librtmp library
|
||||
func (r *revid) sendClipToLibRtmp(clip *ring.Chunk) error {
|
||||
func (r *Revid) sendClipToLibRtmp(clip *ring.Chunk) error {
|
||||
r.sendMutex.Lock()
|
||||
_, err := clip.WriteTo(r.rtmpInst)
|
||||
r.sendMutex.Unlock()
|
||||
|
@ -524,7 +509,7 @@ func (r *revid) sendClipToLibRtmp(clip *ring.Chunk) error {
|
|||
}
|
||||
|
||||
// setupOutputForFfmpegRtmp sets up output to rtmp using an ffmpeg process
|
||||
func (r *revid) setupOutputForFfmpegRtmp() error {
|
||||
func (r *Revid) setupOutputForFfmpegRtmp() error {
|
||||
r.ffmpegCmd = exec.Command(ffmpegPath,
|
||||
"-f", "h264",
|
||||
"-r", r.config.FrameRate,
|
||||
|
@ -558,7 +543,7 @@ func (r *revid) setupOutputForFfmpegRtmp() error {
|
|||
|
||||
// setupOutputForLibRtmp sets up rtmp output using the wrapper for the c based
|
||||
// librtmp library - makes connection and starts comms etc.
|
||||
func (r *revid) setupOutputForLibRtmp() error {
|
||||
func (r *Revid) setupOutputForLibRtmp() error {
|
||||
r.rtmpInst = rtmp.NewSession(r.config.RtmpUrl, rtmpConnectionTimout)
|
||||
err := r.rtmpInst.StartSession()
|
||||
for noOfTries := 0; err != nil && noOfTries < rtmpConnectionMaxTries; noOfTries++ {
|
||||
|
@ -575,14 +560,14 @@ func (r *revid) setupOutputForLibRtmp() error {
|
|||
}
|
||||
|
||||
// setupOutputForFile sets up an output file to output data to
|
||||
func (r *revid) setupOutputForFile() (err error) {
|
||||
func (r *Revid) setupOutputForFile() (err error) {
|
||||
r.outputFile, err = os.Create(r.config.OutputFileName)
|
||||
return
|
||||
}
|
||||
|
||||
// setupInputForRaspivid 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) setupInputForRaspivid() error {
|
||||
r.Log(Info, "Starting raspivid!")
|
||||
switch r.config.InputCodec {
|
||||
case H264:
|
||||
|
@ -642,7 +627,7 @@ func (r *revid) setupInputForRaspivid() error {
|
|||
}
|
||||
|
||||
// setupInputForFile sets things up for getting input from a file
|
||||
func (r *revid) setupInputForFile() error {
|
||||
func (r *Revid) setupInputForFile() error {
|
||||
fps, _ := strconv.Atoi(r.config.FrameRate)
|
||||
r.parser.SetDelay(uint(float64(1000) / float64(fps)))
|
||||
r.readFile()
|
||||
|
@ -652,7 +637,7 @@ func (r *revid) setupInputForFile() error {
|
|||
// testRtmp is useful to check robustness of connections. Intended to be run as
|
||||
// goroutine. After every 'delayTime' the rtmp connection is ended and then
|
||||
// restarted
|
||||
func (r *revid) testRtmp(delayTime uint) {
|
||||
func (r *Revid) testRtmp(delayTime uint) {
|
||||
for {
|
||||
time.Sleep(time.Duration(delayTime) * time.Millisecond)
|
||||
r.rtmpInst.Close()
|
||||
|
@ -660,9 +645,9 @@ func (r *revid) testRtmp(delayTime uint) {
|
|||
}
|
||||
}
|
||||
|
||||
// readCamera reads data from the defined camera while the revid is running.
|
||||
// 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() {
|
||||
func (r *Revid) readCamera() {
|
||||
r.Log(Info, "Reading camera data!")
|
||||
for r.isRunning {
|
||||
data := make([]byte, 1)
|
||||
|
@ -679,8 +664,8 @@ func (r *revid) readCamera() {
|
|||
r.Log(Info, "Not trying to read from camera anymore!")
|
||||
}
|
||||
|
||||
// readFile reads data from the defined file while the revid is running.
|
||||
func (r *revid) readFile() error {
|
||||
// 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)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue