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 707611 - rtspsrc state change always blocks when source is offline (waiting for connect timeout)
rtspsrc state change always blocks when source is offline (waiting for connec...
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-base
git master
Other All
: Normal blocker
: 1.1.90
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2013-09-06 08:32 UTC by Dmitry Shatrov
Modified: 2013-09-18 16:51 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Dmitry Shatrov 2013-09-06 08:32:27 UTC
gst_element_set_state (playbin, GST_STATE_PLAYING) always blocks for a pipeline with rtspsrc when source IP is not responding, i.e. it appears to wait synchronously for connect() to complete.

The problem appears to be because of the following lines in gstrtspsrc.c:

    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      /* unblock the tcp tasks and make the loop waiting */
      gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_WAIT, CMD_LOOP);
      /* make sure it is waiting before we send PAUSE or PLAY below */
// BUG: BLOCKS HERE
      GST_RTSP_STREAM_LOCK (rtspsrc);
      GST_RTSP_STREAM_UNLOCK (rtspsrc);

Lock/unlock pair wasn't there in older versions, and gst_element_set_state() did not block (there was proper async state change).

Here are backtraces from my app for two threads. The first one is the application thread which should not block, but it blocks because of this bug. The second one is gstreamer's rtspsrc thread. Line numbers are for gstreamer-1.0.9 release.

Application thread:
  • #0 __lll_lock_wait
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S line 135
  • #1 _L_lock_928
    from /opt/moment/lib/libpthread.so.0
  • #2 __GI___pthread_mutex_lock
    at pthread_mutex_lock.c line 85
  • #3 gst_rtspsrc_change_state
    at gstrtspsrc.c line 6725
  • #4 gst_element_change_state
    at gstelement.c line 2594
  • #5 gst_element_set_state_func
    at gstelement.c line 2550
  • #6 gst_bin_element_set_state
    at gstbin.c line 2292
  • #7 gst_bin_change_state_func
    at gstbin.c line 2594
  • #8 gst_uri_decode_bin_change_state
    at gsturidecodebin.c line 2580
  • #9 gst_element_change_state
    at gstelement.c line 2594
  • #10 gst_element_set_state_func
    at gstelement.c line 2550
  • #11 gst_bin_element_set_state
    at gstbin.c line 2292
  • #12 gst_bin_change_state_func
    at gstbin.c line 2594
  • #13 gst_pipeline_change_state
    at gstpipeline.c line 471
  • #14 gst_element_change_state
    at gstelement.c line 2594
  • #15 gst_element_set_state_func
    at gstelement.c line 2550
  • #0 poll
    at ../sysdeps/unix/syscall-template.S line 81
  • #1 g_socket_condition_timed_wait
    at gsocket.c line 3562
  • #2 do_connect
    at gstrtspconnection.c line 457
  • #3 gst_rtsp_connection_connect
    at gstrtspconnection.c line 725
  • #4 gst_rtsp_conninfo_connect
    at gstrtspsrc.c line 3371
  • #5 gst_rtspsrc_retrieve_sdp
    at gstrtspsrc.c line 5642
  • #6 gst_rtspsrc_open
    at gstrtspsrc.c line 5809
  • #7 gst_rtspsrc_thread
    at gstrtspsrc.c line 6602
  • #8 gst_task_func
    at gsttask.c line 316
  • #9 g_thread_pool_thread_proxy
    at gthreadpool.c line 309
  • #10 g_thread_proxy
    at gthread.c line 798
  • #11 start_thread
    at pthread_create.c line 308
  • #12 clone
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S line 114

Comment 1 Dmitry Shatrov 2013-09-06 08:34:06 UTC
Backtraces have been automatically screwed up by bugzilla. Repeating:

Application thread:
  • #0 __lll_lock_wait
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S line 135
  • #1 _L_lock_928
    from /opt/moment/lib/libpthread.so.0
  • #2 __GI___pthread_mutex_lock
    at pthread_mutex_lock.c line 85
  • #3 gst_rtspsrc_change_state
    at gstrtspsrc.c line 6725
  • #4 gst_element_change_state
    at gstelement.c line 2594
  • #5 gst_element_set_state_func
    at gstelement.c line 2550
  • #6 gst_bin_element_set_state
    at gstbin.c line 2292
  • #7 gst_bin_change_state_func
    at gstbin.c line 2594
  • #8 gst_uri_decode_bin_change_state
    at gsturidecodebin.c line 2580
  • #9 gst_element_change_state
    at gstelement.c line 2594
  • #10 gst_element_set_state_func
    at gstelement.c line 2550
  • #11 gst_bin_element_set_state
    at gstbin.c line 2292
  • #12 gst_bin_change_state_func
    at gstbin.c line 2594
  • #13 gst_pipeline_change_state
    at gstpipeline.c line 471
  • #14 gst_element_change_state
    at gstelement.c line 2594
  • #15 gst_element_set_state_func
    at gstelement.c line 2550

Comment 2 Dmitry Shatrov 2013-09-06 08:34:18 UTC
GStreamer rtspsrc thread:
  • #0 poll
    at ../sysdeps/unix/syscall-template.S line 81
  • #1 g_socket_condition_timed_wait
    at gsocket.c line 3562
  • #2 do_connect
    at gstrtspconnection.c line 457
  • #3 gst_rtsp_connection_connect
    at gstrtspconnection.c line 725
  • #4 gst_rtsp_conninfo_connect
    at gstrtspsrc.c line 3371
  • #5 gst_rtspsrc_retrieve_sdp
    at gstrtspsrc.c line 5642
  • #6 gst_rtspsrc_open
    at gstrtspsrc.c line 5809
  • #7 gst_rtspsrc_thread
    at gstrtspsrc.c line 6602
  • #8 gst_task_func
    at gsttask.c line 316
  • #9 g_thread_pool_thread_proxy
    at gthreadpool.c line 309
  • #10 g_thread_proxy
    at gthread.c line 798
  • #11 start_thread
    at pthread_create.c line 308
  • #12 clone
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S line 114

Comment 3 Dmitry Shatrov 2013-09-06 08:49:32 UTC
Reverting gst-plugins-base commit b96d931bf4ce5c3c8c5be4fa76f5c75bca85d0c4 fixes the problem.
Comment 4 Sebastian Dröge (slomo) 2013-09-09 11:52:57 UTC
In gst-plugins-good though:

commit b96d931bf4ce5c3c8c5be4fa76f5c75bca85d0c4
Author: Wim Taymans <wim.taymans@collabora.co.uk>
Date:   Thu Jun 20 14:43:47 2013 +0200

    rtspsrc: fix race in state change to paused
    
    When we go to paused, we first flush the connection and then send the pause
    command. As a result of the flushing, the scheduled paused command can get
    lost. Wait until the connection is completely flushed and the rtsp task is
    waiting before issuing the paused or playing request.
    
    Fixes https://bugzilla.gnome.org/show_bug.cgi?id=702705



Also a blocker for 1.0.11!
Comment 5 Wim Taymans 2013-09-09 13:18:36 UTC
Please try this an reopen if still a problem:

commit 9f9bcbc40578847821412e6949984cdc96ebf77a
Author: Wim Taymans <wim.taymans@collabora.co.uk>
Date:   Mon Sep 9 15:11:51 2013 +0200

    rtspsrc: only wait if we flushed
    
    Only wait for the STREAM_LOCK when we flushed something when sending
    a command for PAUSED or PLAYING.
    
    Fixes https://bugzilla.gnome.org/show_bug.cgi?id=707611