From a4ded5337dec14b65a3cb9ed915a94b3bedbbb5c Mon Sep 17 00:00:00 2001 From: saxon Date: Sun, 25 Nov 2018 17:24:52 +1030 Subject: [PATCH 01/16] revid: changed close operation on destination to close operpation on slice ofoperations in reset() --- revid/revid.go | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index fde3efb7..f555e655 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -118,7 +118,7 @@ type Revid struct { // to the target destination. buffer *ring.Buffer // destination is the target endpoint. - destination loadSender + destination []loadSender // bitrate hold the last send bitrate calculation result. bitrate int @@ -200,12 +200,15 @@ func (r *Revid) reset(config Config) error { } r.config = config - if r.destination != nil { - err = r.destination.close() - if err != nil { - r.config.Logger.Log(smartlogger.Error, pkg+"could not close destination", "error", err.Error()) + for i, destination := range r.destination { + if destination != nil { + err = destination.close() + if err != nil { + return err + } } } + switch r.config.Output { case File: s, err := newFileSender(config.OutputFileName) From 5920d1c8d7c43cf2f3912e723585406efb44fc5d Mon Sep 17 00:00:00 2001 From: saxon Date: Sun, 25 Nov 2018 23:10:38 +1030 Subject: [PATCH 02/16] revid: made destination for revid a []loadSender and change code such that iterate through this when performing actions relating to destinations like write, send and close. Also created new sender call rtp sender that has a inherent rtp encoder --- revid/config.go | 25 ++++++++-- revid/revid.go | 125 ++++++++++++++++++++++++++++++----------------- revid/senders.go | 37 ++++++++++++++ 3 files changed, 137 insertions(+), 50 deletions(-) diff --git a/revid/config.go b/revid/config.go index 1ff69e1d..a44a2bbe 100644 --- a/revid/config.go +++ b/revid/config.go @@ -39,7 +39,8 @@ import ( type Config struct { Input uint8 InputCodec uint8 - Output uint8 + Output1 uint8 + Output2 uint8 RtmpMethod uint8 Packetization uint8 QuantizationMode uint8 @@ -181,14 +182,14 @@ func (c *Config) Validate(r *Revid) error { return errors.New("bad input codec defined in config") } - switch c.Output { + switch c.Output1 { case File: case Rtp: case Udp: case Rtmp, FfmpegRtmp: if c.RtmpUrl == "" { c.Logger.Log(smartlogger.Info, pkg+"no RTMP URL: falling back to HTTP") - c.Output = Http + c.Output1 = Http break } c.Logger.Log(smartlogger.Info, pkg+"defaulting frames per clip for rtmp out", @@ -197,7 +198,7 @@ func (c *Config) Validate(r *Revid) error { case NothingDefined: c.Logger.Log(smartlogger.Warning, pkg+"no output defined, defaulting", "output", defaultOutput) - c.Output = defaultOutput + c.Output1 = defaultOutput fallthrough case Http: c.Logger.Log(smartlogger.Info, pkg+"defaulting frames per clip for http out", @@ -207,6 +208,22 @@ func (c *Config) Validate(r *Revid) error { return errors.New("bad output type defined in config") } + switch c.Output2 { + case File: + case Rtp: + case Udp: + case Rtmp, FfmpegRtmp: + if c.RtmpUrl == "" { + c.Logger.Log(smartlogger.Info, pkg+"no RTMP URL: falling back to HTTP") + c.Output2 = Http + break + } + case NothingDefined: + case Http: + default: + return errors.New("bad output2 type defined in config") + } + switch c.HorizontalFlip { case Yes: case No: diff --git a/revid/revid.go b/revid/revid.go index f555e655..ce29abbc 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -200,7 +200,7 @@ func (r *Revid) reset(config Config) error { } r.config = config - for i, destination := range r.destination { + for _, destination := range r.destination { if destination != nil { err = destination.close() if err != nil { @@ -209,33 +209,68 @@ func (r *Revid) reset(config Config) error { } } - switch r.config.Output { + if r.config.Output2 != 0 { + r.destination = make([]loadSender, 2) + } else { + r.destination = make([]loadSender, 1) + } + + switch r.config.Output1 { case File: s, err := newFileSender(config.OutputFileName) if err != nil { return err } - r.destination = s + r.destination[0] = s case FfmpegRtmp: s, err := newFfmpegSender(config.RtmpUrl, r.config.FrameRate) if err != nil { return err } - r.destination = s + r.destination[0] = s case Rtmp: s, err := newRtmpSender(config.RtmpUrl, rtmpConnectionTimout, rtmpConnectionMaxTries, r.config.Logger.Log) if err != nil { return err } - r.destination = s + r.destination[0] = s case Http: - r.destination = newHttpSender(r.ns, r.config.Logger.Log) + r.destination[0] = newHttpSender(r.ns, r.config.Logger.Log) case Rtp, Udp: s, err := newUdpSender(r.config.RtpAddress, r.config.Logger.Log) if err != nil { return err } - r.destination = s + r.destination[0] = s + } + + switch r.config.Output2 { + case File: + s, err := newFileSender(config.OutputFileName) + if err != nil { + return err + } + r.destination[1] = s + case FfmpegRtmp: + s, err := newFfmpegSender(config.RtmpUrl, r.config.FrameRate) + if err != nil { + return err + } + r.destination[1] = s + case Rtmp: + s, err := newRtmpSender(config.RtmpUrl, rtmpConnectionTimout, rtmpConnectionMaxTries, r.config.Logger.Log) + if err != nil { + return err + } + r.destination[1] = s + case Http: + r.destination[1] = newHttpSender(r.ns, r.config.Logger.Log) + case Rtp, Udp: + s, err := newUdpSender(r.config.RtpAddress, r.config.Logger.Log) + if err != nil { + return err + } + r.destination[1] = s } switch r.config.Input { @@ -352,50 +387,46 @@ loop: count += chunk.Len() r.config.Logger.Log(smartlogger.Debug, pkg+"about to send") - err = r.destination.load(chunk) - if err != nil { - r.config.Logger.Log(smartlogger.Error, pkg+"failed to load clip") - } - err = r.destination.send() - if err == nil { - r.config.Logger.Log(smartlogger.Debug, pkg+"sent clip") - } - - if err != nil && chunk.Len() > 11 { - r.config.Logger.Log(smartlogger.Error, pkg+"first send failed", "error", err.Error()) - // Try and send again - err = r.destination.send() + for i, destination := range r.destination { + err = destination.load(chunk) if err != nil { - r.config.Logger.Log(smartlogger.Error, pkg+"destination send error", "error", err.Error()) + r.config.Logger.Log(smartlogger.Error, pkg+"failed to load clip to output"+strconv.Itoa(i)) } + } - // if there's still an error we try and reconnect, unless we're stopping - for err != nil { - r.config.Logger.Log(smartlogger.Debug, pkg+"send failed again, trying to reconnect...") - time.Sleep(sendFailedDelay) - r.config.Logger.Log(smartlogger.Error, pkg+"send failed with error", "error", err.Error()) - - if rs, ok := r.destination.(restarter); ok { - r.config.Logger.Log(smartlogger.Debug, pkg+"restarting session", "session", rs) - err = rs.restart() - if err != nil { - // TODO(kortschak): Make this "Fatal" when that exists. - r.config.Logger.Log(smartlogger.Error, pkg+"failed to restart rtmp session", "error", err.Error()) - r.isRunning = false - return + for i, dest := range r.destination { + err = dest.send() + if err == nil { + r.config.Logger.Log(smartlogger.Debug, pkg+"sent clip to output"+strconv.Itoa(i)) + } else { + r.config.Logger.Log(smartlogger.Error, pkg+"send to output"+strconv.Itoa(i)+ + "failed, trying again", "error", err.Error()) + err = dest.send() + if err != nil && chunk.Len() > 11 { + r.config.Logger.Log(smartlogger.Error, pkg+"second send attempted failed, restarting connection", "error", err.Error()) + for err != nil { + time.Sleep(sendFailedDelay) + if rs, ok := dest.(restarter); ok { + r.config.Logger.Log(smartlogger.Debug, pkg+"restarting session", "session", rs) + err = rs.restart() + for err != nil { + r.config.Logger.Log(smartlogger.Error, pkg+"failed to restart rtmp session, trying again", "error", err.Error()) + err = rs.restart() + } + r.config.Logger.Log(smartlogger.Info, pkg+"restarted rtmp session") + } + err = dest.send() + if err != nil { + r.config.Logger.Log(smartlogger.Error, pkg+"send failed again, with error", "error", err.Error()) + } } - r.config.Logger.Log(smartlogger.Info, pkg+"restarted rtmp session") - } - - r.config.Logger.Log(smartlogger.Debug, pkg+"trying to send again with new connection") - err = r.destination.send() - if err != nil { - r.config.Logger.Log(smartlogger.Error, pkg+"send failed with error", "error", err.Error()) } } } - r.destination.release() + for _, dest := range r.destination { + dest.release() + } r.config.Logger.Log(smartlogger.Debug, pkg+"done reading that clip from ring buffer") @@ -412,9 +443,11 @@ loop: } } r.config.Logger.Log(smartlogger.Info, pkg+"not outputting clips anymore") - err := r.destination.close() - if err != nil { - r.config.Logger.Log(smartlogger.Error, pkg+"failed to close destination", "error", err.Error()) + for i, dest := range r.destination { + err := dest.close() + if err != nil { + r.config.Logger.Log(smartlogger.Error, pkg+"failed to close output"+strconv.Itoa(i)+" destination", "error", err.Error()) + } } } diff --git a/revid/senders.go b/revid/senders.go index cc0b869f..eb149445 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -35,6 +35,7 @@ import ( "os/exec" "bitbucket.org/ausocean/av/rtmp" + "bitbucket.org/ausocean/av/stream/rtp" "bitbucket.org/ausocean/iot/pi/netsender" "bitbucket.org/ausocean/utils/ring" "bitbucket.org/ausocean/utils/smartlogger" @@ -325,3 +326,39 @@ func (s *udpSender) release() { } func (s *udpSender) close() error { return nil } + +// rtpSender implements loadSender for a native udp destination. +type rtpSender struct { + log func(lvl int8, msg string, args ...interface{}) + chunk *ring.Chunk + encoder *rtp.Encoder +} + +func newRtpSender(addr string, log func(lvl int8, msg string, args ...interface{}), fps int) (*rtpSender, error) { + conn, err := net.Dial("udp", addr) + if err != nil { + return nil, err + } + s := &rtpSender{ + log: log, + encoder: rtp.NewEncoder(conn, fps), + } + return s, nil +} + +func (s *rtpSender) load(c *ring.Chunk) error { + s.chunk = c + return nil +} + +func (s *rtpSender) send() error { + _, err := s.chunk.WriteTo(s.encoder) + return err +} + +func (s *rtpSender) release() { + s.chunk.Close() + s.chunk = nil +} + +func (s *rtpSender) close() error { return nil } From 218dcfb8b2376cc2a2e9501b64f6f9b8fd0b99cb Mon Sep 17 00:00:00 2001 From: saxon Date: Sun, 25 Nov 2018 23:24:03 +1030 Subject: [PATCH 03/16] revid-cli: removed concept of mpegtsrtp packetization as not needed anymore --- cmd/revid-cli/main.go | 54 ++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/cmd/revid-cli/main.go b/cmd/revid-cli/main.go index 58c094f6..bfd8f35f 100644 --- a/cmd/revid-cli/main.go +++ b/cmd/revid-cli/main.go @@ -52,7 +52,8 @@ const ( const ( inputPtr = iota inputCodecPtr - outputPtr + output1Ptr + output2Ptr rtmpMethodPtr packetizationPtr quantizationModePtr @@ -107,9 +108,9 @@ var ( flagNames = [noOfConfigFlags]struct{ name, description string }{ {"Input", "The input type: Raspivid, File"}, {"InputCodec", "The codec of the input: H264, Mjpeg"}, - {"Output", "The output type: Http, Rtmp, File, Udp, Rtp"}, + {"Output1", "The first output type: Http, Rtmp, File, Udp, Rtp"}, + {"Output2", "The second output type: Http, Rtmp, File, Udp, Rtp"}, {"RtmpMethod", "The method used to send over rtmp: Ffmpeg, Librtmp"}, - // NOTE: we add rtp here when we have this functionality {"Packetization", "The method of data packetisation: Flv, Mpegts, None"}, {"QuantizationMode", "Whether quantization if on or off (variable bitrate): On, Off"}, {"Verbosity", "Verbosity: Info, Warning, Error, Fatal"}, @@ -202,23 +203,40 @@ func handleFlags() { logger.Log(smartlogger.Error, pkg+"bad input codec argument") } - switch *configFlags[outputPtr] { + switch *configFlags[output1Ptr] { case "File": - config.Output = revid.File + config.Output1 = revid.File case "Http": - config.Output = revid.Http + config.Output1 = revid.Http case "Rtmp": - config.Output = revid.Rtmp + config.Output1 = revid.Rtmp case "FfmpegRtmp": - config.Output = revid.FfmpegRtmp + config.Output1 = revid.FfmpegRtmp case "Udp": - config.Output = revid.Udp + config.Output1 = revid.Udp case "Rtp": - config.Output = revid.Rtp - config.Packetization = revid.MpegtsRtp + config.Output1 = revid.Rtp case "": default: - logger.Log(smartlogger.Error, pkg+"bad output argument") + logger.Log(smartlogger.Error, pkg+"bad output 1 argument") + } + + switch *configFlags[output2Ptr] { + case "File": + config.Output2 = revid.File + case "Http": + config.Output2 = revid.Http + case "Rtmp": + config.Output2 = revid.Rtmp + case "FfmpegRtmp": + config.Output2 = revid.FfmpegRtmp + case "Udp": + config.Output2 = revid.Udp + case "Rtp": + config.Output2 = revid.Rtp + case "": + default: + logger.Log(smartlogger.Error, pkg+"bad output 2 argument") } switch *configFlags[rtmpMethodPtr] { @@ -238,8 +256,6 @@ func handleFlags() { config.Packetization = revid.Mpegts case "Flv": config.Packetization = revid.Flv - case "MpegtsRtp": - config.Packetization = revid.MpegtsRtp case "": default: logger.Log(smartlogger.Error, pkg+"bad packetization argument") @@ -418,15 +434,15 @@ func updateRevid(ns *netsender.Sender, vars map[string]string, stop bool) error case "Output": switch value { case "File": - config.Output = revid.File + config.Output1 = revid.File case "Http": - config.Output = revid.Http + config.Output1 = revid.Http case "Rtmp": - config.Output = revid.Rtmp + config.Output1 = revid.Rtmp case "FfmpegRtmp": - config.Output = revid.FfmpegRtmp + config.Output1 = revid.FfmpegRtmp default: - logger.Log(smartlogger.Warning, pkg+"invalid Output param", "value", value) + logger.Log(smartlogger.Warning, pkg+"invalid Output1 param", "value", value) continue } case "FramesPerClip": From 98eb2c64e88c30c8646cc8028189af21186a62fa Mon Sep 17 00:00:00 2001 From: saxon Date: Sun, 25 Nov 2018 23:45:38 +1030 Subject: [PATCH 04/16] revid: revid output check and destination setting cleaner. Also changed destination release to single chunk.Close() so that chunks aren't closed more than once --- revid/revid.go | 120 ++++++++++++++++++++--------------------------- revid/senders.go | 5 +- 2 files changed, 54 insertions(+), 71 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index ce29abbc..af604d31 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -43,7 +43,6 @@ import ( "bitbucket.org/ausocean/av/stream/flv" "bitbucket.org/ausocean/av/stream/lex" "bitbucket.org/ausocean/av/stream/mts" - "bitbucket.org/ausocean/av/stream/rtp" "bitbucket.org/ausocean/iot/pi/netsender" "bitbucket.org/ausocean/utils/ring" "bitbucket.org/ausocean/utils/smartlogger" @@ -75,6 +74,11 @@ const ( pkg = "revid:" ) +const ( + out1 = 0 + out2 = 1 +) + // Log Types const ( Error = "Error" @@ -209,68 +213,50 @@ func (r *Revid) reset(config Config) error { } } + n := 1 if r.config.Output2 != 0 { - r.destination = make([]loadSender, 2) - } else { - r.destination = make([]loadSender, 1) + n = 2 } + r.destination = make([]loadSender, n) - switch r.config.Output1 { - case File: - s, err := newFileSender(config.OutputFileName) - if err != nil { - return err + for outNo, outType := range []uint8{r.config.Output1, r.config.Output2} { + switch outType { + case File: + s, err := newFileSender(config.OutputFileName) + if err != nil { + return err + } + r.destination[outNo] = s + case FfmpegRtmp: + s, err := newFfmpegSender(config.RtmpUrl, r.config.FrameRate) + if err != nil { + return err + } + r.destination[outNo] = s + case Rtmp: + s, err := newRtmpSender(config.RtmpUrl, rtmpConnectionTimout, rtmpConnectionMaxTries, r.config.Logger.Log) + if err != nil { + return err + } + r.destination[outNo] = s + case Http: + r.destination[outNo] = newHttpSender(r.ns, r.config.Logger.Log) + case Udp: + s, err := newUdpSender(r.config.RtpAddress, r.config.Logger.Log) + if err != nil { + return err + } + r.destination[outNo] = s + case Rtp: + // TODO: framerate in config should probably be an int, make conversions early + // 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 { + return err + } + r.destination[outNo] = s } - r.destination[0] = s - case FfmpegRtmp: - s, err := newFfmpegSender(config.RtmpUrl, r.config.FrameRate) - if err != nil { - return err - } - r.destination[0] = s - case Rtmp: - s, err := newRtmpSender(config.RtmpUrl, rtmpConnectionTimout, rtmpConnectionMaxTries, r.config.Logger.Log) - if err != nil { - return err - } - r.destination[0] = s - case Http: - r.destination[0] = newHttpSender(r.ns, r.config.Logger.Log) - case Rtp, Udp: - s, err := newUdpSender(r.config.RtpAddress, r.config.Logger.Log) - if err != nil { - return err - } - r.destination[0] = s - } - - switch r.config.Output2 { - case File: - s, err := newFileSender(config.OutputFileName) - if err != nil { - return err - } - r.destination[1] = s - case FfmpegRtmp: - s, err := newFfmpegSender(config.RtmpUrl, r.config.FrameRate) - if err != nil { - return err - } - r.destination[1] = s - case Rtmp: - s, err := newRtmpSender(config.RtmpUrl, rtmpConnectionTimout, rtmpConnectionMaxTries, r.config.Logger.Log) - if err != nil { - return err - } - r.destination[1] = s - case Http: - r.destination[1] = newHttpSender(r.ns, r.config.Logger.Log) - case Rtp, Udp: - s, err := newUdpSender(r.config.RtpAddress, r.config.Logger.Log) - if err != nil { - return err - } - r.destination[1] = s } switch r.config.Input { @@ -316,10 +302,6 @@ func (r *Revid) reset(config Config) error { if err != nil { return err } - case MpegtsRtp: - r.config.Logger.Log(smartlogger.Info, pkg+"using RTP packetisation") - frameRate, _ := strconv.Atoi(r.config.FrameRate) - r.encoder = mts.NewEncoder(rtp.NewEncoder(&r.packer, frameRate), float64(frameRate)) } return nil @@ -397,9 +379,9 @@ loop: for i, dest := range r.destination { err = dest.send() if err == nil { - r.config.Logger.Log(smartlogger.Debug, pkg+"sent clip to output"+strconv.Itoa(i)) + r.config.Logger.Log(smartlogger.Debug, pkg+"sent clip to output "+strconv.Itoa(i)) } else { - r.config.Logger.Log(smartlogger.Error, pkg+"send to output"+strconv.Itoa(i)+ + r.config.Logger.Log(smartlogger.Error, pkg+"send to output "+strconv.Itoa(i)+ "failed, trying again", "error", err.Error()) err = dest.send() if err != nil && chunk.Len() > 11 { @@ -413,8 +395,10 @@ loop: r.config.Logger.Log(smartlogger.Error, pkg+"failed to restart rtmp session, trying again", "error", err.Error()) err = rs.restart() } + r.config.Logger.Log(smartlogger.Info, pkg+"restarted rtmp session") } + err = dest.send() if err != nil { r.config.Logger.Log(smartlogger.Error, pkg+"send failed again, with error", "error", err.Error()) @@ -424,10 +408,8 @@ loop: } } - for _, dest := range r.destination { - dest.release() - } - + // Release the chunk back to the ring buffer for use + chunk.Close() r.config.Logger.Log(smartlogger.Debug, pkg+"done reading that clip from ring buffer") // Log some information regarding bitrate and ring buffer size if it's time diff --git a/revid/senders.go b/revid/senders.go index eb149445..81aaf7b6 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -292,7 +292,7 @@ func (s *rtmpSender) close() error { return s.sess.Close() } -// rtpSender implements loadSender for a native udp destination. +// udpSender implements loadSender for a native udp destination. type udpSender struct { conn net.Conn log func(lvl int8, msg string, args ...interface{}) @@ -327,7 +327,8 @@ func (s *udpSender) release() { func (s *udpSender) close() error { return nil } -// rtpSender implements loadSender for a native udp destination. +// TODO: Write restart func for rtpSender +// rtpSender implements loadSender for a native udp destination with rtp packetization. type rtpSender struct { log func(lvl int8, msg string, args ...interface{}) chunk *ring.Chunk From 227f25a3fbd40e7e4602efcafea6ceb1ac34749d Mon Sep 17 00:00:00 2001 From: saxon Date: Mon, 26 Nov 2018 00:40:18 +1030 Subject: [PATCH 05/16] revid: improved some naming and revmoed uneeded const --- revid/revid.go | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index af604d31..df534f15 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -74,11 +74,6 @@ const ( pkg = "revid:" ) -const ( - out1 = 0 - out2 = 1 -) - // Log Types const ( Error = "Error" @@ -204,9 +199,9 @@ func (r *Revid) reset(config Config) error { } r.config = config - for _, destination := range r.destination { - if destination != nil { - err = destination.close() + for _, dest := range r.destination { + if dest != nil { + err = dest.close() if err != nil { return err } @@ -369,8 +364,8 @@ loop: count += chunk.Len() r.config.Logger.Log(smartlogger.Debug, pkg+"about to send") - for i, destination := range r.destination { - err = destination.load(chunk) + for i, dest := range r.destination { + err = dest.load(chunk) if err != nil { r.config.Logger.Log(smartlogger.Error, pkg+"failed to load clip to output"+strconv.Itoa(i)) } From 1824273f8cbf12b28e1090ba782d242eb4a57640 Mon Sep 17 00:00:00 2001 From: saxon Date: Wed, 28 Nov 2018 15:26:17 +1030 Subject: [PATCH 06/16] revid: undoing logging changes, removed chunk closing in http sender send method --- revid/senders.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/revid/senders.go b/revid/senders.go index 81aaf7b6..5375730a 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -144,17 +144,18 @@ func (s *httpSender) send() error { } var err error if send { - _, _, err = s.client.Send(netsender.RequestPoll, pins) + _, _, err = s.client.Send(netsender.RequestVideo, pins) } + return err +} + +func (s *httpSender) release() { // We will not retry, so release // the chunk and clear it now. s.chunk.Close() s.chunk = nil - return err } -func (s *httpSender) release() {} - func (s *httpSender) close() error { return nil } // ffmpegSender implements loadSender for an FFMPEG RTMP destination. From 0afaa07c1e2073a4d23898d34cc20bd6c9296aaa Mon Sep 17 00:00:00 2001 From: saxon Date: Wed, 28 Nov 2018 15:29:54 +1030 Subject: [PATCH 07/16] revid-cli: added todo in regards to the flag list --- cmd/revid-cli/main.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/revid-cli/main.go b/cmd/revid-cli/main.go index bfd8f35f..0ac071df 100644 --- a/cmd/revid-cli/main.go +++ b/cmd/revid-cli/main.go @@ -105,7 +105,9 @@ var ( cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`") useNetsender = flag.Bool("NetSender", false, "Are we checking vars through netsender?") runDurationPtr = flag.Duration("runDuration", defaultRunDuration, "How long do you want revid to run for?") - flagNames = [noOfConfigFlags]struct{ name, description string }{ + // TODO: We should make this a comma-separated list that can have an arbitrary + //number of targets. Duplicating fields to do this is a code smell. + flagNames = [noOfConfigFlags]struct{ name, description string }{ {"Input", "The input type: Raspivid, File"}, {"InputCodec", "The codec of the input: H264, Mjpeg"}, {"Output1", "The first output type: Http, Rtmp, File, Udp, Rtp"}, From 89b7a0acfafc87fd4fa0f442f1ca24e6ece5dfe5 Mon Sep 17 00:00:00 2001 From: saxon Date: Wed, 28 Nov 2018 15:33:56 +1030 Subject: [PATCH 08/16] revid: reverted section of code which deals with failed restart of connection --- revid/revid.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/revid/revid.go b/revid/revid.go index df534f15..c3af4cd9 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -386,9 +386,10 @@ loop: if rs, ok := dest.(restarter); ok { r.config.Logger.Log(smartlogger.Debug, pkg+"restarting session", "session", rs) err = rs.restart() - for err != nil { - r.config.Logger.Log(smartlogger.Error, pkg+"failed to restart rtmp session, trying again", "error", err.Error()) - err = rs.restart() + if err != nil { + r.config.Logger.Log(smartlogger.Error, pkg+"failed to restart rtmp session", "error", err.Error()) + r.isRunning = false + return } r.config.Logger.Log(smartlogger.Info, pkg+"restarted rtmp session") From d32a7155493d3edbfd4dd5b8743a5a27f11bb0fd Mon Sep 17 00:00:00 2001 From: saxon Date: Thu, 29 Nov 2018 13:50:17 +1030 Subject: [PATCH 09/16] revid: testing request poll instead of requestvideo --- revid/senders.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/revid/senders.go b/revid/senders.go index 5375730a..fa72af3e 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -144,7 +144,7 @@ func (s *httpSender) send() error { } var err error if send { - _, _, err = s.client.Send(netsender.RequestVideo, pins) + _, _, err = s.client.Send(netsender.RequestPoll, pins) } return err } From 14f4bb0e63189cacc217581399e47f78b384aa4c Mon Sep 17 00:00:00 2001 From: saxon Date: Thu, 29 Nov 2018 14:06:16 +1030 Subject: [PATCH 10/16] revid: changed back to requestVideo --- revid/senders.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/revid/senders.go b/revid/senders.go index fa72af3e..5375730a 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -144,7 +144,7 @@ func (s *httpSender) send() error { } var err error if send { - _, _, err = s.client.Send(netsender.RequestPoll, pins) + _, _, err = s.client.Send(netsender.RequestVideo, pins) } return err } From 2c2be8449939de63485b15d8cd5b6dce9d176fa0 Mon Sep 17 00:00:00 2001 From: saxon Date: Thu, 29 Nov 2018 14:22:39 +1030 Subject: [PATCH 11/16] revid: iterating through destinations and using destination.release() instead of directly talking to ringbuffer chunks --- revid/revid.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/revid/revid.go b/revid/revid.go index c3af4cd9..058ccd67 100644 --- a/revid/revid.go +++ b/revid/revid.go @@ -405,7 +405,9 @@ loop: } // Release the chunk back to the ring buffer for use - chunk.Close() + for _, dest := range r.destination { + dest.release() + } r.config.Logger.Log(smartlogger.Debug, pkg+"done reading that clip from ring buffer") // Log some information regarding bitrate and ring buffer size if it's time From 1c105405e8ca88ae63888cc1d0740b570966a124 Mon Sep 17 00:00:00 2001 From: saxon Date: Fri, 30 Nov 2018 22:25:38 +1030 Subject: [PATCH 12/16] revid: changed request type back to poll so that build compiles on master --- revid/senders.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/revid/senders.go b/revid/senders.go index 5375730a..fa72af3e 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -144,7 +144,7 @@ func (s *httpSender) send() error { } var err error if send { - _, _, err = s.client.Send(netsender.RequestVideo, pins) + _, _, err = s.client.Send(netsender.RequestPoll, pins) } return err } From a421e4cee8a4315e209835a08aef0f3c4f22b59b Mon Sep 17 00:00:00 2001 From: saxon Date: Fri, 30 Nov 2018 22:29:20 +1030 Subject: [PATCH 13/16] revid-cli: moved todo comment to correct position above output1 and output2 flag declarations --- cmd/revid-cli/main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/revid-cli/main.go b/cmd/revid-cli/main.go index 0ac071df..016ed656 100644 --- a/cmd/revid-cli/main.go +++ b/cmd/revid-cli/main.go @@ -105,11 +105,11 @@ var ( cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`") useNetsender = flag.Bool("NetSender", false, "Are we checking vars through netsender?") runDurationPtr = flag.Duration("runDuration", defaultRunDuration, "How long do you want revid to run for?") - // TODO: We should make this a comma-separated list that can have an arbitrary - //number of targets. Duplicating fields to do this is a code smell. - flagNames = [noOfConfigFlags]struct{ name, description string }{ + flagNames = [noOfConfigFlags]struct{ name, description string }{ {"Input", "The input type: Raspivid, File"}, {"InputCodec", "The codec of the input: H264, Mjpeg"}, + // TODO: We should make this a comma-separated list that can have an arbitrary + //number of targets. {"Output1", "The first output type: Http, Rtmp, File, Udp, Rtp"}, {"Output2", "The second output type: Http, Rtmp, File, Udp, Rtp"}, {"RtmpMethod", "The method used to send over rtmp: Ffmpeg, Librtmp"}, From e0207d979fef3fd9ad5e4779f28e235bdf5fd49e Mon Sep 17 00:00:00 2001 From: saxon Date: Sat, 1 Dec 2018 11:17:12 +1030 Subject: [PATCH 14/16] revid: fixed test cases to use output1 to fix build errors --- revid/cmd/h264-file-to-flv-rtmp/main.go | 2 +- revid/cmd/h264-file-to-mpgets-file/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/revid/cmd/h264-file-to-flv-rtmp/main.go b/revid/cmd/h264-file-to-flv-rtmp/main.go index 70250df1..907e414b 100644 --- a/revid/cmd/h264-file-to-flv-rtmp/main.go +++ b/revid/cmd/h264-file-to-flv-rtmp/main.go @@ -57,7 +57,7 @@ func main() { Input: revid.File, InputFileName: inputFile, InputCodec: revid.H264, - Output: revid.Rtmp, + Output1: revid.Rtmp, RtmpMethod: revid.LibRtmp, RtmpUrl: *rtmpUrlPtr, Packetization: revid.Flv, diff --git a/revid/cmd/h264-file-to-mpgets-file/main.go b/revid/cmd/h264-file-to-mpgets-file/main.go index a1238da6..5530f6c4 100644 --- a/revid/cmd/h264-file-to-mpgets-file/main.go +++ b/revid/cmd/h264-file-to-mpgets-file/main.go @@ -49,7 +49,7 @@ func main() { Input: revid.File, InputFileName: inputFile, InputCodec: revid.H264, - Output: revid.File, + Output1: revid.File, OutputFileName: outputFile, Packetization: revid.Mpegts, Logger: smartlogger.New(smartlogger.Info, logPath), From 0f273e42b65f6c92f7d3a33f6a936f55e763df7f Mon Sep 17 00:00:00 2001 From: saxon Date: Tue, 4 Dec 2018 10:13:18 +1030 Subject: [PATCH 15/16] revid: using RequestRecv for http sender --- revid/senders.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/revid/senders.go b/revid/senders.go index fa72af3e..c4ab9cfc 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -144,7 +144,7 @@ func (s *httpSender) send() error { } var err error if send { - _, _, err = s.client.Send(netsender.RequestPoll, pins) + _, _, err = s.client.Send(netsender.RequestRecv, pins) } return err } From 402f2fb1657f70ed66dae1ce6f85f9c12c3d381d Mon Sep 17 00:00:00 2001 From: saxon Date: Tue, 4 Dec 2018 10:14:45 +1030 Subject: [PATCH 16/16] revid: revert so that netsender pull request can be done first --- revid/senders.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/revid/senders.go b/revid/senders.go index c4ab9cfc..fa72af3e 100644 --- a/revid/senders.go +++ b/revid/senders.go @@ -144,7 +144,7 @@ func (s *httpSender) send() error { } var err error if send { - _, _, err = s.client.Send(netsender.RequestRecv, pins) + _, _, err = s.client.Send(netsender.RequestPoll, pins) } return err }