GNOME Bugzilla – Bug 625597
gst-rtsp-server needs to send EOS on client session end so that elements such as 'filesink' are satisfied
Last modified: 2011-01-12 16:01:20 UTC
Created attachment 166783 [details] Patch to allow elements such as 'filesink" that need an EOS to receive an EOS when an RTSP client session ends. test-launch "gnomevfssrc location=http://admin:mncamera@192.168.1.176/img/video.asf ! tee name=t ! queue ! fluasfdemux ! mpeg4videoparse ! rtpmp4vpay pt=96 name=pay0 t. ! queue ! fluasfdemux ! mpeg4videoparse ! mp4mux ! filesink location=file.mp4" Above is an example pipeline passed in to test-launch. Currently, when the client session ends the pipelines do not receive an EOS resulting in an unplayable file being generated by the 'filesink' element above. The attached patch fixes this problem.
That patch is not quite right. The part where you send the EOS is also the part that is executed when the client issues a pause request. You probably want to send the EOS into the pipeline only right before the pipeline is set to READY or NULL. Also the logic to send the EOS to all elements in the pipeline is not so good. It should be possible to just send the EOS to the pipeline, which then dispatches it to all sources in the pipeline. I will take a look how this patch can be improved.
(In reply to comment #1) > That patch is not quite right. > > The part where you send the EOS is also the part that is executed when the > client issues a pause request. You probably want to send the EOS into the > pipeline only right before the pipeline is set to READY or NULL. > > Also the logic to send the EOS to all elements in the pipeline is not so good. > It should be possible to just send the EOS to the pipeline, which then > dispatches it to all sources in the pipeline. > > I will take a look how this patch can be improved. Hello Wim, I tried to send the EOS down the pipeline but it seemed as though it was not propagated to all of the elements. I admit that the logic itself is pretty much a hack. I needed to be able to have an EOS sent down the pipeline since I was recording the stream to a file as well. Let me know how I can help. Best Regards, Rob Krakora
(In reply to comment #2) > I tried to send the EOS down the pipeline but it seemed as though it was not > propagated to all of the elements. There seems to be a problem in the GStreamer core with the dispatching of the EOS events to sources. Will fix that.
commit 57cc780c45a4c14decda0ac5fde58db3d13c7980 Author: Wim Taymans <wim.taymans@collabora.co.uk> Date: Fri Aug 20 18:04:52 2010 +0200 bin: relax the source element check When there is a sink inside a bin, the SINK flag is set on the bin. When we are trying to iterate the source elements, also include the bins with the SINK flag because they could also contain source elements, in which case they are also a source. This solves the case where sending an EOS to a pipeline didn't get dispatched to all source elements. See #625597
I commited my version. It's possible to set the eos-shutdown property on the media factory or media, which will trigger the sending of the EOS event. You need git core for this to work. commit dc33070da3c28f81b083f20881234a712babe0fc Author: Wim Taymans <wim.taymans@collabora.co.uk> Date: Fri Aug 20 18:17:08 2010 +0200 media-factory: add eos-shutdown property Add an eos-shutdown property that will send an EOS to the pipeline before shutting it down. This allows for nice cleanup in case of a muxer. Fixes #625597
(In reply to comment #5) > I commited my version. It's possible to set the eos-shutdown property on the > media factory or media, which will trigger the sending of the EOS event. You > need git core for this to work. > > commit dc33070da3c28f81b083f20881234a712babe0fc > Author: Wim Taymans <wim.taymans@collabora.co.uk> > Date: Fri Aug 20 18:17:08 2010 +0200 > > media-factory: add eos-shutdown property > > Add an eos-shutdown property that will send an EOS to the pipeline before > shutting it down. This allows for nice cleanup in case of a muxer. > > Fixes #625597 Hello Wim, Thanks so much for addressing this issue so promptly. I will get the core and test it out. Best Regards, Rob Krakora
Hello Wim, When I compiled the core I got some warnings that were interpreted by the compiler as errors. Here are the changes I had to make to negate the warnings. Best Regards, Rob Krakora diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index c6a45ac..886b9c7 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -1664,11 +1664,11 @@ add_udp_destination (GstRTSPMedia *media, GstRTSPMediaSt gchar *dest, gint min, gint max) { gboolean do_add = TRUE; - RTSPDestination *ndest; + RTSPDestination *ndest = NULL; if (stream->filter_duplicates) { RTSPDestination fdest; - GList *find; + GList *find = NULL; fdest.dest = dest; fdest.min = min; @@ -1702,8 +1702,8 @@ remove_udp_destination (GstRTSPMedia *media, GstRTSPMediaS gchar *dest, gint min, gint max) { gboolean do_remove = TRUE; - RTSPDestination *ndest;
This patch can't work, it removes the ndest variable.
Hi Wim, I just sets the ndest variable to NULL it does not remove it. Best Regards, Rob Krakora
Hi Wim, I tested your fix for EOS and it worked great with one client. However, with two clients it sent the EOS when one client was exited and killed the pipe line for the other client. I hacked on the code a bit and was able to get the behavior that I was expecting with more than one client. Let me know if I am just misusing the RTSP server or if this is a legitimate problem. The hack is not meant to be a permanent fix, just to show you where there may be a problem. Here is the hack-patch: diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c old mode 100644 new mode 100755 index c6a45ac..4ccd172 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -27,7 +27,7 @@ #define DEFAULT_SHARED FALSE #define DEFAULT_REUSABLE FALSE -#define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_TCP +#define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_TCP //#define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP_MCAST #define DEFAULT_EOS_SHUTDOWN FALSE @@ -129,6 +129,7 @@ gst_rtsp_media_init (GstRTSPMedia * media) media->cond = g_cond_new (); media->shared = DEFAULT_SHARED; + media->shared_cnt = 0; media->reusable = DEFAULT_REUSABLE; media->protocols = DEFAULT_PROTOCOLS; media->eos_shutdown = DEFAULT_EOS_SHUTDOWN; @@ -1496,7 +1497,11 @@ gst_rtsp_media_prepare (GstRTSPMedia * media) GList *walk; if (media->status == GST_RTSP_MEDIA_STATUS_PREPARED) + { + if (media->shared) + media->shared_cnt++; goto was_prepared; + } if (!media->reusable && media->reused) goto is_reused; @@ -1643,7 +1648,10 @@ gst_rtsp_media_unprepare (GstRTSPMedia * media) static gboolean default_unprepare (GstRTSPMedia * media) { - if (media->eos_shutdown) { + if (media->shared && media->shared_cnt > 0) + media->shared_cnt--; + + if (media->eos_shutdown && media->shared_cnt == 0) { GST_DEBUG ("sending EOS for shutdown"); /* ref so that we don't disappear */ g_object_ref (media); @@ -1656,6 +1664,7 @@ default_unprepare (GstRTSPMedia * media) GST_DEBUG ("shutting down"); gst_element_set_state (media->pipeline, GST_STATE_NULL); } + return TRUE; } @@ -1664,11 +1673,11 @@ add_udp_destination (GstRTSPMedia *media, GstRTSPMediaStream *stream, gchar *dest, gint min, gint max) { gboolean do_add = TRUE; - RTSPDestination *ndest; + RTSPDestination *ndest = NULL; if (stream->filter_duplicates) { RTSPDestination fdest; - GList *find; + GList *find = NULL; fdest.dest = dest; fdest.min = min; @@ -1702,8 +1711,8 @@ remove_udp_destination (GstRTSPMedia *media, GstRTSPMediaStream *stream, gchar *dest, gint min, gint max) { gboolean do_remove = TRUE; - RTSPDestination *ndest; - GList *find; + RTSPDestination *ndest = NULL; + GList *find = NULL; if (stream->filter_duplicates) { RTSPDestination fdest; diff --git a/gst/rtsp-server/rtsp-media.h b/gst/rtsp-server/rtsp-media.h old mode 100644 new mode 100755 index 211e2c0..081436b --- a/gst/rtsp-server/rtsp-media.h +++ b/gst/rtsp-server/rtsp-media.h @@ -196,6 +196,7 @@ struct _GstRTSPMedia { GCond *cond; gboolean shared; + gint shared_cnt; gboolean reusable; GstRTSPLowerTrans protocols; gboolean reused; Best Regards, Rob Krakora
(In reply to comment #10) > Hi Wim, > > I tested your fix for EOS and it worked great with one client. However, with > two clients it sent the EOS when one client was exited and killed the pipe line > for the other client. > > I hacked on the code a bit and was able to get the behavior that I was > expecting with more than one client. Let me know if I am just misusing the > RTSP server or if this is a legitimate problem. The hack is not meant to be a > permanent fix, just to show you where there may be a problem. This can't really happen, for shared media the prepare and unprepare methods are only called when all clients are done with the media.
Hi Wim, If shutdown-on-eos and shared are enabled in the server and two clients are connected, the server blows up if one of the clients terminates it's connection. I have tested this many times without my hack and this indeed appears to be the case. I will send you a trace. Best Regards, Rob Krakora (In reply to comment #11) > (In reply to comment #10) > > Hi Wim, > > > > I tested your fix for EOS and it worked great with one client. However, with > > two clients it sent the EOS when one client was exited and killed the pipe line > > for the other client. > > > > I hacked on the code a bit and was able to get the behavior that I was > > expecting with more than one client. Let me know if I am just misusing the > > RTSP server or if this is a legitimate problem. The hack is not meant to be a > > permanent fix, just to show you where there may be a problem. > > This can't really happen, for shared media the prepare and unprepare methods > are only called when all clients are done with the media.
(In reply to comment #12) > Hi Wim, > > If shutdown-on-eos and shared are enabled in the server and two clients are > connected, the server blows up if one of the clients terminates it's > connection. I have tested this many times without my hack and this indeed > appears to be the case. I will send you a trace. Strange. I will try this.
(In reply to comment #13) > (In reply to comment #12) > > Hi Wim, > > > > If shutdown-on-eos and shared are enabled in the server and two clients are > > connected, the server blows up if one of the clients terminates it's > > connection. I have tested this many times without my hack and this indeed > > appears to be the case. I will send you a trace. > > Strange. I will try this. I tried and it doesn't fail. I need your trace then.
Hi Wim, First off, my profound apologies. I had a bug in my test code that exercised the server. I fixed the bug and now I cannot get the server to fail with my "hack" removed. The prepare and unprepare methods only get called after no client needs the media as you stated. I should have looked at my test code more carefully before jumping to conclusions. Thanks for your prompt attention to this matter that has unfortunately wasted your time. Also, thanks for the official RTSP server release yesterday. ;-) Best Regards, Rob Krakora