From b4a8028c042fd7a6bcb86481f2fcb9b997967f98 Mon Sep 17 00:00:00 2001 From: Cedric Verstraeten Date: Tue, 14 Feb 2023 08:57:55 +0100 Subject: [PATCH] better way of doing prerecording + matching timestamp with prerecord time --- machinery/src/capture/IPCamera.go | 54 ++++++++++++++++++++++++++++ machinery/src/capture/main.go | 8 ++++- machinery/src/components/Kerberos.go | 6 ++-- 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/machinery/src/capture/IPCamera.go b/machinery/src/capture/IPCamera.go index bfb6d59..527d180 100644 --- a/machinery/src/capture/IPCamera.go +++ b/machinery/src/capture/IPCamera.go @@ -46,6 +46,60 @@ func DecodeImage(frame *ffmpeg.VideoFrame, pkt av.Packet, decoder *ffmpeg.VideoD return img, err } +func GetStreamInsights(infile av.DemuxCloser, streams []av.CodecData) (int, int, int, int) { + var width, height, fps, gopsize int + for _, stream := range streams { + if stream.Type().IsAudio() { + //astream := stream.(av.AudioCodecData) + } else if stream.Type().IsVideo() { + vstream := stream.(av.VideoCodecData) + width = vstream.Width() + height = vstream.Height() + } + } + +loop: + for timeout := time.After(1 * time.Second); ; { + var err error + if _, err = infile.ReadPacket(); err != nil { // sometimes this throws an end of file.. + log.Log.Error("HandleStream: " + err.Error()) + } + fps++ + select { + case <-timeout: + break loop + default: + } + } + + gopCounter := 0 + start := false + for { + var pkt av.Packet + var err error + if pkt, err = infile.ReadPacket(); err != nil { // sometimes this throws an end of file.. + log.Log.Error("HandleStream: " + err.Error()) + } + // Could be that a decode is throwing errors. + if len(pkt.Data) > 0 { + if start { + gopCounter = gopCounter + 1 + } + + if pkt.IsKeyFrame { + if start == false { + start = true + } else { + gopsize = gopCounter + break + } + } + } + } + + return width, height, fps, gopsize +} + func HandleStream(infile av.DemuxCloser, queue *pubsub.Queue, communication *models.Communication) { //, wg *sync.WaitGroup) { log.Log.Debug("HandleStream: started") diff --git a/machinery/src/capture/main.go b/machinery/src/capture/main.go index 839e79a..eb688e4 100644 --- a/machinery/src/capture/main.go +++ b/machinery/src/capture/main.go @@ -278,6 +278,12 @@ func HandleRecordStream(queue *pubsub.Queue, configuration *models.Configuration startRecording = time.Now().Unix() // we mark the current time when the record started. numberOfChanges := motion.NumberOfChanges + // If we have prerecording we will substract the number of seconds. + // Taking into account FPS = GOP size (Keyfram interval) + if config.Capture.PreRecording > 0 { + startRecording = startRecording - int64(config.Capture.PreRecording) + 1 + } + // timestamp_microseconds_instanceName_regionCoordinates_numberOfChanges_token // 1564859471_6-474162_oprit_577-283-727-375_1153_27.mp4 // - Timestamp @@ -318,7 +324,7 @@ func HandleRecordStream(queue *pubsub.Queue, configuration *models.Configuration var cursorError error var pkt av.Packet var nextPkt av.Packet - recordingCursor := queue.Oldest() + recordingCursor := queue.DelayedGopCount(int(config.Capture.PreRecording)) if cursorError == nil { pkt, cursorError = recordingCursor.ReadPacket() diff --git a/machinery/src/components/Kerberos.go b/machinery/src/components/Kerberos.go index cb74685..4e50b42 100644 --- a/machinery/src/components/Kerberos.go +++ b/machinery/src/components/Kerberos.go @@ -131,14 +131,14 @@ func RunAgent(configuration *models.Configuration, communication *models.Communi // processed by the different consumers: motion detection, recording, etc. queue = pubsub.NewQueue() communication.Queue = queue - queue.SetMaxGopCount(int(config.Capture.PreRecording)) // GOP time frame is set to prerecording. - log.Log.Info("RunAgent: SetMaxGopCount was set with: " + strconv.Itoa(int(config.Capture.PreRecording))) + queue.SetMaxGopCount(int(config.Capture.PreRecording) + 1) // GOP time frame is set to prerecording (we'll add 2 gops to leave some room). + log.Log.Info("RunAgent: SetMaxGopCount was set with: " + strconv.Itoa(int(config.Capture.PreRecording)+1)) queue.WriteHeader(streams) // We might have a substream, if so we'll create a seperate queue. var subQueue *pubsub.Queue if subStreamEnabled { - log.Log.Info("RunAgent: Creating sub stream queue with SetMaxGopCount set to " + strconv.Itoa(int(config.Capture.PreRecording))) + log.Log.Info("RunAgent: Creating sub stream queue with SetMaxGopCount set to " + strconv.Itoa(int(1))) subQueue = pubsub.NewQueue() subQueue.SetMaxGopCount(1) subQueue.WriteHeader(subStreams)