After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 758160 - splitmuxsink with mpegtsmux, curlftpsink generates only the first fragment and pipeline exits with a timeout error.
splitmuxsink with mpegtsmux, curlftpsink generates only the first fragment a...
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gst-plugins-bad
1.6.0
Other Linux
: Normal major
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2015-11-16 07:03 UTC by Raghavendra
Modified: 2018-11-03 13:42 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
curl: curlftpsink throws poll timed out when used with splitmuxsink (1.85 KB, patch)
2016-12-17 07:12 UTC, Vinod Kesti
none Details | Review
curl: curlftpsink throws poll timed out when used with splitmuxsink (2.04 KB, patch)
2016-12-17 07:16 UTC, Vinod Kesti
reviewed Details | Review

Description Raghavendra 2015-11-16 07:03:04 UTC
splitmuxsink with mpegtsmux and curlftpsink is generating only one fragment and pipeline exits after displaying a timeout error with gst_poll_wait API. 

After lots of experiments, I tried disabling the portion of code in the function "handle_transfer" of the file gstcurlbasesink.c of gst-plugins-bad where gst_poll_wait API is being used and GST_FLOW_ERROR is returned if no activity is found the concerned fd. 

By disabling this, I could see the pipeline moving ahead and the fragments being generated at the target location. 

I want to understand what gstcurlbasesink is exactly trying to do and why is it only after disabling this portion of code fragments are being generated. 

Also, I observed one more thing. If I use mp4mux instead of mpegtsmux the pipeline just exits. 
Please help me to resolve these issues. Any quick response is greatly appreciated.
Comment 1 Tim-Philipp Müller 2015-11-16 10:08:19 UTC
mp4mux probably just errors out, because it needs a seekable sink due to how the file format works. mpegtsmux does not need that.

Have you tried a pipeline without splitmuxsink?

Something like ... ! mpegtsmux ! curlftpsink ?
Comment 2 Raghavendra 2015-11-16 12:58:19 UTC
I tried the following pipelines.

1. gst-launch-1.0 filesrc location=/root/big_buck_bunny_270p.mp4 ! decodebin ! videoconvert ! x264enc ! mp4mux name=muxer ! curlftpsink user=test22 passwd=test22 location=ftp://10.0.0.16/ file-name=new.mp4

This works with gstreamer-1.2.2 and gstreamer-1.5.2 & I could see the file dump at destination. But the same pipeline exits with gstreamer-1.6.0.

2. gst-launch-1.0 filesrc location=/root/big_buck_bunny_270p.mp4 ! decodebin ! videoconvert ! x264enc ! mpegtsmux name=muxer ! curlftpsink user=test22 passwd=test22 location=ftp://10.0.0.16/ file-name=new.ts

This pipeline works and I could see the file dump at destination.

3. gst-launch-1.0 filesrc location=/root/big_buck_bunny_270p.mp4 ! decodebin ! videoconvert ! x264enc ! splitmuxsink muxer="mpegtsmux name=muxer" sink="curlftpsink user=test22 passwd=test22" location=ftp://10.0.0.16/test_bunny.ts max-size-time=10000000000 max-size-bytes=18446744073709551615

This pipeline generates first fragment and then timesout. Pipeline exits after throwing timeout error.

If I disable the code which I mentioned in earlier comment (in the function "handle_transfer" of the file gstcurlbasesink.c of gst-plugins-bad where gst_poll_wait API is being used and GST_FLOW_ERROR is returned if no activity is found the concerned fd), I could see all the fragments getting generated. 

This is seen with gstreamer-1.6.0

4. gst-launch-1.0 filesrc location=/root/big_buck_bunny_270p.mp4 ! decodebin ! videoconvert ! x264enc ! splitmuxsink muxer="mp4mux name=muxer" sink="curlftpsink user=test22 passwd=test22" location=ftp://10.0.0.16/test_bunny.mp4 max-size-time=10000000000 max-size-bytes=18446744073709551615

This pipelne just exits with gstreamer-1.6.0

Regards,
Raghavendra Rao
Comment 3 Thiago Sousa Santos 2015-11-17 19:39:59 UTC
Can you clarify whether the generated files with 1.2 and 1.4 actually work (play successfully)? Specially the ones using mp4mux.
Comment 4 Raghavendra 2015-11-18 08:28:35 UTC
I am able to play the files generated with mpegtsmux but not those which got genereated by mp4mux.
Comment 5 Tim-Philipp Müller 2015-11-18 08:57:09 UTC
mp4mux won't work with curlftpsink (unless someone writes an element that pretends to be seekable and caches all data internally or in a file, and only sends it in one go once it gets EOS), but it should error out.

Perhaps curlftpsink needs to implement the SEEKING query.
Comment 6 Randeep 2016-01-19 05:40:36 UTC
Hi,

I'm able to interleave audio and video using splitmuxsink for avimux. But this is not happening for mpegtsmux. For mpegtsmux I'm getting negotiation error.
Pipeline which i used for avimux is given below,

gst-launch-1.0 videotestsrc do-timestamp=true num-buffers=300 ! 'video/x-raw,width=720,height=480,format=NV12,framerate=30/1' ! splitmuxsink name=mux location= <Output_File.avi> muxer=avimux filesrc location= ./audio.wav ! wavparse ! teaacenc ! mux.audio_0

Can anyone please provide the pipeline to interleave audio and video using splitmuxsink using mpegtsmux ?
Comment 7 Jan Schmidt 2016-01-19 06:37:22 UTC
(In reply to Randeep from comment #6)
> Hi,
> 
> I'm able to interleave audio and video using splitmuxsink for avimux. But
> this is not happening for mpegtsmux. For mpegtsmux I'm getting negotiation
> error.
> Pipeline which i used for avimux is given below,
> 
> gst-launch-1.0 videotestsrc do-timestamp=true num-buffers=300 !
> 'video/x-raw,width=720,height=480,format=NV12,framerate=30/1' ! splitmuxsink
> name=mux location= <Output_File.avi> muxer=avimux filesrc location=
> ./audio.wav ! wavparse ! teaacenc ! mux.audio_0
> 
> Can anyone please provide the pipeline to interleave audio and video using
> splitmuxsink using mpegtsmux ?

If you look at the gst-inspect output for mpegtsmux, you'll see that it doesn't support muxing raw video frames. Input has to be H.264, MPEG-2 or Dirac video.
Comment 8 Randeep 2016-01-19 08:58:52 UTC
(In reply to Jan Schmidt from comment #7)
> (In reply to Randeep from comment #6)
> > Hi,
> > 
> > I'm able to interleave audio and video using splitmuxsink for avimux. But
> > this is not happening for mpegtsmux. For mpegtsmux I'm getting negotiation
> > error.
> > Pipeline which i used for avimux is given below,
> > 
> > gst-launch-1.0 videotestsrc do-timestamp=true num-buffers=300 !
> > 'video/x-raw,width=720,height=480,format=NV12,framerate=30/1' ! splitmuxsink
> > name=mux location= <Output_File.avi> muxer=avimux filesrc location=
> > ./audio.wav ! wavparse ! teaacenc ! mux.audio_0
> > 
> > Can anyone please provide the pipeline to interleave audio and video using
> > splitmuxsink using mpegtsmux ?
> 
> If you look at the gst-inspect output for mpegtsmux, you'll see that it
> doesn't support muxing raw video frames. Input has to be H.264, MPEG-2 or
> Dirac video.

The example pipeline was for avimux, for mpegtsmux i used the below pipeline with encoded video as input. But still i'm not able to connect the audio to the right pad of mpegtsmux. mpegtsmux expects audio in sink_%d and splitmuxsink expects audio in audio_%0, will this be a problem ? 
can you please check the pipeline i used for splitmuxsink for mpegtsmux and correct me if i'm wrong somewhere.

gst-launch-1.0 filesrc location= ./Drive_safe.mp4.h264 ! h264parse ! splitmuxsink name=mux location=Output_File.ts muxer=mpegtsmux filesrc location= ./audio.wav ! wavparse ! teaacenc ! mux.audio_0

My final goal is to interleave both audio and video using splitmuxsink for mpegtsmux. For 'avimux' i was able to interleave the same.
Comment 9 Thiago Sousa Santos 2016-01-19 12:23:25 UTC
(In reply to Randeep from comment #8)
> (In reply to Jan Schmidt from comment #7)
> > (In reply to Randeep from comment #6)
> > > Hi,
> > > 
> > > I'm able to interleave audio and video using splitmuxsink for avimux. But
> > > this is not happening for mpegtsmux. For mpegtsmux I'm getting negotiation
> > > error.
> > > Pipeline which i used for avimux is given below,
> > > 
> > > gst-launch-1.0 videotestsrc do-timestamp=true num-buffers=300 !
> > > 'video/x-raw,width=720,height=480,format=NV12,framerate=30/1' ! splitmuxsink
> > > name=mux location= <Output_File.avi> muxer=avimux filesrc location=
> > > ./audio.wav ! wavparse ! teaacenc ! mux.audio_0
> > > 
> > > Can anyone please provide the pipeline to interleave audio and video using
> > > splitmuxsink using mpegtsmux ?
> > 
> > If you look at the gst-inspect output for mpegtsmux, you'll see that it
> > doesn't support muxing raw video frames. Input has to be H.264, MPEG-2 or
> > Dirac video.
> 
> The example pipeline was for avimux, for mpegtsmux i used the below pipeline
> with encoded video as input. But still i'm not able to connect the audio to
> the right pad of mpegtsmux. mpegtsmux expects audio in sink_%d and
> splitmuxsink expects audio in audio_%0, will this be a problem ? 
> can you please check the pipeline i used for splitmuxsink for mpegtsmux and
> correct me if i'm wrong somewhere.
> 
> gst-launch-1.0 filesrc location= ./Drive_safe.mp4.h264 ! h264parse !
> splitmuxsink name=mux location=Output_File.ts muxer=mpegtsmux filesrc
> location= ./audio.wav ! wavparse ! teaacenc ! mux.audio_0
> 
> My final goal is to interleave both audio and video using splitmuxsink for
> mpegtsmux. For 'avimux' i was able to interleave the same.

You just request audio_%u for splitmuxsink and it will request a sink_%d from mpegtsmux. It works here with a simple example:

gst-launch-1.0 videotestsrc num-buffers=10000 ! x264enc ! splitmuxsink muxer=mpegtsmux location=test%03d.ts max-size-time=2000000000

This seems unrelated to this bug, please open a separate one if you still have problems.
Comment 10 Vinod Kesti 2016-12-17 07:12:52 UTC
Created attachment 342106 [details] [review]
curl: curlftpsink throws poll timed out when used with splitmuxsink

I also faced similar issues. I found issue with GstPoll. 
curlbasesink opens GstPoll for curlfd on start and closes on stop. When curlftpsink and curlhttpsink
are used with splitmuxsink, start and stop  functions are called for every fragment generated. Upon every fragment
curlbasesink creates new GstPoll, but curl generates FD only once. For second fragment onwards gst_poll_wait waits on FD -1
and times out as no action happening on FD -1. Now GstPoll created once and reused.

With this patch it works for me.
Comment 11 Vinod Kesti 2016-12-17 07:16:47 UTC
Created attachment 342107 [details] [review]
curl: curlftpsink throws poll timed out when used with splitmuxsink

All,

Sorry previously I updated wrong patch,

I also faced same issue. I found GstPoll is not used properly.
curlbasesink opens GstPoll for curlfd on start and closes on stop. When curlftpsink and curlhttpsink
are used with splitmuxsink, start and stop  functions are called for every fragment generated. Upon every fragment
curlbasesink creates new GstPoll, but curl generates FD only once. For second fragment onwards gst_poll_wait waits on FD -1
and times out as no action happening on FD -1. Now GstPoll created once and reused.

I have created patch on today git master.
With this patch it is working for me.

Regards,
Vinod
Comment 12 Vinod Kesti 2017-01-02 10:57:41 UTC
Can some one please review the patch ??
Comment 13 Jan Schmidt 2017-01-02 14:58:44 UTC
Review of attachment 342107 [details] [review]:

::: ext/curl/gstcurlbasesink.c
@@ -468,3 @@
-    gst_poll_free (sink->fdset);
-    sink->fdset = NULL;
-  }

This doesn't seem quite right. In general, in ->stop(), elements should clean up dynamic resources that were created in start() or during streaming. If curl is reusing data across calls to start()/stop()/start(), it sounds like it's not doing enough cleanup in stop().
Comment 14 Vinod Kesti 2017-01-03 10:08:30 UTC
Hi Jan,

If that is the case then we have to call gst_curl_base_sink_transfer_cleanup function in ->stop(). Currently it is called in ->finalize() function. 
adding gst_curl_base_sink_transfer_cleanup function call to ->stop() function also works.

But what I feel is calling gst_curl_base_sink_transfer_cleanup in ->stop() function is adds extra overhead, for every fragment created by splitmuxsink curl creates new session and closes at the end.

From functionality point what you said is correct. But from optimisation point I feel reusing connection is good.

Need your view on this..

~ Vinod
Comment 15 Jan Schmidt 2017-01-03 12:34:02 UTC
We recently made souphttpsrc keep connections open until it's moved to the NULL state, rather than READY when stop() is called - so it's probably OK to do that here too as long as:

* Connections are cleaned up on READY -> NULL transition, rather than in finalize, since element instances might stick around a while in garbage-collected environments, but we still want them to clean themselves up.

* The element is reusable from the READY state. We expect that setting an element to READY and changing the URI, then setting it back to PAUSED/PLAYING should start output to the new URI instead. I realise that didn't work before anyway, but it's the expected behaviour so we might as well fix it.
Comment 16 GStreamer system administrator 2018-11-03 13:42:39 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/issues/323.