playbin3: Configure combiner on pad-added if needed
authorSeungha Yang <seungha@centricular.com>
Tue, 24 May 2022 17:10:30 +0000 (02:10 +0900)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 25 May 2022 13:50:17 +0000 (13:50 +0000)
When collection is updated, decodebin3 exposes pad first and then
streams-selected message is posted.
The condition can cause a situation where playbin3 links non-existing
combiner/playsink pads (since streams-selected is not posted yet) with
new decodebin output pad. This commit will re-check selected/active
streams condition on pad-added and reconfigure output if needed.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2482>

subprojects/gst-plugins-base/gst/playback/gstplaybin3.c

index b727d16..1072705 100644 (file)
@@ -3021,6 +3021,7 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstSourceGroup * group)
   gchar *pad_name;
   GstPlayBin3 *playbin = group->playbin;
   GstPad *combine_pad;
+  GstStreamType selected, active, cur;
 
   GST_PLAY_BIN3_SHUTDOWN_LOCK (playbin, shutdown);
 
@@ -3033,10 +3034,13 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstSourceGroup * group)
      try exact match first */
   if (g_str_has_prefix (pad_name, "video")) {
     pb_stream_type = PLAYBIN_STREAM_VIDEO;
+    cur = GST_STREAM_TYPE_VIDEO;
   } else if (g_str_has_prefix (pad_name, "audio")) {
     pb_stream_type = PLAYBIN_STREAM_AUDIO;
+    cur = GST_STREAM_TYPE_AUDIO;
   } else if (g_str_has_prefix (pad_name, "text")) {
     pb_stream_type = PLAYBIN_STREAM_TEXT;
+    cur = GST_STREAM_TYPE_TEXT;
   }
 
   g_free (pad_name);
@@ -3051,6 +3055,30 @@ pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstSourceGroup * group)
   GST_PLAY_BIN3_LOCK (playbin);
   combine = &playbin->combiner[pb_stream_type];
 
+  /* (uri)decodebin3 will post streams-selected once all pads are expose.
+   * Therefore this stream might not be marked as selected on pad-added,
+   * and associated combiner can be null here.
+   * Marks this stream as selected manually, exposed pad implies it's selected
+   * already */
+  selected = playbin->selected_stream_types | cur;
+  active = playbin->active_stream_types;
+
+  if (selected != active) {
+    GST_DEBUG_OBJECT (playbin,
+        "%s:%s added but not an active stream, marking active",
+        GST_DEBUG_PAD_NAME (pad));
+    playbin->selected_stream_types = selected;
+    reconfigure_output (playbin);
+
+    /* shutdown state can be changed meantime then combiner will not be
+     * configured */
+    if (g_atomic_int_get (&playbin->shutdown)) {
+      GST_PLAY_BIN3_UNLOCK (playbin);
+      GST_PLAY_BIN3_SHUTDOWN_UNLOCK (playbin);
+      return;
+    }
+  }
+
   combine_pad = combiner_control_pad (playbin, combine, pad);
 
   control_source_pad (group, pad, combine_pad, combine->stream_type);