I’m currently developing a prototype for a feature that requires pre-recording video before a trigger event. To test the concept, I built a small prototype that listens for keyboard input and saves video recordings accordingly.
My goal is to maintain a 15-second recording buffer before the trigger occurs. For that, I referred to this example: GStreamer Rolling Buffer Snippet
The following GStreamer pipeline works perfectly with my current codebase:
app.pipeline =
gst_parse_launch(
"nvv4l2camerasrc device=/dev/video0 ! "
"video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1 ! "
"nvvidconv ! video/x-raw,format=NV12 ! "
"clockoverlay shaded-background=true ! "
"nvvidconv ! video/x-raw(memory:NVMM),format=NV12 ! "
"nvv4l2h264enc insert-sps-pps=true iframeinterval=30 bitrate=6000000 ! "
"h264parse ! tee name=vtee "
/* Display branch (hardware decode + EGL sink) */
"vtee. ! queue ! h264parse ! nvv4l2decoder ! "
"nvvidconv ! nvegltransform ! nveglglessink sync=false "
/* Recording branch (uses rolling queue) */
"vtee. ! queue name=vrecq max-size-time=15000000000 max-size-bytes=0 max-size-buffers=0 "
"! mp4mux name=mux ! filesink async=false name=filesink",
NULL);
However, in my pipeline architecture, the encoder must be placed after the tee element, so I modified it as follows:
app.pipeline = gst_parse_launch(
"nvv4l2camerasrc device=/dev/video0 ! "
"video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1 ! "
"nvvidconv ! video/x-raw,format=NV12 ! "
"clockoverlay shaded-background=true ! "
"nvvidconv ! video/x-raw(memory:NVMM),format=NV12 ! "
"tee name=main_tee "
/* Display branch */
"main_tee. ! queue ! nvvidconv ! nvegltransform ! nveglglessink sync=false "
/* Recording branch */
"main_tee. ! queue ! nvvidconv ! "
"nvv4l2h264enc name=record_encoder insert-sps-pps=true iframeinterval=30 bitrate=8000000 ! "
"h264parse name=record_h264parse ! "
"queue name=vrecq max-size-time=15000000000 max-size-bytes=0 max-size-buffers=0 ! "
"mp4mux name=mux ! filesink async=false name=filesink",
NULL);
Unfortunately, this modified version does not work as expected—the video is not saved, even though the first pipeline works fine. I’m not sure where the issue lies or how to debug it further.
The placeholder video that gets created is of 595bytes and is corrupt and i was trying different stuff which sometimes halt the whole pipeline after stop_recording .
How do i make sure encoder to be after the tee element strictly
I’ve attached the full codebase I created for testing this pre-record circular buffer setup.