Vincentz
Vincentz

Reputation: 546

GStreamer: how to pause h.264 recording whilst still displaying live video

My pipeline is as follows:

rtspsrc -> tee -> queue (Q1) -> mp4mux  -> filesink
           tee -> queue      -> decoder -> displaysink

I need to be able to pause and resume recording. I installed a pad probe on the sink pad of Q1 and drop the samples whilst recording is paused. When recording is enabled, I edit the timestamps to ensure they remain monotonic as otherwise when I playback the MP4 the video will freeze for the duration of the gap in the timestamps. The pad probe also allows me to 'cut' the H.264 stream on an I-Frames so that the recording is made of full GOPs.

Here is an extract from the pad probe:

if (This->RecordPaused) {
   return GST_PAD_PROBE_DROP;
} else {
   This->monotonicTimestamp += GST_BUFFER_DURATION(buffer);
   GST_BUFFER_PTS(buffer) = This->monotonicTimestamp;
   GST_BUFFER_DTS(buffer) = This->monotonicTimestamp;
}

My problem is that the timestamps are also modified for GstSamples on the display path. The decoder produces warnings that the timestamps are going backwards. Usually this has no effect on the display, but if I insert the deinterlace element then the display freezes when there is a gap in the timestamps.

I suspect the tee is sending references to the GstSamples to the two branches, instead of shallow-copying the GstSamples, so editing the timestamps on one affects the other.

I am thinking of rewriting the recording branch to use appsink and appsrc as follows:

queue (Q1) -> appsink
appsrc     ->  mp4mux  -> filesink

That way I can create separate GstSample s and set their timestamps to a monotonic timer without affecting the other branch of the pipeline.

However, I am wondering if this is the correct approach or if there is already a built-in way to do what I need in GStreamer?

I have been reading about Segments, but I have not found good doc to understand if it could be used for my use-case. This post seems to imply it could, but how should I construct the Segment event and can I send it from my pad probe?

Alternatively, is there an element I could use to ensure the GstSamples are duplicated (ideally without deep-copying the underlying memory)?

EDIT

Looking at gsttee.c I confirmed the tee sends refs of GstBuffers, which explains the behaviour. Is there an existing element I could use to do a shallow-copy of the GstBuffer? Alternatively I could write one myself, but it does feel like the wrong way to go about getting what I need...

Upvotes: 1

Views: 380

Answers (0)

Related Questions