gst-interpipe
gst-interpipe copied to clipboard
Strange interaction between different pipelines
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:
- This works fine
pipelines.append("interpipesrc listen-to=cam1_V name=vselect is-live=false stream-sync=passthrough-ts format=time ! "
"avdec_h264 qos=false name=dec_live ! "
"fakesink ")
- However if I change to stream-sync to
restart-ts
then my file doesn't play correctly.
pipelines.append("interpipesrc listen-to=cam1_V name=vselect is-live=false stream-sync=restart-ts format=time ! "
"avdec_h264 qos=false name=dec_live ! "
"fakesink ")
- If I remove the decoder it works with
restart-ts
pipelines.append("interpipesrc listen-to=cam1_V name=vselect is-live=false stream-sync=restart-ts format=time ! "
"fakesink ")
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
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.
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...
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
This seems to be very appropriate. Thanks for the fix, I'll be merging in.