mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 20:42:30 +00:00
videobox: Properly handle ranges/lists of width or height when transforming caps
Code partly taken from the videocrop element.
This commit is contained in:
parent
f71157fa06
commit
a105bf49e3
1 changed files with 101 additions and 27 deletions
|
@ -2181,6 +2181,66 @@ gst_video_box_get_property (GObject * object, guint prop_id, GValue * value,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline gint
|
||||||
|
gst_video_box_transform_dimension (gint val, gint delta)
|
||||||
|
{
|
||||||
|
gint64 new_val = (gint64) val + (gint64) delta;
|
||||||
|
|
||||||
|
new_val = CLAMP (new_val, 1, G_MAXINT);
|
||||||
|
|
||||||
|
return (gint) new_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_video_box_transform_dimension_value (const GValue * src_val,
|
||||||
|
gint delta, GValue * dest_val)
|
||||||
|
{
|
||||||
|
gboolean ret = TRUE;
|
||||||
|
|
||||||
|
g_value_init (dest_val, G_VALUE_TYPE (src_val));
|
||||||
|
|
||||||
|
if (G_VALUE_HOLDS_INT (src_val)) {
|
||||||
|
gint ival = g_value_get_int (src_val);
|
||||||
|
|
||||||
|
ival = gst_video_box_transform_dimension (ival, delta);
|
||||||
|
g_value_set_int (dest_val, ival);
|
||||||
|
} else if (GST_VALUE_HOLDS_INT_RANGE (src_val)) {
|
||||||
|
gint min = gst_value_get_int_range_min (src_val);
|
||||||
|
gint max = gst_value_get_int_range_max (src_val);
|
||||||
|
|
||||||
|
min = gst_video_box_transform_dimension (min, delta);
|
||||||
|
max = gst_video_box_transform_dimension (max, delta);
|
||||||
|
if (min > max) {
|
||||||
|
ret = FALSE;
|
||||||
|
g_value_unset (dest_val);
|
||||||
|
} else {
|
||||||
|
gst_value_set_int_range (dest_val, min, max);
|
||||||
|
}
|
||||||
|
} else if (GST_VALUE_HOLDS_LIST (src_val)) {
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
for (i = 0; i < gst_value_list_get_size (src_val); ++i) {
|
||||||
|
const GValue *list_val;
|
||||||
|
GValue newval = { 0, };
|
||||||
|
|
||||||
|
list_val = gst_value_list_get_value (src_val, i);
|
||||||
|
if (gst_video_box_transform_dimension_value (list_val, delta, &newval))
|
||||||
|
gst_value_list_append_value (dest_val, &newval);
|
||||||
|
g_value_unset (&newval);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_value_list_get_size (dest_val) == 0) {
|
||||||
|
g_value_unset (dest_val);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
g_value_unset (dest_val);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
gst_video_box_transform_caps (GstBaseTransform * trans,
|
gst_video_box_transform_caps (GstBaseTransform * trans,
|
||||||
GstPadDirection direction, GstCaps * from)
|
GstPadDirection direction, GstCaps * from)
|
||||||
|
@ -2191,7 +2251,6 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
|
||||||
const gchar *name;
|
const gchar *name;
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
GstPad *other;
|
GstPad *other;
|
||||||
gint width, height;
|
|
||||||
|
|
||||||
to = gst_caps_copy (from);
|
to = gst_caps_copy (from);
|
||||||
/* Just to be sure... */
|
/* Just to be sure... */
|
||||||
|
@ -2203,37 +2262,52 @@ gst_video_box_transform_caps (GstBaseTransform * trans,
|
||||||
gst_structure_remove_field (structure, "width");
|
gst_structure_remove_field (structure, "width");
|
||||||
gst_structure_remove_field (structure, "height");
|
gst_structure_remove_field (structure, "height");
|
||||||
} else {
|
} else {
|
||||||
|
gint dw = 0, dh = 0;
|
||||||
|
const GValue *v;
|
||||||
|
GValue w_val = { 0, };
|
||||||
|
GValue h_val = { 0, };
|
||||||
|
|
||||||
/* calculate width and height */
|
/* calculate width and height */
|
||||||
if (gst_structure_get_int (structure, "width", &width)) {
|
if (direction == GST_PAD_SINK) {
|
||||||
if (direction == GST_PAD_SINK) {
|
dw -= video_box->box_left;
|
||||||
width -= video_box->box_left;
|
dw -= video_box->box_right;
|
||||||
width -= video_box->box_right;
|
} else {
|
||||||
} else {
|
dw += video_box->box_left;
|
||||||
width += video_box->box_left;
|
dw += video_box->box_right;
|
||||||
width += video_box->box_right;
|
|
||||||
}
|
|
||||||
if (width <= 0)
|
|
||||||
width = 1;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (trans, "New caps width: %d", width);
|
|
||||||
gst_structure_set (structure, "width", G_TYPE_INT, width, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gst_structure_get_int (structure, "height", &height)) {
|
|
||||||
if (direction == GST_PAD_SINK) {
|
|
||||||
height -= video_box->box_top;
|
|
||||||
height -= video_box->box_bottom;
|
|
||||||
} else {
|
|
||||||
height += video_box->box_top;
|
|
||||||
height += video_box->box_bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (height <= 0)
|
if (direction == GST_PAD_SINK) {
|
||||||
height = 1;
|
dh -= video_box->box_top;
|
||||||
|
dh -= video_box->box_bottom;
|
||||||
GST_DEBUG_OBJECT (trans, "New caps height: %d", height);
|
} else {
|
||||||
gst_structure_set (structure, "height", G_TYPE_INT, height, NULL);
|
dh += video_box->box_top;
|
||||||
|
dh += video_box->box_bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v = gst_structure_get_value (structure, "width");
|
||||||
|
if (!gst_video_box_transform_dimension_value (v, dw, &w_val)) {
|
||||||
|
GST_WARNING_OBJECT (video_box, "could not tranform width value with dw=%d"
|
||||||
|
", caps structure=%" GST_PTR_FORMAT, dw, structure);
|
||||||
|
gst_caps_unref (to);
|
||||||
|
to = gst_caps_new_empty ();
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
gst_structure_set_value (structure, "width", &w_val);
|
||||||
|
|
||||||
|
v = gst_structure_get_value (structure, "height");
|
||||||
|
if (!gst_video_box_transform_dimension_value (v, dh, &h_val)) {
|
||||||
|
g_value_unset (&w_val);
|
||||||
|
GST_WARNING_OBJECT (video_box,
|
||||||
|
"could not tranform height value with dh=%d" ", caps structure=%"
|
||||||
|
GST_PTR_FORMAT, dh, structure);
|
||||||
|
gst_caps_unref (to);
|
||||||
|
to = gst_caps_new_empty ();
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
gst_structure_set_value (structure, "height", &h_val);
|
||||||
|
g_value_unset (&w_val);
|
||||||
|
g_value_unset (&h_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Supported conversions:
|
/* Supported conversions:
|
||||||
|
|
Loading…
Reference in a new issue