RidgeRun / gst-interpipe

GStreamer plug-in for interpipeline communication
Other
143 stars 64 forks source link

Strange interaction between different pipelines #92

Open mariannasb opened 3 years ago

mariannasb commented 3 years ago

I have the following pipelines:

pipelines.append("udpsrc name=cam1_udpsrc address=224.1.1.1 port=5000 multicast-iface=enx00051bc005af ! "
                 "application/x-rtp,media=video,payload=33,clock-rate=90000,encoding-name=MP2T ! "
                 "rtpbin ! "
                 "rtpmp2tdepay ! "
                 "tsdemux : h264parse ! "
                 "interpipesink name=cam1_V sync=false async=false forward-events=false ")
pipelines.append("interpipesrc name=filesave listen-to=cam1_V is-live=false stream-sync=passthrough-ts format=time ! "
                 "mpegtsmux name=mux ! "
                 "filesink location=/tmp/test1.ts ")

Basically receiving a multicast stream and saving to a file, works as expected.

However when I add another branch by using another interpipesrc listening to the same sink I start getting files which don't play correctly depending on the src settings and pipe contents:

I don't get why this pipeline should be affecting the other one. I though the whole point of interpipe elements was to decouple to avoid interaction...

I have tried playing with accept-events and forward-events but with no success

mariannasb commented 3 years ago

Moreover, if I change to stream-sync=restart-ts in the filesink pipeline (instead of passthrough-ts), then it works no matter the stream-sync type on the decoder pipeline.

mariannasb commented 3 years ago

A simpler test shows that the PTS and DTS are getting invalid in one branch depending on the stream-sync settings of the other:

pipelines.append("interpipesrc name=file_video listen-to=cam1_V is-live=true stream-sync=passthrough-ts format=time ! h264parse ! mpegtsmux name=mux1 ! filesink location=/tmp/test1.ts")

Debugging buffers shows all is good:

0:00:00.949949651 157109 0x7fbb2c3c95e0 TRACE             GST_TRACER :0:: buffer, pad=(string)file_video:src, pts=(string)0:00:00.809537826, dts=(string)0:00:00.809537826, duration=(string)0:00:00.100000000, offset=(guint64)56502, offset_end=(guint64)18446744073709551615, size=(guint64)16052, flags=(string)GST_BUFFER_FLAG_MARKER+GST_BUFFER_FLAG_DELTA_UNIT, refcount=(uint)3;

However when I add another src listening to the same sink:

pipelines.append("interpipesrc name=file_video listen-to=cam1_V is-live=true stream-sync=passthrough-ts format=time ! "
                 "h264parse ! mpegtsmux name=mux1 ! filesink location=/tmp/test1.ts")

pipelines.append("interpipesrc name=vselect listen-to=cam1_V is-live=true stream-sync=restart-ts format=time ! "
                 "interpipesink name=video_out sync=false async=false")

The PTS and DTS become invalid:

0:00:04.149195659 157362 0x7f5a30041180 TRACE             GST_TRACER :0:: buffer, pad=(string)file_video:src, pts=(string)99:99:99.999999999, dts=(string)99:99:99.999999999, duration=(string)0:00:00.100000000, offset=(guint64)852570, offset_end=(guint64)18446744073709551615, size=(guint64)21906, flags=(string)GST_BUFFER_FLAG_MARKER+GST_BUFFER_FLAG_DELTA_UNIT, refcount=(uint)3;

And if I then change the stream-sync I get valid PTS again. All these combinations work:

pipelines.append("interpipesrc name=file_video listen-to=cam1_V is-live=true stream-sync=restart-ts format=time ! "
                 "h264parse ! mpegtsmux name=mux1 ! filesink location=/tmp/test1.ts")

pipelines.append("interpipesrc name=vselect listen-to=cam1_V is-live=true stream-sync=restart-ts format=time ! "
                 "interpipesink name=video_out sync=false async=false")
pipelines.append("interpipesrc name=file_video listen-to=cam1_V is-live=true stream-sync=passthrough-ts format=time ! "
                 "h264parse ! mpegtsmux name=mux1 ! filesink location=/tmp/test1.ts")

pipelines.append("interpipesrc name=vselect listen-to=cam1_V is-live=true stream-sync=passthrough-ts format=time ! "
                 "interpipesink name=video_out sync=false async=false")
pipelines.append("interpipesrc name=file_video listen-to=cam1_V is-live=true stream-sync=restart-ts format=time ! "
                 "h264parse ! mpegtsmux name=mux1 ! filesink location=/tmp/test1.ts")

pipelines.append("interpipesrc name=vselect listen-to=cam1_V is-live=true stream-sync=passthrough-ts format=time ! "
                 "interpipesink name=video_out sync=false async=false")

I though it had something to so with the segment, but using handle-segment-change=true didn't change anything.

From what I understand from the documentation nothing should propagate upstream when there are 2 listeners? But something seems to be happening here...

mariannasb commented 3 years ago

I believe the problem is here: https://github.com/RidgeRun/gst-interpipe/blob/master/gst/interpipe/gstinterpipesrc.c#L672

} else if (GST_INTER_PIPE_SRC_RESTART_TIMESTAMP == src->stream_sync) {
    /* Remove the incoming timestamp to be generated according this basetime */
    GST_BUFFER_PTS (buffer) = GST_CLOCK_TIME_NONE;
    GST_BUFFER_DTS (buffer) = GST_CLOCK_TIME_NONE;
  }

The PTS and DTS get reset here and affect both branches since it is the same memory?

But only the branch with restart-ts has do-timestamp=true in order to set new values.

But it is just a matter of missing buffer = gst_buffer_make_writable (buffer); like in the compensate-ts branch of the code?

It seems to fix it ;)

https://github.com/RidgeRun/gst-interpipe/pull/95

michaelgruner commented 3 years ago

This seems to be very appropriate. Thanks for the fix, I'll be merging in.