[rhythmbox] xfade: handle linking and unblocking streams better



commit e57c81ef95196dc8edbfd21555b86a25787d4efc
Author: Jonathan Matthew <jonathan d14n org>
Date:   Wed May 12 22:18:32 2021 +1000

    xfade: handle linking and unblocking streams better
    
    If the stream already has an adder pad, contine on with the rest
    of the process anyway.  It doesn't really matter whether the
    stream is blocked or not, we need to remove the block either way.
    Sometimes a stream can finish buffering before it gets blocked,
    which this function needs to be able to handle.

 backends/gstreamer/rb-player-gst-xfade.c | 126 ++++++++++++++-----------------
 1 file changed, 56 insertions(+), 70 deletions(-)
---
diff --git a/backends/gstreamer/rb-player-gst-xfade.c b/backends/gstreamer/rb-player-gst-xfade.c
index 4862b9320..4952eebd8 100644
--- a/backends/gstreamer/rb-player-gst-xfade.c
+++ b/backends/gstreamer/rb-player-gst-xfade.c
@@ -1090,88 +1090,74 @@ link_and_unblock_stream (RBXFadeStream *stream, GError **error)
        }
 
        g_mutex_lock (&stream->lock);
-       if (stream->adder_pad != NULL) {
-               rb_debug ("stream %s is already linked", stream->uri);
-               g_mutex_unlock (&stream->lock);
-               return TRUE;
-       }
        stream->needs_unlink = FALSE;
-
-       rb_debug ("linking stream %s", stream->uri);
-       if (GST_ELEMENT_PARENT (GST_ELEMENT (stream)) == NULL)
-               gst_bin_add (GST_BIN (player->priv->pipeline), GST_ELEMENT (stream));
-
-       stream->adder_pad = gst_element_get_request_pad (player->priv->adder, "sink_%u");
        if (stream->adder_pad == NULL) {
-               /* this error message kind of sucks */
-               rb_debug ("couldn't get adder pad to link in new stream");
-               g_set_error (error,
-                            RB_PLAYER_ERROR,
-                            RB_PLAYER_ERROR_GENERAL,
-                            _("Failed to link new stream into GStreamer pipeline"));
-               g_mutex_unlock (&stream->lock);
-               return FALSE;
-       }
-
-       plr = gst_pad_link (stream->ghost_pad, stream->adder_pad);
-       if (GST_PAD_LINK_FAILED (plr)) {
-               gst_element_release_request_pad (player->priv->adder, stream->adder_pad);
-               stream->adder_pad = NULL;
-
-               /* this error message kind of sucks */
-               rb_debug ("linking stream pad to adder pad failed: %d", plr);
-               g_set_error (error,
-                            RB_PLAYER_ERROR,
-                            RB_PLAYER_ERROR_GENERAL,
-                            _("Failed to link new stream into GStreamer pipeline"));
-               return FALSE;
-               g_mutex_unlock (&stream->lock);
-       }
-
-       g_atomic_int_inc (&player->priv->linked_streams);
-       rb_debug ("now have %d linked streams", player->priv->linked_streams);
+               rb_debug ("linking stream %s", stream->uri);
+               if (GST_ELEMENT_PARENT (GST_ELEMENT (stream)) == NULL)
+                       gst_bin_add (GST_BIN (player->priv->pipeline), GST_ELEMENT (stream));
+
+               stream->adder_pad = gst_element_get_request_pad (player->priv->adder, "sink_%u");
+               if (stream->adder_pad == NULL) {
+                       /* this error message kind of sucks */
+                       rb_debug ("couldn't get adder pad to link in new stream");
+                       g_set_error (error,
+                                    RB_PLAYER_ERROR,
+                                    RB_PLAYER_ERROR_GENERAL,
+                                    _("Failed to link new stream into GStreamer pipeline"));
+                       g_mutex_unlock (&stream->lock);
+                       return FALSE;
+               }
 
-       result = TRUE;
-       if (stream->src_blocked) {
-               GstStateChangeReturn state_ret;
+               plr = gst_pad_link (stream->ghost_pad, stream->adder_pad);
+               if (GST_PAD_LINK_FAILED (plr)) {
+                       gst_element_release_request_pad (player->priv->adder, stream->adder_pad);
+                       stream->adder_pad = NULL;
 
-               if (stream->block_probe_id != 0) {
-                       gst_pad_remove_probe (stream->src_pad, stream->block_probe_id);
-                       stream->block_probe_id = 0;
+                       /* this error message kind of sucks */
+                       rb_debug ("linking stream pad to adder pad failed: %d", plr);
+                       g_set_error (error,
+                                    RB_PLAYER_ERROR,
+                                    RB_PLAYER_ERROR_GENERAL,
+                                    _("Failed to link new stream into GStreamer pipeline"));
+                       return FALSE;
+                       g_mutex_unlock (&stream->lock);
                }
 
-               rb_debug ("stream %s is unblocked -> FADING_IN | PLAYING", stream->uri);
-               stream->src_blocked = FALSE;
-               if (stream->fading)
-                       stream->state = FADING_IN;
-               else
-                       stream->state = PLAYING;
-               
-               adjust_stream_base_time (stream);
+               g_atomic_int_inc (&player->priv->linked_streams);
+               rb_debug ("now have %d linked streams", player->priv->linked_streams);
+       } else {
+               rb_debug ("stream %s is already linked", stream->uri);
+       }
 
-               /* should handle state change failures here.. */
-               state_ret = gst_element_set_state (GST_ELEMENT (stream), GST_STATE_PLAYING);
-               rb_debug ("stream %s state change returned: %s", stream->uri,
-                         gst_element_state_change_return_get_name (state_ret));
+       result = TRUE;
+       if (stream->block_probe_id != 0) {
+               gst_pad_remove_probe (stream->src_pad, stream->block_probe_id);
+               stream->block_probe_id = 0;
+       }
 
-               post_stream_playing_message (stream, FALSE);
-       } else {
-               rb_debug ("??? stream %s is already unblocked -> PLAYING", stream->uri);
+       rb_debug ("stream %s is unblocked -> FADING_IN | PLAYING", stream->uri);
+       stream->src_blocked = FALSE;
+       if (stream->fading)
+               stream->state = FADING_IN;
+       else
                stream->state = PLAYING;
-               adjust_stream_base_time (stream);
 
-               scr = gst_element_set_state (GST_ELEMENT (stream), GST_STATE_PLAYING);
-
-               post_stream_playing_message (stream, FALSE);
+       stream->base_time = GST_CLOCK_TIME_NONE;
+       adjust_stream_base_time (stream);
 
-               if (scr == GST_STATE_CHANGE_FAILURE) {
-                       g_set_error (error,
-                                    RB_PLAYER_ERROR,
-                                    RB_PLAYER_ERROR_GENERAL,
-                                    _("Failed to start new stream"));
-                       result = FALSE;
-               }
+       /* should handle state change failures here.. */
+       scr = gst_element_set_state (GST_ELEMENT (stream), GST_STATE_PLAYING);
+       rb_debug ("stream %s state change returned: %s", stream->uri,
+                 gst_element_state_change_return_get_name (scr));
+       if (scr == GST_STATE_CHANGE_FAILURE) {
+               g_set_error (error,
+                            RB_PLAYER_ERROR,
+                            RB_PLAYER_ERROR_GENERAL,
+                            _("Failed to start new stream"));
+               result = FALSE;
        }
+
+       post_stream_playing_message (stream, FALSE);
        g_mutex_unlock (&stream->lock);
        return result;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]