glvideomixer: Add crop-{left,right,top,bottom} pad properties for cropping inputs

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2669>
This commit is contained in:
Sebastian Dröge 2022-06-27 21:28:07 +03:00
parent 30c8dbe032
commit 3a252f3d87
2 changed files with 241 additions and 18 deletions

View file

@ -7550,6 +7550,62 @@
"type": "GstGLVideoMixerBlendFunction",
"writable": true
},
"crop-bottom": {
"blurb": "Crop bottom of the picture",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": true,
"default": "0",
"max": "2147483647",
"min": "0",
"mutable": "null",
"readable": true,
"type": "gint",
"writable": true
},
"crop-left": {
"blurb": "Crop left of the picture",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": true,
"default": "0",
"max": "2147483647",
"min": "0",
"mutable": "null",
"readable": true,
"type": "gint",
"writable": true
},
"crop-right": {
"blurb": "Crop right of the picture",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": true,
"default": "0",
"max": "2147483647",
"min": "0",
"mutable": "null",
"readable": true,
"type": "gint",
"writable": true
},
"crop-top": {
"blurb": "Crop top of the picture",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": true,
"default": "0",
"max": "2147483647",
"min": "0",
"mutable": "null",
"readable": true,
"type": "gint",
"writable": true
},
"height": {
"blurb": "Height of the picture",
"conditionally-available": false,

View file

@ -166,6 +166,7 @@ gst_gl_video_mixer_blend_function_get_type (void)
#define DEFAULT_PAD_BLEND_FUNCTION_SRC_ALPHA GST_GL_VIDEO_MIXER_BLEND_FUNCTION_ONE
#define DEFAULT_PAD_BLEND_FUNCTION_DST_RGB GST_GL_VIDEO_MIXER_BLEND_FUNCTION_ONE_MINUS_SRC_ALPHA
#define DEFAULT_PAD_BLEND_FUNCTION_DST_ALPHA GST_GL_VIDEO_MIXER_BLEND_FUNCTION_ONE_MINUS_SRC_ALPHA
#define DEFAULT_PAD_CROP 0
enum
{
@ -187,6 +188,10 @@ enum
PROP_INPUT_BLEND_FUNCTION_CONSTANT_COLOR_ALPHA,
PROP_INPUT_ZORDER,
PROP_INPUT_REPEAT_AFTER_EOS,
PROP_INPUT_CROP_LEFT,
PROP_INPUT_CROP_RIGHT,
PROP_INPUT_CROP_TOP,
PROP_INPUT_CROP_BOTTOM,
};
static void gst_gl_video_mixer_input_get_property (GObject * object,
@ -319,6 +324,54 @@ gst_gl_video_mixer_input_class_init (GstGLVideoMixerInputClass * klass)
"Blend Constant Color Alpha", "Blend Constant Color Alpha", 0.0, 1.0,
0.0,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
/**
* GstGLVideoMixerInput:crop-left:
*
* Defines how many pixels of the input in input size should be cropped on
* the left side.
*
* Since: 1.22
*/
g_object_class_install_property (gobject_class, PROP_INPUT_CROP_LEFT,
g_param_spec_int ("crop-left", "Crop Left", "Crop left of the picture", 0,
G_MAXINT, DEFAULT_PAD_CROP,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
/**
* GstGLVideoMixerInput:crop-right:
*
* Defines how many pixels of the input in input size should be cropped on
* the right side.
*
* Since: 1.22
*/
g_object_class_install_property (gobject_class, PROP_INPUT_CROP_RIGHT,
g_param_spec_int ("crop-right", "Crop Right", "Crop right of the picture",
0, G_MAXINT, DEFAULT_PAD_CROP,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
/**
* GstGLVideoMixerInput:crop-top:
*
* Defines how many pixels of the input in input size should be cropped on
* the top side.
*
* Since: 1.22
*/
g_object_class_install_property (gobject_class, PROP_INPUT_CROP_TOP,
g_param_spec_int ("crop-top", "Crop Top", "Crop top of the picture", 0,
G_MAXINT, DEFAULT_PAD_CROP,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
/**
* GstGLVideoMixerInput:crop-bottom:
*
* Defines how many pixels of the input in input size should be cropped on
* the bottom side.
*
* Since: 1.22
*/
g_object_class_install_property (gobject_class, PROP_INPUT_CROP_BOTTOM,
g_param_spec_int ("crop-bottom", "Crop Bottom",
"Crop bottom of the picture", 0, G_MAXINT, DEFAULT_PAD_CROP,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
}
static void
@ -567,6 +620,9 @@ struct _GstGLVideoMixerPad
gdouble blend_constant_color_blue;
gdouble blend_constant_color_alpha;
gint crop_left, crop_right;
gint crop_top, crop_bottom;
gboolean geometry_change;
GLuint vertex_buffer;
gfloat m_matrix[16];
@ -604,6 +660,10 @@ enum
PROP_PAD_BLEND_FUNCTION_CONSTANT_COLOR_GREEN,
PROP_PAD_BLEND_FUNCTION_CONSTANT_COLOR_BLUE,
PROP_PAD_BLEND_FUNCTION_CONSTANT_COLOR_ALPHA,
PROP_PAD_CROP_LEFT,
PROP_PAD_CROP_RIGHT,
PROP_PAD_CROP_TOP,
PROP_PAD_CROP_BOTTOM,
};
static void
@ -716,6 +776,54 @@ gst_gl_video_mixer_pad_class_init (GstGLVideoMixerPadClass * klass)
"Blend Constant Color Alpha", "Blend Constant Color Alpha", 0.0, 1.0,
0.0,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
/**
* GstGLVideoMixerPad:crop-left:
*
* Defines how many pixels of the input in input size should be cropped on
* the left side.
*
* Since: 1.22
*/
g_object_class_install_property (gobject_class, PROP_PAD_CROP_LEFT,
g_param_spec_int ("crop-left", "Crop Left", "Crop left of the picture", 0,
G_MAXINT, DEFAULT_PAD_CROP,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
/**
* GstGLVideoMixerPad:crop-right:
*
* Defines how many pixels of the input in input size should be cropped on
* the right side.
*
* Since: 1.22
*/
g_object_class_install_property (gobject_class, PROP_PAD_CROP_RIGHT,
g_param_spec_int ("crop-right", "Crop Right", "Crop right of the picture",
0, G_MAXINT, DEFAULT_PAD_CROP,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
/**
* GstGLVideoMixerPad:crop-top:
*
* Defines how many pixels of the input in input size should be cropped on
* the top side.
*
* Since: 1.22
*/
g_object_class_install_property (gobject_class, PROP_PAD_CROP_TOP,
g_param_spec_int ("crop-top", "Crop Top", "Crop top of the picture", 0,
G_MAXINT, DEFAULT_PAD_CROP,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
/**
* GstGLVideoMixerPad:crop-bottom:
*
* Defines how many pixels of the input in input size should be cropped on
* the bottom side.
*
* Since: 1.22
*/
g_object_class_install_property (gobject_class, PROP_PAD_CROP_BOTTOM,
g_param_spec_int ("crop-bottom", "Crop Bottom",
"Crop bottom of the picture", 0, G_MAXINT, DEFAULT_PAD_CROP,
G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE | G_PARAM_STATIC_STRINGS));
}
static void
@ -770,6 +878,18 @@ gst_gl_video_mixer_pad_get_property (GObject * object, guint prop_id,
case PROP_PAD_BLEND_FUNCTION_CONSTANT_COLOR_ALPHA:
g_value_set_double (value, pad->blend_constant_color_alpha);
break;
case PROP_PAD_CROP_LEFT:
g_value_set_int (value, pad->crop_left);
break;
case PROP_PAD_CROP_RIGHT:
g_value_set_int (value, pad->crop_right);
break;
case PROP_PAD_CROP_TOP:
g_value_set_int (value, pad->crop_top);
break;
case PROP_PAD_CROP_BOTTOM:
g_value_set_int (value, pad->crop_bottom);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -833,6 +953,22 @@ gst_gl_video_mixer_pad_set_property (GObject * object, guint prop_id,
case PROP_PAD_BLEND_FUNCTION_CONSTANT_COLOR_ALPHA:
pad->blend_constant_color_alpha = g_value_get_double (value);
break;
case PROP_PAD_CROP_LEFT:
pad->crop_left = g_value_get_int (value);
pad->geometry_change = TRUE;
break;
case PROP_PAD_CROP_RIGHT:
pad->crop_right = g_value_get_int (value);
pad->geometry_change = TRUE;
break;
case PROP_PAD_CROP_TOP:
pad->crop_top = g_value_get_int (value);
pad->geometry_change = TRUE;
break;
case PROP_PAD_CROP_BOTTOM:
pad->crop_bottom = g_value_get_int (value);
pad->geometry_change = TRUE;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -1019,12 +1155,27 @@ _mixer_pad_get_output_size (GstGLVideoMixer * mix,
return;
}
pad_width =
mix_pad->width <=
0 ? GST_VIDEO_INFO_WIDTH (&vagg_pad->info) : mix_pad->width;
pad_height =
mix_pad->height <=
0 ? GST_VIDEO_INFO_HEIGHT (&vagg_pad->info) : mix_pad->height;
if (mix_pad->width <= 0) {
gint crop = mix_pad->crop_left + mix_pad->crop_right;
if (GST_VIDEO_INFO_WIDTH (&vagg_pad->info) > crop)
pad_width = GST_VIDEO_INFO_WIDTH (&vagg_pad->info) - crop;
else
pad_width = 0;
} else {
pad_width = mix_pad->width;
}
if (mix_pad->height <= 0) {
gint crop = mix_pad->crop_top + mix_pad->crop_bottom;
if (GST_VIDEO_INFO_HEIGHT (&vagg_pad->info) > crop)
pad_height = GST_VIDEO_INFO_HEIGHT (&vagg_pad->info) - crop;
else
pad_height = 0;
} else {
pad_height = mix_pad->height;
}
if (!gst_video_calculate_display_ratio (&dar_n, &dar_d, pad_width, pad_height,
GST_VIDEO_INFO_PAR_N (&vagg_pad->info),
@ -1624,15 +1775,6 @@ gst_gl_video_mixer_callback (gpointer stuff)
guint in_tex;
guint in_width, in_height;
/* *INDENT-OFF* */
gfloat v_vertices[] = {
-1.0,-1.0, 0.0f, 0.0f, 0.0f,
1.0,-1.0, 0.0f, 1.0f, 0.0f,
1.0, 1.0, 0.0f, 1.0f, 1.0f,
-1.0, 1.0, 0.0f, 0.0f, 1.0f,
};
/* *INDENT-ON* */
v_info = &GST_VIDEO_AGGREGATOR_PAD (pad)->info;
in_width = GST_VIDEO_INFO_WIDTH (v_info);
in_height = GST_VIDEO_INFO_HEIGHT (v_info);
@ -1659,6 +1801,14 @@ gst_gl_video_mixer_callback (gpointer stuff)
|| pad->geometry_change || !pad->vertex_buffer) {
gint pad_width, pad_height;
gfloat w, h;
/* *INDENT-OFF* */
gfloat v_vertices[] = {
-1.0,-1.0, 0.0f, 0.0f, 0.0f,
1.0,-1.0, 0.0f, 1.0f, 0.0f,
1.0, 1.0, 0.0f, 1.0f, 1.0f,
-1.0, 1.0, 0.0f, 0.0f, 1.0f,
};
/* *INDENT-ON* */
_mixer_pad_get_output_size (video_mixer, pad,
GST_VIDEO_INFO_PAR_N (&vagg->info),
@ -1674,9 +1824,26 @@ gst_gl_video_mixer_callback (gpointer stuff)
pad->m_matrix[13] =
2. * (gfloat) pad->ypos / (gfloat) out_height - (1. - h);
GST_TRACE ("processing texture:%u dimensions:%ux%u, at %f,%f %fx%f with "
"alpha:%f", in_tex, in_width, in_height, pad->m_matrix[12],
pad->m_matrix[13], pad->m_matrix[0], pad->m_matrix[5], pad->alpha);
v_vertices[0 * 5 + 3] = v_vertices[3 * 5 + 3] =
pad->crop_left ? ((gfloat) pad->crop_left) /
((gfloat) in_width) : 0.0f;
v_vertices[1 * 5 + 3] = v_vertices[2 * 5 + 3] =
pad->crop_right ? 1.0 -
((gfloat) pad->crop_right) / ((gfloat) in_width) : 1.0f;
v_vertices[0 * 5 + 4] = v_vertices[1 * 5 + 4] =
pad->crop_top ? ((gfloat) pad->crop_top) /
((gfloat) in_height) : 0.0f;
v_vertices[2 * 5 + 4] = v_vertices[3 * 5 + 4] =
pad->crop_bottom ? 1.0 -
((gfloat) pad->crop_bottom) / ((gfloat) in_height) : 1.0f;
GST_TRACE ("processing texture:%u dimensions:%ux%u with texture "
"coordinates %f:%fx%f:%f, at %f,%f %fx%f with alpha:%f "
"and crop: %d:%dx%d:%d", in_tex, in_width, in_height,
v_vertices[0 * 5 + 3], v_vertices[1 * 5 + 3], v_vertices[0 * 5 + 4],
v_vertices[1 * 5 + 4], pad->m_matrix[12], pad->m_matrix[13],
pad->m_matrix[0], pad->m_matrix[5], pad->alpha, pad->crop_left,
pad->crop_right, pad->crop_top, pad->crop_bottom);
if (!pad->vertex_buffer)
gl->GenBuffers (1, &pad->vertex_buffer);