videocrop: Add support for automatic cropping

This change enable automatic cropping using -1 set to left, top, right or
bottom property. In the case both side are set to automatic cropping, the
croping will be done equally on both side (in the odd case, right and
bottom cropping will be 1 pixel more).

https://bugzilla.gnome.org/show_bug.cgi?id=687761
This commit is contained in:
Nicolas Dufresne 2012-11-06 15:03:55 +01:00 committed by Olivier Crête
parent 8c44361bca
commit 1ad8ebac44
3 changed files with 185 additions and 65 deletions

View File

@ -179,17 +179,21 @@ gst_video_crop_class_init (GstVideoCropClass * klass)
gobject_class->get_property = gst_video_crop_get_property; gobject_class->get_property = gst_video_crop_get_property;
g_object_class_install_property (gobject_class, ARG_LEFT, g_object_class_install_property (gobject_class, ARG_LEFT,
g_param_spec_int ("left", "Left", "Pixels to crop at left", g_param_spec_int ("left", "Left",
0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); "Pixels to crop at left (-1 to auto-crop)", -1, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, ARG_RIGHT, g_object_class_install_property (gobject_class, ARG_RIGHT,
g_param_spec_int ("right", "Right", "Pixels to crop at right", g_param_spec_int ("right", "Right",
0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); "Pixels to crop at right (-1 to auto-crop)", -1, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, ARG_TOP, g_object_class_install_property (gobject_class, ARG_TOP,
g_param_spec_int ("top", "Top", "Pixels to crop at top", g_param_spec_int ("top", "Top",
0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); "Pixels to crop at top (-1 to auto-crop)", -1, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, ARG_BOTTOM, g_object_class_install_property (gobject_class, ARG_BOTTOM,
g_param_spec_int ("bottom", "Bottom", "Pixels to crop at bottom", g_param_spec_int ("bottom", "Bottom",
0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); "Pixels to crop at bottom (-1 to auto-crop)", -1, G_MAXINT, 0,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gst_element_class_add_pad_template (element_class, gst_element_class_add_pad_template (element_class,
gst_static_pad_template_get (&sink_template)); gst_static_pad_template_get (&sink_template));
@ -406,33 +410,69 @@ gst_video_crop_transform_dimension (gint val, gint delta)
static gboolean static gboolean
gst_video_crop_transform_dimension_value (const GValue * src_val, gst_video_crop_transform_dimension_value (const GValue * src_val,
gint delta, GValue * dest_val) gint delta, GValue * dest_val, GstPadDirection direction, gboolean dynamic)
{ {
gboolean ret = TRUE; gboolean ret = TRUE;
g_value_init (dest_val, G_VALUE_TYPE (src_val));
if (G_VALUE_HOLDS_INT (src_val)) { if (G_VALUE_HOLDS_INT (src_val)) {
gint ival = g_value_get_int (src_val); gint ival = g_value_get_int (src_val);
ival = gst_video_crop_transform_dimension (ival, delta); ival = gst_video_crop_transform_dimension (ival, delta);
g_value_set_int (dest_val, ival);
if (dynamic) {
if (direction == GST_PAD_SRC) {
if (ival == G_MAXINT) {
g_value_init (dest_val, G_TYPE_INT);
g_value_set_int (dest_val, ival);
} else {
g_value_init (dest_val, GST_TYPE_INT_RANGE);
gst_value_set_int_range (dest_val, ival, G_MAXINT);
}
} else {
if (ival == 1) {
g_value_init (dest_val, G_TYPE_INT);
g_value_set_int (dest_val, ival);
} else {
g_value_init (dest_val, GST_TYPE_INT_RANGE);
gst_value_set_int_range (dest_val, 1, ival);
}
}
} else {
g_value_init (dest_val, G_TYPE_INT);
g_value_set_int (dest_val, ival);
}
} else if (GST_VALUE_HOLDS_INT_RANGE (src_val)) { } else if (GST_VALUE_HOLDS_INT_RANGE (src_val)) {
gint min = gst_value_get_int_range_min (src_val); gint min = gst_value_get_int_range_min (src_val);
gint max = gst_value_get_int_range_max (src_val); gint max = gst_value_get_int_range_max (src_val);
min = gst_video_crop_transform_dimension (min, delta); min = gst_video_crop_transform_dimension (min, delta);
max = gst_video_crop_transform_dimension (max, delta); max = gst_video_crop_transform_dimension (max, delta);
gst_value_set_int_range (dest_val, min, max);
if (dynamic) {
if (direction == GST_PAD_SRC)
max = G_MAXINT;
else
min = 1;
}
if (min == max) {
g_value_init (dest_val, G_TYPE_INT);
g_value_set_int (dest_val, min);
} else {
g_value_init (dest_val, GST_TYPE_INT_RANGE);
gst_value_set_int_range (dest_val, min, max);
}
} else if (GST_VALUE_HOLDS_LIST (src_val)) { } else if (GST_VALUE_HOLDS_LIST (src_val)) {
gint i; gint i;
g_value_init (dest_val, GST_TYPE_LIST);
for (i = 0; i < gst_value_list_get_size (src_val); ++i) { for (i = 0; i < gst_value_list_get_size (src_val); ++i) {
const GValue *list_val; const GValue *list_val;
GValue newval = { 0, }; GValue newval = { 0, };
list_val = gst_value_list_get_value (src_val, i); list_val = gst_value_list_get_value (src_val, i);
if (gst_video_crop_transform_dimension_value (list_val, delta, &newval)) if (gst_video_crop_transform_dimension_value (list_val, delta, &newval,
direction, dynamic))
gst_value_list_append_value (dest_val, &newval); gst_value_list_append_value (dest_val, &newval);
g_value_unset (&newval); g_value_unset (&newval);
} }
@ -442,7 +482,6 @@ gst_video_crop_transform_dimension_value (const GValue * src_val,
ret = FALSE; ret = FALSE;
} }
} else { } else {
g_value_unset (dest_val);
ret = FALSE; ret = FALSE;
} }
@ -456,21 +495,30 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
{ {
GstVideoCrop *vcrop; GstVideoCrop *vcrop;
GstCaps *other_caps; GstCaps *other_caps;
gint dy, dx, i; gint dy, dx, i, left, right, bottom, top;
gboolean w_dynamic, h_dynamic;
vcrop = GST_VIDEO_CROP (trans); vcrop = GST_VIDEO_CROP (trans);
GST_OBJECT_LOCK (vcrop); GST_OBJECT_LOCK (vcrop);
GST_LOG_OBJECT (vcrop, "l=%d,r=%d,b=%d,t=%d", GST_LOG_OBJECT (vcrop, "l=%d,r=%d,b=%d,t=%d",
vcrop->crop_left, vcrop->crop_right, vcrop->crop_bottom, vcrop->crop_top); vcrop->prop_left, vcrop->prop_right, vcrop->prop_bottom, vcrop->prop_top);
w_dynamic = (vcrop->prop_left == -1 || vcrop->prop_right == -1);
h_dynamic = (vcrop->prop_top == -1 || vcrop->prop_bottom == -1);
left = (vcrop->prop_left == -1) ? 0 : vcrop->prop_left;
right = (vcrop->prop_right == -1) ? 0 : vcrop->prop_right;
bottom = (vcrop->prop_bottom == -1) ? 0 : vcrop->prop_bottom;
top = (vcrop->prop_top == -1) ? 0 : vcrop->prop_top;
if (direction == GST_PAD_SRC) { if (direction == GST_PAD_SRC) {
dx = vcrop->crop_left + vcrop->crop_right; dx = left + right;
dy = vcrop->crop_top + vcrop->crop_bottom; dy = top + bottom;
} else { } else {
dx = 0 - (vcrop->crop_left + vcrop->crop_right); dx = 0 - (left + right);
dy = 0 - (vcrop->crop_top + vcrop->crop_bottom); dy = 0 - (top + bottom);
} }
GST_OBJECT_UNLOCK (vcrop); GST_OBJECT_UNLOCK (vcrop);
@ -487,14 +535,16 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
structure = gst_caps_get_structure (caps, i); structure = gst_caps_get_structure (caps, i);
v = gst_structure_get_value (structure, "width"); v = gst_structure_get_value (structure, "width");
if (!gst_video_crop_transform_dimension_value (v, dx, &w_val)) { if (!gst_video_crop_transform_dimension_value (v, dx, &w_val, direction,
w_dynamic)) {
GST_WARNING_OBJECT (vcrop, "could not tranform width value with dx=%d" GST_WARNING_OBJECT (vcrop, "could not tranform width value with dx=%d"
", caps structure=%" GST_PTR_FORMAT, dx, structure); ", caps structure=%" GST_PTR_FORMAT, dx, structure);
continue; continue;
} }
v = gst_structure_get_value (structure, "height"); v = gst_structure_get_value (structure, "height");
if (!gst_video_crop_transform_dimension_value (v, dy, &h_val)) { if (!gst_video_crop_transform_dimension_value (v, dy, &h_val, direction,
h_dynamic)) {
g_value_unset (&w_val); g_value_unset (&w_val);
GST_WARNING_OBJECT (vcrop, "could not tranform height value with dy=%d" GST_WARNING_OBJECT (vcrop, "could not tranform height value with dy=%d"
", caps structure=%" GST_PTR_FORMAT, dy, structure); ", caps structure=%" GST_PTR_FORMAT, dy, structure);
@ -526,6 +576,41 @@ gst_video_crop_set_info (GstVideoFilter * vfilter, GstCaps * in,
GstVideoInfo * in_info, GstCaps * out, GstVideoInfo * out_info) GstVideoInfo * in_info, GstCaps * out, GstVideoInfo * out_info)
{ {
GstVideoCrop *crop = GST_VIDEO_CROP (vfilter); GstVideoCrop *crop = GST_VIDEO_CROP (vfilter);
int dx, dy;
crop->crop_left = crop->prop_left;
crop->crop_right = crop->prop_right;
crop->crop_top = crop->prop_top;
crop->crop_bottom = crop->prop_bottom;
dx = GST_VIDEO_INFO_WIDTH (in_info) - GST_VIDEO_INFO_WIDTH (out_info);
dy = GST_VIDEO_INFO_HEIGHT (in_info) - GST_VIDEO_INFO_HEIGHT (out_info);
if (crop->prop_left == -1 && crop->prop_right == -1) {
crop->crop_left = dx / 2;
crop->crop_right = dx / 2 + (dx & 1);
} else if (crop->prop_left == -1) {
if (G_UNLIKELY (crop->prop_right > dx))
goto cropping_too_much;
crop->crop_left = dx - crop->prop_right;
} else if (crop->prop_right == -1) {
if (G_UNLIKELY (crop->prop_left > dx))
goto cropping_too_much;
crop->crop_right = dx - crop->prop_left;
}
if (crop->prop_top == -1 && crop->prop_bottom == -1) {
crop->crop_top = dy / 2;
crop->crop_bottom = dy / 2 + (dy & 1);
} else if (crop->prop_top == -1) {
if (G_UNLIKELY (crop->prop_bottom > dy))
goto cropping_too_much;
crop->crop_top = dy - crop->prop_bottom;
} else if (crop->prop_bottom == -1) {
if (G_UNLIKELY (crop->prop_top > dy))
goto cropping_too_much;
crop->crop_bottom = dy - crop->prop_top;
}
if (G_UNLIKELY ((crop->crop_left + crop->crop_right) >= if (G_UNLIKELY ((crop->crop_left + crop->crop_right) >=
GST_VIDEO_INFO_WIDTH (in_info) GST_VIDEO_INFO_WIDTH (in_info)
@ -582,12 +667,12 @@ gst_video_crop_set_info (GstVideoFilter * vfilter, GstCaps * in,
/* ERROR */ /* ERROR */
cropping_too_much: cropping_too_much:
{ {
GST_DEBUG_OBJECT (crop, "we are cropping too much"); GST_WARNING_OBJECT (crop, "we are cropping too much");
return FALSE; return FALSE;
} }
unknown_format: unknown_format:
{ {
GST_DEBUG_OBJECT (crop, "Unsupported format"); GST_WARNING_OBJECT (crop, "Unsupported format");
return FALSE; return FALSE;
} }
} }
@ -607,16 +692,16 @@ gst_video_crop_set_property (GObject * object, guint prop_id,
GST_OBJECT_LOCK (video_crop); GST_OBJECT_LOCK (video_crop);
switch (prop_id) { switch (prop_id) {
case ARG_LEFT: case ARG_LEFT:
video_crop->crop_left = g_value_get_int (value); video_crop->prop_left = g_value_get_int (value);
break; break;
case ARG_RIGHT: case ARG_RIGHT:
video_crop->crop_right = g_value_get_int (value); video_crop->prop_right = g_value_get_int (value);
break; break;
case ARG_TOP: case ARG_TOP:
video_crop->crop_top = g_value_get_int (value); video_crop->prop_top = g_value_get_int (value);
break; break;
case ARG_BOTTOM: case ARG_BOTTOM:
video_crop->crop_bottom = g_value_get_int (value); video_crop->prop_bottom = g_value_get_int (value);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -642,16 +727,16 @@ gst_video_crop_get_property (GObject * object, guint prop_id, GValue * value,
GST_OBJECT_LOCK (video_crop); GST_OBJECT_LOCK (video_crop);
switch (prop_id) { switch (prop_id) {
case ARG_LEFT: case ARG_LEFT:
g_value_set_int (value, video_crop->crop_left); g_value_set_int (value, video_crop->prop_left);
break; break;
case ARG_RIGHT: case ARG_RIGHT:
g_value_set_int (value, video_crop->crop_right); g_value_set_int (value, video_crop->prop_right);
break; break;
case ARG_TOP: case ARG_TOP:
g_value_set_int (value, video_crop->crop_top); g_value_set_int (value, video_crop->prop_top);
break; break;
case ARG_BOTTOM: case ARG_BOTTOM:
g_value_set_int (value, video_crop->crop_bottom); g_value_set_int (value, video_crop->prop_bottom);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);

View File

@ -51,6 +51,11 @@ struct _GstVideoCrop
GstVideoFilter parent; GstVideoFilter parent;
/*< private >*/ /*< private >*/
gint prop_left;
gint prop_right;
gint prop_top;
gint prop_bottom;
gint crop_left; gint crop_left;
gint crop_right; gint crop_right;
gint crop_top; gint crop_top;

View File

@ -160,6 +160,7 @@ typedef struct
GstElement *src; GstElement *src;
GstElement *filter; GstElement *filter;
GstElement *crop; GstElement *crop;
GstElement *filter2;
GstElement *sink; GstElement *sink;
GstBuffer *last_buf; GstBuffer *last_buf;
GstCaps *last_caps; GstCaps *last_caps;
@ -190,12 +191,16 @@ videocrop_test_cropping_init_context (GstVideoCropTestContext * ctx)
fail_unless (ctx->filter != NULL, "Failed to create capsfilter element"); fail_unless (ctx->filter != NULL, "Failed to create capsfilter element");
ctx->crop = gst_element_factory_make ("videocrop", "crop"); ctx->crop = gst_element_factory_make ("videocrop", "crop");
fail_unless (ctx->crop != NULL, "Failed to create videocrop element"); fail_unless (ctx->crop != NULL, "Failed to create videocrop element");
ctx->filter2 = gst_element_factory_make ("capsfilter", "filter2");
fail_unless (ctx->filter2 != NULL,
"Failed to create second capsfilter element");
ctx->sink = gst_element_factory_make ("fakesink", "sink"); ctx->sink = gst_element_factory_make ("fakesink", "sink");
fail_unless (ctx->sink != NULL, "Failed to create fakesink element"); fail_unless (ctx->sink != NULL, "Failed to create fakesink element");
gst_bin_add_many (GST_BIN (ctx->pipeline), ctx->src, ctx->filter, gst_bin_add_many (GST_BIN (ctx->pipeline), ctx->src, ctx->filter,
ctx->crop, ctx->sink, NULL); ctx->crop, ctx->filter2, ctx->sink, NULL);
gst_element_link_many (ctx->src, ctx->filter, ctx->crop, ctx->sink, NULL); gst_element_link_many (ctx->src, ctx->filter, ctx->crop, ctx->filter2,
ctx->sink, NULL);
/* set pattern to 'red' - for our purposes it doesn't matter anyway */ /* set pattern to 'red' - for our purposes it doesn't matter anyway */
g_object_set (ctx->src, "pattern", 4, NULL); g_object_set (ctx->src, "pattern", 4, NULL);
@ -225,13 +230,15 @@ typedef void (*GstVideoCropTestBufferFunc) (GstBuffer * buffer, GstCaps * caps);
static void static void
videocrop_test_cropping (GstVideoCropTestContext * ctx, GstCaps * in_caps, videocrop_test_cropping (GstVideoCropTestContext * ctx, GstCaps * in_caps,
gint left, gint right, gint top, gint bottom, GstCaps * out_caps, gint left, gint right, gint top, gint bottom,
GstVideoCropTestBufferFunc func) GstVideoCropTestBufferFunc func)
{ {
GST_LOG ("lrtb = %03u %03u %03u %03u, caps = %" GST_PTR_FORMAT, left, right, GST_LOG ("lrtb = %03u %03u %03u %03u, in_caps = %" GST_PTR_FORMAT
top, bottom, in_caps); ", out_caps = %" GST_PTR_FORMAT, left, right, top, bottom, in_caps,
out_caps);
g_object_set (ctx->filter, "caps", in_caps, NULL); g_object_set (ctx->filter, "caps", in_caps, NULL);
g_object_set (ctx->filter2, "caps", out_caps, NULL);
g_object_set (ctx->crop, "left", left, "right", right, "top", top, g_object_set (ctx->crop, "left", left, "right", right, "top", top,
"bottom", bottom, NULL); "bottom", bottom, NULL);
@ -345,11 +352,12 @@ GST_START_TEST (test_crop_to_1x1)
gst_structure_set (s, "width", G_TYPE_INT, 160, gst_structure_set (s, "width", G_TYPE_INT, 160,
"height", G_TYPE_INT, 160, NULL); "height", G_TYPE_INT, 160, NULL);
videocrop_test_cropping (&ctx, caps, 159, 0, 159, 0, check_1x1_buffer); videocrop_test_cropping (&ctx, caps, NULL, 159, 0, 159, 0,
check_1x1_buffer);
/* commented out because they don't really add anything useful check-wise: /* commented out because they don't really add anything useful check-wise:
videocrop_test_cropping (&ctx, caps, 0, 159, 0, 159, check_1x1_buffer); videocrop_test_cropping (&ctx, caps, NULL, 0, 159, 0, 159, check_1x1_buffer);
videocrop_test_cropping (&ctx, caps, 159, 0, 0, 159, check_1x1_buffer); videocrop_test_cropping (&ctx, caps, NULL, 159, 0, 0, 159, check_1x1_buffer);
videocrop_test_cropping (&ctx, caps, 0, 159, 159, 0, check_1x1_buffer); videocrop_test_cropping (&ctx, caps, NULL, 0, 159, 159, 0, check_1x1_buffer);
*/ */
gst_caps_unref (caps); gst_caps_unref (caps);
} }
@ -397,7 +405,7 @@ GST_START_TEST (test_cropping)
GST_INFO ("testing format: %" GST_PTR_FORMAT, caps); GST_INFO ("testing format: %" GST_PTR_FORMAT, caps);
for (i = 0; i < G_N_ELEMENTS (sizes_to_try); ++i) { for (i = 0; i < G_N_ELEMENTS (sizes_to_try); ++i) {
GstCaps *in_caps; GstCaps *in_caps, *out_caps;
GST_INFO (" - %d x %d", sizes_to_try[i].width, sizes_to_try[i].height); GST_INFO (" - %d x %d", sizes_to_try[i].width, sizes_to_try[i].height);
@ -405,29 +413,51 @@ GST_START_TEST (test_cropping)
"height", G_TYPE_INT, sizes_to_try[i].height, NULL); "height", G_TYPE_INT, sizes_to_try[i].height, NULL);
in_caps = gst_caps_copy (caps); in_caps = gst_caps_copy (caps);
videocrop_test_cropping (&ctx, in_caps, 0, 0, 0, 0, NULL); gst_structure_set (s, "width", G_TYPE_INT, 1, "height", G_TYPE_INT, 1,
videocrop_test_cropping (&ctx, in_caps, 1, 0, 0, 0, NULL); NULL);
videocrop_test_cropping (&ctx, in_caps, 0, 1, 0, 0, NULL); out_caps = gst_caps_copy (caps);
videocrop_test_cropping (&ctx, in_caps, 0, 0, 1, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 0, 0, 0, 1, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 0, 0, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 63, 0, 0, 0, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 1, 0, 0, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 0, 63, 0, 0, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 1, 0, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 0, 0, 63, 0, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 0, 1, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 0, 0, 0, 63, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 0, 0, 1, NULL);
videocrop_test_cropping (&ctx, in_caps, 63, 0, 0, 1, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 63, 0, 0, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 0, 63, 1, 0, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 63, 0, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 0, 1, 63, 0, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 0, 63, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 1, 0, 0, 63, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 0, 0, 63, NULL);
videocrop_test_cropping (&ctx, in_caps, 0, 0, 0, 0, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 63, 0, 0, 1, NULL);
videocrop_test_cropping (&ctx, in_caps, 32, 0, 0, 128, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 63, 1, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 0, 32, 128, 0, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 1, 63, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 0, 128, 32, 0, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 1, 0, 0, 63, NULL);
videocrop_test_cropping (&ctx, in_caps, 128, 0, 0, 32, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 0, 0, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 1, 1, 1, 1, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 32, 0, 0, 128, NULL);
videocrop_test_cropping (&ctx, in_caps, 63, 63, 63, 63, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 32, 128, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, 64, 64, 64, 64, NULL); videocrop_test_cropping (&ctx, in_caps, NULL, 0, 128, 32, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, NULL, 128, 0, 0, 32, NULL);
videocrop_test_cropping (&ctx, in_caps, NULL, 1, 1, 1, 1, NULL);
videocrop_test_cropping (&ctx, in_caps, NULL, 63, 63, 63, 63, NULL);
videocrop_test_cropping (&ctx, in_caps, NULL, 64, 64, 64, 64, NULL);
/* Dynamic cropping */
videocrop_test_cropping (&ctx, in_caps, out_caps, -1, -1, -1, -1, NULL);
videocrop_test_cropping (&ctx, in_caps, out_caps, 0, -1, -1, -1, NULL);
videocrop_test_cropping (&ctx, in_caps, out_caps, -1, 0, -1, -1, NULL);
videocrop_test_cropping (&ctx, in_caps, out_caps, -1, -1, 0, -1, NULL);
videocrop_test_cropping (&ctx, in_caps, out_caps, -1, -1, -1, 0, NULL);
videocrop_test_cropping (&ctx, in_caps, out_caps, 10, -1, 10, -1, NULL);
videocrop_test_cropping (&ctx, in_caps, out_caps, -1, 10, -1, 10, NULL);
videocrop_test_cropping (&ctx, in_caps, out_caps,
sizes_to_try[i].width - 1, -1, -1, -1, NULL);
videocrop_test_cropping (&ctx, in_caps, out_caps, -1,
sizes_to_try[i].width - 1, -1, -1, NULL);
videocrop_test_cropping (&ctx, in_caps, out_caps, -1, -1,
sizes_to_try[i].height - 1, -1, NULL);
videocrop_test_cropping (&ctx, in_caps, out_caps, -1, -1, -1,
sizes_to_try[i].height - 1, NULL);
gst_caps_unref (in_caps); gst_caps_unref (in_caps);
gst_caps_unref (out_caps);
} }
gst_caps_unref (caps); gst_caps_unref (caps);