audio/video aggregator: make use of new aggregator inactive pad API
authorMathieu Duponchelle <mathieu@centricular.com>
Sat, 14 Aug 2021 23:36:14 +0000 (01:36 +0200)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 18 Oct 2021 22:34:11 +0000 (22:34 +0000)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/867>

subprojects/gst-plugins-base/docs/plugins/gst_plugins_cache.json
subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioaggregator.c
subprojects/gst-plugins-base/gst-libs/gst/video/gstvideoaggregator.c
subprojects/gst-plugins-base/gst/compositor/compositor.c

index 2ce8496..5f2e759 100644 (file)
                         "type": "GstCompositorBackground",
                         "writable": true
                     },
+                    "ignore-inactive-pads": {
+                        "blurb": "Avoid timing out waiting for inactive pads",
+                        "conditionally-available": false,
+                        "construct": false,
+                        "construct-only": false,
+                        "controllable": false,
+                        "default": "false",
+                        "mutable": "null",
+                        "readable": true,
+                        "type": "gboolean",
+                        "writable": true
+                    },
                     "max-threads": {
                         "blurb": "Maximum number of blending/rendering worker threads to spawn (0 = auto)",
                         "conditionally-available": false,
index f40975b..4eb91db 100644 (file)
@@ -537,6 +537,7 @@ enum
   PROP_ALIGNMENT_THRESHOLD,
   PROP_DISCONT_WAIT,
   PROP_OUTPUT_BUFFER_DURATION_FRACTION,
+  PROP_IGNORE_INACTIVE_PADS,
 };
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GstAudioAggregator, gst_audio_aggregator,
@@ -697,6 +698,27 @@ gst_audio_aggregator_class_init (GstAudioAggregatorClass * klass)
           "Window of time in nanoseconds to wait before "
           "creating a discontinuity", 0,
           G_MAXUINT64 - 1, DEFAULT_DISCONT_WAIT,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+          GST_PARAM_MUTABLE_PLAYING));
+
+  /**
+   * GstAudioAggregator:ignore-inactive-pads:
+   *
+   * Don't wait for inactive pads when live. An inactive pad
+   * is a pad that hasn't yet received a buffer, but that has
+   * been waited on at least once.
+   *
+   * The purpose of this property is to avoid aggregating on
+   * timeout when new pads are requested in advance of receiving
+   * data flow, for example the user may decide to connect it later,
+   * but wants to configure it already.
+   *
+   * Since: 1.20
+   */
+  g_object_class_install_property (gobject_class,
+      PROP_IGNORE_INACTIVE_PADS, g_param_spec_boolean ("ignore-inactive-pads",
+          "Ignore inactive pads",
+          "Avoid timing out waiting for inactive pads", FALSE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
@@ -763,6 +785,10 @@ gst_audio_aggregator_set_property (GObject * object, guint prop_id,
       g_object_notify (object, "output-buffer-duration");
       gst_audio_aggregator_recalculate_latency (aagg);
       break;
+    case PROP_IGNORE_INACTIVE_PADS:
+      gst_aggregator_set_ignore_inactive_pads (GST_AGGREGATOR (object),
+          g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -791,6 +817,10 @@ gst_audio_aggregator_get_property (GObject * object, guint prop_id,
       gst_value_set_fraction (value, aagg->priv->output_buffer_duration_n,
           aagg->priv->output_buffer_duration_d);
       break;
+    case PROP_IGNORE_INACTIVE_PADS:
+      g_value_set_boolean (value,
+          gst_aggregator_get_ignore_inactive_pads (GST_AGGREGATOR (object)));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -2271,6 +2301,9 @@ gst_audio_aggregator_aggregate (GstAggregator * agg, gboolean timeout)
     gboolean pad_eos = gst_aggregator_pad_is_eos (aggpad);
     GstBuffer *input_buffer;
 
+    if (gst_aggregator_pad_is_inactive (aggpad))
+      continue;
+
     if (!pad_eos)
       is_eos = FALSE;
 
@@ -2381,6 +2414,9 @@ gst_audio_aggregator_aggregate (GstAggregator * agg, gboolean timeout)
     GstAudioAggregatorPad *pad = (GstAudioAggregatorPad *) iter->data;
     GstAggregatorPad *aggpad = (GstAggregatorPad *) iter->data;
 
+    if (gst_aggregator_pad_is_inactive (aggpad))
+      continue;
+
     GST_OBJECT_LOCK (pad);
 
     if (pad->priv->buffer && pad->priv->output_offset >= aagg->priv->offset
@@ -2432,6 +2468,9 @@ gst_audio_aggregator_aggregate (GstAggregator * agg, gboolean timeout)
     for (iter = GST_ELEMENT (agg)->sinkpads; iter; iter = iter->next) {
       GstAudioAggregatorPad *pad = GST_AUDIO_AGGREGATOR_PAD (iter->data);
 
+      if (gst_aggregator_pad_is_inactive (GST_AGGREGATOR_PAD (pad)))
+        continue;
+
       max_offset = MAX ((gint64) max_offset, (gint64) pad->priv->output_offset);
     }
     GST_OBJECT_UNLOCK (agg);
index 6d8b1a9..cbad92d 100644 (file)
@@ -1745,6 +1745,10 @@ gst_video_aggregator_fill_queues (GstVideoAggregator * vagg,
     gboolean is_eos;
 
     bpad = GST_AGGREGATOR_PAD (pad);
+
+    if (gst_aggregator_pad_is_inactive (bpad))
+      continue;
+
     GST_OBJECT_LOCK (bpad);
     segment = bpad->segment;
     GST_OBJECT_UNLOCK (bpad);
index ca4df68..9938154 100644 (file)
@@ -544,6 +544,9 @@ gst_compositor_pad_prepare_frame_start (GstVideoAggregatorPad * pad,
     return;
   }
 
+  if (gst_aggregator_pad_is_inactive (GST_AGGREGATOR_PAD (pad)))
+    return;
+
   frame_rect = clamp_rectangle (cpad->xpos + cpad->x_offset,
       cpad->ypos + cpad->y_offset, width, height,
       GST_VIDEO_INFO_WIDTH (&vagg->info), GST_VIDEO_INFO_HEIGHT (&vagg->info));
@@ -709,6 +712,7 @@ enum
   PROP_BACKGROUND,
   PROP_ZERO_SIZE_IS_UNSCALED,
   PROP_MAX_THREADS,
+  PROP_IGNORE_INACTIVE_PADS,
 };
 
 static void
@@ -727,6 +731,10 @@ gst_compositor_get_property (GObject * object,
     case PROP_MAX_THREADS:
       g_value_set_uint (value, self->max_threads);
       break;
+    case PROP_IGNORE_INACTIVE_PADS:
+      g_value_set_boolean (value,
+          gst_aggregator_get_ignore_inactive_pads (GST_AGGREGATOR (object)));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -749,6 +757,10 @@ gst_compositor_set_property (GObject * object,
     case PROP_MAX_THREADS:
       self->max_threads = g_value_get_uint (value);
       break;
+    case PROP_IGNORE_INACTIVE_PADS:
+      gst_aggregator_set_ignore_inactive_pads (GST_AGGREGATOR (object),
+          g_value_get_boolean (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -968,6 +980,9 @@ _fixate_caps (GstAggregator * agg, GstCaps * caps)
     gint x_offset;
     gint y_offset;
 
+    if (gst_aggregator_pad_is_inactive (GST_AGGREGATOR_PAD (vaggpad)))
+      continue;
+
     fps_n = GST_VIDEO_INFO_FPS_N (&vaggpad->info);
     fps_d = GST_VIDEO_INFO_FPS_D (&vaggpad->info);
     _mixer_pad_get_output_size (GST_COMPOSITOR (vagg), compositor_pad, par_n,
@@ -1217,6 +1232,9 @@ _should_draw_background (GstVideoAggregator * vagg)
   /* Check if the background is completely obscured by a pad
    * TODO: Also skip if it's obscured by a combination of pads */
   for (l = GST_ELEMENT (vagg)->sinkpads; l; l = l->next) {
+    if (gst_aggregator_pad_is_inactive (GST_AGGREGATOR_PAD (l->data)))
+      continue;
+
     if (_pad_obscures_rectangle (vagg, l->data, bg_rect)) {
       draw = FALSE;
       break;
@@ -1611,6 +1629,26 @@ gst_compositor_class_init (GstCompositorClass * klass)
       "Composite multiple video streams", "Wim Taymans <wim@fluendo.com>, "
       "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
 
+  /**
+   * compositor:ignore-inactive-pads:
+   *
+   * Don't wait for inactive pads when live. An inactive pad
+   * is a pad that hasn't yet received a buffer, but that has
+   * been waited on at least once.
+   *
+   * The purpose of this property is to avoid aggregating on
+   * timeout when new pads are requested in advance of receiving
+   * data flow, for example the user may decide to connect it later,
+   * but wants to configure it already.
+   *
+   * Since: 1.20
+   */
+  g_object_class_install_property (gobject_class,
+      PROP_IGNORE_INACTIVE_PADS, g_param_spec_boolean ("ignore-inactive-pads",
+          "Ignore inactive pads",
+          "Avoid timing out waiting for inactive pads", FALSE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gst_type_mark_as_plugin_api (GST_TYPE_COMPOSITOR_PAD, 0);
   gst_type_mark_as_plugin_api (GST_TYPE_COMPOSITOR_OPERATOR, 0);
   gst_type_mark_as_plugin_api (GST_TYPE_COMPOSITOR_BACKGROUND, 0);