Queue2 with a 4s pre-roll recorder

Hi all.

My aim is to save frames at 2fps and record an rtsp stream with a 4s pre-roll. To do this, I have created the pipeline:

f"rtspsrc location=rtsp://... protocols=tcp latency=200 ! "
f"rtp{codec}depay ! tee name=dep "

# 2fps JPEG branch
f"dep. ! queue ! avdec_{codec} ! videorate ! video/x-raw,framerate=2/1 ! videoconvert ! jpegenc ! "
f"appsink name=appsink2fps emit-signals=true sync=false max-buffers=1 drop=true "

# 4-second ring buffer -> valve -> MP4
f"dep. ! queue2 name=queue4sec use-buffering=true "
f"max-size-time=4000000000 max-size-buffers=0 max-size-bytes=0 ring-buffer-max-size=0 "
f"! valve name=rec_valve drop=true "
f"! {codec}parse ! mp4mux name=mp4mux streamable=true fragment-duration=1000000000 "
f"! filesink name=rec_filesink location=/tmp/rec/test5.mp4 "

However, the second branch blocks the first branch as initially it is drop=true. Even when I start a recording, which opens the valve, the first branch is still blocked and I get no recording. If I start the branch in drop=false, I get frames and a recording.

Am I on the right track to creating the desired output?

Also, I want to change the recording location depending on when the recording happened. To do this I had to stop playing the pipeline, change the location, and then play it again with the valve open. I feel like this isn’t optimal. Would it be better to connect the queue2 branch to an empty sink and then attach a recording pipeline source to it (while recording) to solve both problems?

You can set async=false on the sink element of the branch where drop=true is in effect. That should hopefully make the pipeline preroll.

I’m not sure however whether the 4s backlog queue will work like that, I think probably not.

There’s an example for how to implement dynamic recording with a backlog here for what it’s worth: H.264 backlog recording example ($1760) · Snippets · freedesktop.org / Snippets · GitLab

You can feed the h264 data from rtsp as well of course.

I see, so do you think it is a better idea to use the queue element instead of queue2 - because queue2 cannot use leaky?

If I have you code correct you:

  • Create a sink in queue
  • Attach to it and give a few seconds buffer
  • When recording, attach and remove all frames from the start which aren’t keyframes
  • Attach and record in to a file
  • Cleanup