tests: check: vaapipostproc test_crop_mouse_events
authorU. Artie Eoff <ullysses.a.eoff@intel.com>
Wed, 9 Oct 2019 17:11:54 +0000 (10:11 -0700)
committerU. Artie Eoff <ullysses.a.eoff@intel.com>
Wed, 16 Oct 2019 19:53:07 +0000 (12:53 -0700)
Test that vaapipostproc properly translates mouse events
when cropping.

tests/check/elements/vaapipostproc.c
tests/check/meson.build

index 9190fcf..82b894f 100644 (file)
 #endif
 
 #include <gst/check/gstcheck.h>
+#include <gst/video/video.h>
+#include <gst/video/navigation.h>
+
+typedef struct
+{
+  GstElement *pipeline;
+  GstElement *source;
+  GstElement *filter;
+  GstElement *vpp;
+  GstElement *sink;
+} VppTestContext;
+
+typedef struct
+{
+  gdouble x;
+  gdouble y;
+} VppTestCoordinate;
+
+typedef struct
+{
+  VppTestCoordinate send;
+  VppTestCoordinate expect;
+} VppTestCoordinateParams;
 
 GST_START_TEST (test_make)
 {
@@ -38,6 +61,211 @@ GST_START_TEST (test_make)
 
 GST_END_TEST;
 
+static void
+vpp_test_init_context (VppTestContext * ctx)
+{
+  GST_INFO ("initing context");
+
+  ctx->pipeline = gst_pipeline_new ("pipeline");
+  fail_unless (ctx->pipeline != NULL);
+
+  ctx->source = gst_element_factory_make ("videotestsrc", "src");
+  fail_unless (ctx->source != NULL, "Failed to create videotestsrc element");
+
+  ctx->filter = gst_element_factory_make ("capsfilter", "filter");
+  fail_unless (ctx->filter != NULL, "Failed to create caps filter element");
+
+  ctx->vpp = gst_element_factory_make ("vaapipostproc", "vpp");
+  fail_unless (ctx->vpp != NULL, "Failed to create vaapipostproc element");
+
+  ctx->sink = gst_element_factory_make ("fakesink", "sink");
+  fail_unless (ctx->sink != NULL, "Failed to create fakesink element");
+
+  gst_bin_add_many (GST_BIN (ctx->pipeline), ctx->source, ctx->filter, ctx->vpp,
+      ctx->sink, NULL);
+  gst_element_link_many (ctx->source, ctx->filter, ctx->vpp, ctx->sink, NULL);
+}
+
+static void
+vpp_test_deinit_context (VppTestContext * ctx)
+{
+  GST_INFO ("deiniting context");
+
+  gst_element_set_state (ctx->pipeline, GST_STATE_NULL);
+  gst_object_unref (ctx->pipeline);
+  memset (ctx, 0x00, sizeof (VppTestContext));
+}
+
+static void
+vpp_test_set_crop (VppTestContext * ctx, gint l, gint r, gint t, gint b)
+{
+  GST_LOG ("%d %d %d %0d", l, r, t, b);
+  g_object_set (ctx->vpp, "crop-left", l, "crop-right", r,
+      "crop-top", t, "crop-bottom", b, NULL);
+}
+
+static void
+vpp_test_set_dimensions (VppTestContext * ctx, gint w, gint h)
+{
+  GST_LOG ("%dx%d", w, h);
+  GstCaps *caps = gst_caps_new_simple ("video/x-raw",
+      "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
+  g_object_set (ctx->filter, "caps", caps, NULL);
+  gst_caps_unref (caps);
+}
+
+static GstPadProbeReturn
+cb_mouse_event (GstPad * pad, GstPadProbeInfo * info, gpointer data)
+{
+  VppTestCoordinate *coord = data;
+  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
+
+  if (GST_EVENT_TYPE (event) == GST_EVENT_NAVIGATION) {
+    switch (gst_navigation_event_get_type (event)) {
+      case GST_NAVIGATION_EVENT_MOUSE_MOVE:
+        gst_navigation_event_parse_mouse_move_event (event, &coord->x,
+            &coord->y);
+        break;
+      case GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS:
+      case GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE:
+        gst_navigation_event_parse_mouse_button_event (event, NULL, &coord->x,
+            &coord->y);
+        break;
+      default:
+        break;
+    }
+  }
+
+  return GST_PAD_PROBE_OK;
+}
+
+static void
+vpp_test_mouse_events (VppTestContext * ctx,
+    const VppTestCoordinateParams * const params, const size_t nparams)
+{
+  GstStructure *structure;
+  GstEvent *event;
+  VppTestCoordinate probed;
+  guint i, j;
+
+  /* probe mouse events propagated up from vaapipostproc */
+  GstPad *pad = gst_element_get_static_pad (ctx->source, "src");
+  gulong id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
+      (GstPadProbeCallback) cb_mouse_event, &probed, NULL);
+
+  const char *mouse_events[] = {
+    "mouse-move",
+    "mouse-button-press",
+    "mouse-button-release",
+  };
+
+  fail_unless (gst_element_set_state (ctx->pipeline, GST_STATE_PAUSED)
+      != GST_STATE_CHANGE_FAILURE);
+  fail_unless (gst_element_get_state (ctx->pipeline, NULL, NULL, -1)
+      == GST_STATE_CHANGE_SUCCESS);
+
+  for (i = 0; i < nparams; ++i) {
+    for (j = 0; j < G_N_ELEMENTS (mouse_events); ++j) {
+      probed.x = probed.y = -1;
+
+      GST_LOG ("sending %s event %fx%f", mouse_events[j], params[i].send.x,
+          params[i].send.y);
+      structure = gst_structure_new ("application/x-gst-navigation", "event",
+          G_TYPE_STRING, mouse_events[j],
+          "pointer_x", G_TYPE_DOUBLE, params[i].send.x,
+          "pointer_y", G_TYPE_DOUBLE, params[i].send.y, NULL);
+      event = gst_event_new_navigation (structure);
+      gst_element_send_event (ctx->pipeline, event);
+
+      GST_LOG ("probed %s event %fx%f", mouse_events[j], probed.x, probed.y);
+
+      fail_unless (params[i].expect.x == probed.x);
+      fail_unless (params[i].expect.y == probed.y);
+    }
+  }
+
+  gst_element_set_state (ctx->pipeline, GST_STATE_NULL);
+
+  gst_pad_remove_probe (pad, id);
+  gst_object_unref (pad);
+}
+
+static void
+vpp_test_crop_mouse_events (VppTestContext * ctx, gint w, gint h, gint l,
+    gint r, gint t, gint b)
+{
+  const gdouble xmin = 0.0;
+  const gdouble ymin = 0.0;
+  const gdouble xmax = w - (l + r) - 1;
+  const gdouble ymax = h - (t + b) - 1;
+  const gdouble xctr = xmax / 2;
+  const gdouble yctr = ymax / 2;
+  const gdouble xrand = g_random_double_range (xmin, xmax);
+  const gdouble yrand = g_random_double_range (ymin, ymax);
+
+  const gdouble e_xmin = xmin + l;
+  const gdouble e_ymin = ymin + t;
+  const gdouble e_xmax = xmax + l;
+  const gdouble e_ymax = ymax + t;
+  const gdouble e_xctr = xctr + l;
+  const gdouble e_yctr = yctr + t;
+  const gdouble e_xrand = xrand + l;
+  const gdouble e_yrand = yrand + t;
+
+  const VppTestCoordinateParams params[] = {
+    {{xmin, ymin}, {e_xmin, e_ymin}},   /* left-top */
+    {{xmin, yctr}, {e_xmin, e_yctr}},   /* left-center */
+    {{xmin, ymax}, {e_xmin, e_ymax}},   /* left-bottom */
+
+    {{xmax, ymin}, {e_xmax, e_ymin}},   /* right-top */
+    {{xmax, yctr}, {e_xmax, e_yctr}},   /* right-center */
+    {{xmax, ymax}, {e_xmax, e_ymax}},   /* right-bottom */
+
+    {{xctr, ymin}, {e_xctr, e_ymin}},   /* center-top */
+    {{xctr, yctr}, {e_xctr, e_yctr}},   /* center */
+    {{xctr, ymax}, {e_xctr, e_ymax}},   /* center-bottom */
+
+    {{xrand, yrand}, {e_xrand, e_yrand}},       /* random */
+  };
+
+  vpp_test_set_dimensions (ctx, w, h);
+  vpp_test_set_crop (ctx, l, r, t, b);
+  vpp_test_mouse_events (ctx, params, G_N_ELEMENTS (params));
+}
+
+GST_START_TEST (test_crop_mouse_events)
+{
+  VppTestContext ctx;
+
+  vpp_test_init_context (&ctx);
+
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 1, 0, 0, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 1, 0, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 1, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 1);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 63, 0, 0, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 63, 0, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 63, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 63);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 63, 0, 0, 1);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 63, 1, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 1, 63, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 1, 0, 0, 63);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 32, 0, 0, 128);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 32, 128, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 128, 32, 0);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 128, 0, 0, 32);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 1, 1, 1, 1);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 63, 63, 63, 63);
+  vpp_test_crop_mouse_events (&ctx, 160, 160, 64, 64, 64, 64);
+
+  vpp_test_deinit_context (&ctx);
+}
+
+GST_END_TEST;
+
 static Suite *
 vaapipostproc_suite (void)
 {
@@ -46,6 +274,7 @@ vaapipostproc_suite (void)
 
   suite_add_tcase (s, tc_chain);
   tcase_add_test (tc_chain, test_make);
+  tcase_add_test (tc_chain, test_crop_mouse_events);
 
   return s;
 }
index 1b2a4a0..7ebe8a8 100644 (file)
@@ -2,7 +2,7 @@ tests = [
   [ 'elements/vaapipostproc' ],
 ]
 
-test_deps = [gst_dep, gstcheck_dep]
+test_deps = [gst_dep, gstbase_dep, gstvideo_dep, gstcheck_dep]
 test_defines = [
   '-UG_DISABLE_ASSERT',
   '-UG_DISABLE_CAST_CHECKS',