Skip to content

Commit

Permalink
compositor: expose zero-size-is-unscaled property
Browse files Browse the repository at this point in the history
When that property is left to its default, the width and height
property considers frames from input pads with width or height <= 0
should be left unscaled in that dimension.

Setting this property to FALSE changes that behaviour to < 0, as when
animating these properties, 0 should be a valid end value (eg. shrinking
an input stream until it disappears).

The default value of the width and height properties is set to -1, so that
the default behaviour stays consistent whether that new property is set
or not.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/923>
  • Loading branch information
MathieuDuponchelle authored and GStreamer Merge Bot committed Nov 13, 2020
1 parent c50f447 commit fe20cac
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 19 deletions.
16 changes: 14 additions & 2 deletions docs/plugins/gst_plugins_cache.json
Expand Up @@ -1790,6 +1790,18 @@
"readable": true,
"type": "GstCompositorBackground",
"writable": true
},
"zero-size-is-unscaled": {
"blurb": "If TRUE, then input video is unscaled in that dimension if width or height is 0 (for backwards compatibility)",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "true",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
}
},
"rank": "primary + 1"
Expand Down Expand Up @@ -1876,7 +1888,7 @@
"construct": false,
"construct-only": false,
"controllable": true,
"default": "0",
"default": "-1",
"max": "2147483647",
"min": "-2147483648",
"mutable": "null",
Expand All @@ -1902,7 +1914,7 @@
"construct": false,
"construct-only": false,
"controllable": true,
"default": "0",
"default": "-1",
"max": "2147483647",
"min": "-2147483648",
"mutable": "null",
Expand Down
80 changes: 63 additions & 17 deletions gst/compositor/compositor.c
Expand Up @@ -167,8 +167,8 @@ gst_compositor_background_get_type (void)

#define DEFAULT_PAD_XPOS 0
#define DEFAULT_PAD_YPOS 0
#define DEFAULT_PAD_WIDTH 0
#define DEFAULT_PAD_HEIGHT 0
#define DEFAULT_PAD_WIDTH -1
#define DEFAULT_PAD_HEIGHT -1
#define DEFAULT_PAD_ALPHA 1.0
#define DEFAULT_PAD_OPERATOR COMPOSITOR_OPERATOR_OVER
enum
Expand Down Expand Up @@ -254,8 +254,8 @@ gst_compositor_pad_set_property (GObject * object, guint prop_id,
}

static void
_mixer_pad_get_output_size (GstCompositorPad * comp_pad, gint out_par_n,
gint out_par_d, gint * width, gint * height)
_mixer_pad_get_output_size (GstCompositor * comp, GstCompositorPad * comp_pad,
gint out_par_n, gint out_par_d, gint * width, gint * height)
{
GstVideoAggregatorPad *vagg_pad = GST_VIDEO_AGGREGATOR_PAD (comp_pad);
gint pad_width, pad_height;
Expand All @@ -270,12 +270,27 @@ _mixer_pad_get_output_size (GstCompositorPad * comp_pad, gint out_par_n,
return;
}

pad_width =
comp_pad->width <=
0 ? GST_VIDEO_INFO_WIDTH (&vagg_pad->info) : comp_pad->width;
pad_height =
comp_pad->height <=
0 ? GST_VIDEO_INFO_HEIGHT (&vagg_pad->info) : comp_pad->height;
if (comp->zero_size_is_unscaled) {
pad_width =
comp_pad->width <=
0 ? GST_VIDEO_INFO_WIDTH (&vagg_pad->info) : comp_pad->width;
pad_height =
comp_pad->height <=
0 ? GST_VIDEO_INFO_HEIGHT (&vagg_pad->info) : comp_pad->height;
} else {
pad_width =
comp_pad->width <
0 ? GST_VIDEO_INFO_WIDTH (&vagg_pad->info) : comp_pad->width;
pad_height =
comp_pad->height <
0 ? GST_VIDEO_INFO_HEIGHT (&vagg_pad->info) : comp_pad->height;
}

if (pad_width == 0 || pad_height == 0) {
*width = 0;
*height = 0;
return;
}

if (!gst_video_calculate_display_ratio (&dar_n, &dar_d, pad_width, pad_height,
GST_VIDEO_INFO_PAR_N (&vagg_pad->info),
Expand Down Expand Up @@ -357,8 +372,9 @@ _pad_obscures_rectangle (GstVideoAggregator * vagg, GstVideoAggregatorPad * pad,
pad_rect.x = cpad->xpos;
pad_rect.y = cpad->ypos;
/* Handle pixel and display aspect ratios to find the actual size */
_mixer_pad_get_output_size (cpad, GST_VIDEO_INFO_PAR_N (&vagg->info),
GST_VIDEO_INFO_PAR_D (&vagg->info), &(pad_rect.w), &(pad_rect.h));
_mixer_pad_get_output_size (GST_COMPOSITOR (vagg), cpad,
GST_VIDEO_INFO_PAR_N (&vagg->info), GST_VIDEO_INFO_PAR_D (&vagg->info),
&(pad_rect.w), &(pad_rect.h));

if (!is_rectangle_contained (rect, pad_rect))
return FALSE;
Expand Down Expand Up @@ -395,8 +411,9 @@ gst_compositor_pad_prepare_frame (GstVideoAggregatorPad * pad,
* width/height. See ->set_info()
* */

_mixer_pad_get_output_size (cpad, GST_VIDEO_INFO_PAR_N (&vagg->info),
GST_VIDEO_INFO_PAR_D (&vagg->info), &width, &height);
_mixer_pad_get_output_size (GST_COMPOSITOR (vagg), cpad,
GST_VIDEO_INFO_PAR_N (&vagg->info), GST_VIDEO_INFO_PAR_D (&vagg->info),
&width, &height);

if (cpad->alpha == 0.0) {
GST_DEBUG_OBJECT (pad, "Pad has alpha 0.0, not converting frame");
Expand Down Expand Up @@ -451,8 +468,9 @@ gst_compositor_pad_create_conversion_info (GstVideoAggregatorConvertPad * pad,
if (!conversion_info->finfo)
return;

_mixer_pad_get_output_size (cpad, GST_VIDEO_INFO_PAR_N (&vagg->info),
GST_VIDEO_INFO_PAR_D (&vagg->info), &width, &height);
_mixer_pad_get_output_size (GST_COMPOSITOR (vagg), cpad,
GST_VIDEO_INFO_PAR_N (&vagg->info), GST_VIDEO_INFO_PAR_D (&vagg->info),
&width, &height);

/* The only thing that can change here is the width
* and height, otherwise set_info would've been called */
Expand Down Expand Up @@ -532,15 +550,19 @@ gst_compositor_pad_init (GstCompositorPad * compo_pad)
compo_pad->ypos = DEFAULT_PAD_YPOS;
compo_pad->alpha = DEFAULT_PAD_ALPHA;
compo_pad->op = DEFAULT_PAD_OPERATOR;
compo_pad->width = DEFAULT_PAD_WIDTH;
compo_pad->height = DEFAULT_PAD_HEIGHT;
}


/* GstCompositor */
#define DEFAULT_BACKGROUND COMPOSITOR_BACKGROUND_CHECKER
#define DEFAULT_ZERO_SIZE_IS_UNSCALED TRUE
enum
{
PROP_0,
PROP_BACKGROUND,
PROP_ZERO_SIZE_IS_UNSCALED,
};

static void
Expand All @@ -553,6 +575,9 @@ gst_compositor_get_property (GObject * object,
case PROP_BACKGROUND:
g_value_set_enum (value, self->background);
break;
case PROP_ZERO_SIZE_IS_UNSCALED:
g_value_set_boolean (value, self->zero_size_is_unscaled);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
Expand All @@ -569,6 +594,9 @@ gst_compositor_set_property (GObject * object,
case PROP_BACKGROUND:
self->background = g_value_get_enum (value);
break;
case PROP_ZERO_SIZE_IS_UNSCALED:
self->zero_size_is_unscaled = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
Expand Down Expand Up @@ -786,7 +814,8 @@ _fixate_caps (GstAggregator * agg, GstCaps * caps)

fps_n = GST_VIDEO_INFO_FPS_N (&vaggpad->info);
fps_d = GST_VIDEO_INFO_FPS_D (&vaggpad->info);
_mixer_pad_get_output_size (compositor_pad, par_n, par_d, &width, &height);
_mixer_pad_get_output_size (GST_COMPOSITOR (vagg), compositor_pad, par_n,
par_d, &width, &height);

if (width == 0 || height == 0)
continue;
Expand Down Expand Up @@ -1374,6 +1403,22 @@ gst_compositor_class_init (GstCompositorClass * klass)
GST_TYPE_COMPOSITOR_BACKGROUND,
DEFAULT_BACKGROUND, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

/**
* compositor:zero-size-is-unscaled:
*
* Whether a pad with height or width 0 should be left unscaled
* in that dimension, or simply not composited in. Setting it to
* %FALSE might be useful when animating those properties.
*
* Since: 1.20
*/
g_object_class_install_property (gobject_class, PROP_ZERO_SIZE_IS_UNSCALED,
g_param_spec_boolean ("zero-size-is-unscaled", "Zero size is unscaled",
"If TRUE, then input video is unscaled in that dimension "
"if width or height is 0 (for backwards compatibility)",
DEFAULT_ZERO_SIZE_IS_UNSCALED,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
&src_factory, GST_TYPE_AGGREGATOR_PAD);
gst_element_class_add_static_pad_template_with_gtype (gstelement_class,
Expand All @@ -1394,6 +1439,7 @@ gst_compositor_init (GstCompositor * self)
{
/* initialize variables */
self->background = DEFAULT_BACKGROUND;
self->zero_size_is_unscaled = DEFAULT_ZERO_SIZE_IS_UNSCALED;
}

/* GstChildProxy implementation */
Expand Down
8 changes: 8 additions & 0 deletions gst/compositor/compositor.h
Expand Up @@ -114,6 +114,14 @@ struct _GstCompositor
GstVideoAggregator videoaggregator;
GstCompositorBackground background;

/* Property to allow overriding the default behaviour of
* pad.width == 0 or pad.height == 0: by default it means the input
* image should be left unscaled in that dimension, but it may be desirable
* to have it simply mean the image should not be composited into the output
* image, for example when animating the property.
*/
gboolean zero_size_is_unscaled;

/* The 'blend' compositing function does not preserve the alpha value of the
* background, while 'overlay' does; i.e., COMPOSITOR_OPERATOR_ADD is the
* same as COMPOSITOR_OPERATOR_OVER when using the 'blend' BlendFunction. */
Expand Down

0 comments on commit fe20cac

Please sign in to comment.