audio/video aggregator: make use of new aggregator inactive pad API

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/867>
This commit is contained in:
Mathieu Duponchelle 2021-08-15 01:36:14 +02:00 committed by GStreamer Marge Bot
parent f829ed3313
commit c3d878e990
4 changed files with 93 additions and 0 deletions

View file

@ -1875,6 +1875,18 @@
"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,

View 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);

View 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);

View 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);