Merge branch 'move_subdir_editing-services' into tizen_gst_1.19.2_mono
[platform/upstream/gstreamer.git] / subprojects / gstreamer-vaapi / tests / check / elements / vaapipostproc.c
1 /*
2  *  vaapipostproc.c - GStreamer unit test for the vaapipostproc element
3  *
4  *  Copyright (C) 2019 Intel Corporation
5  *    Author: U. Artie Eoff <ullysses.a.eoff@intel.com>
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public License
9  *  as published by the Free Software Foundation; either version 2.1
10  *  of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free
19  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301 USA
21  */
22
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #include <gst/check/gstcheck.h>
28 #include <gst/video/video.h>
29 #include <gst/video/navigation.h>
30
31 typedef struct
32 {
33   GstElement *pipeline;
34   GstElement *source;
35   GstElement *filter;
36   GstElement *vpp;
37   GstElement *sink;
38 } VppTestContext;
39
40 typedef struct
41 {
42   gdouble x;
43   gdouble y;
44 } VppTestCoordinate;
45
46 typedef struct
47 {
48   VppTestCoordinate send;
49   VppTestCoordinate expect;
50 } VppTestCoordinateParams;
51
52 GST_START_TEST (test_make)
53 {
54   GstElement *vaapipostproc;
55
56   vaapipostproc = gst_element_factory_make ("vaapipostproc", "vaapipostproc");
57   fail_unless (vaapipostproc != NULL, "Failed to create vaapipostproc element");
58
59   gst_object_unref (vaapipostproc);
60 }
61
62 GST_END_TEST;
63
64 static void
65 vpp_test_init_context (VppTestContext * ctx)
66 {
67   GST_INFO ("initing context");
68
69   ctx->pipeline = gst_pipeline_new ("pipeline");
70   fail_unless (ctx->pipeline != NULL);
71
72   ctx->source = gst_element_factory_make ("videotestsrc", "src");
73   fail_unless (ctx->source != NULL, "Failed to create videotestsrc element");
74
75   ctx->filter = gst_element_factory_make ("capsfilter", "filter");
76   fail_unless (ctx->filter != NULL, "Failed to create caps filter element");
77
78   ctx->vpp = gst_element_factory_make ("vaapipostproc", "vpp");
79   fail_unless (ctx->vpp != NULL, "Failed to create vaapipostproc element");
80
81   ctx->sink = gst_element_factory_make ("fakesink", "sink");
82   fail_unless (ctx->sink != NULL, "Failed to create fakesink element");
83
84   gst_bin_add_many (GST_BIN (ctx->pipeline), ctx->source, ctx->filter, ctx->vpp,
85       ctx->sink, NULL);
86   gst_element_link_many (ctx->source, ctx->filter, ctx->vpp, ctx->sink, NULL);
87 }
88
89 static void
90 vpp_test_deinit_context (VppTestContext * ctx)
91 {
92   GST_INFO ("deiniting context");
93
94   gst_element_set_state (ctx->pipeline, GST_STATE_NULL);
95   gst_object_unref (ctx->pipeline);
96   memset (ctx, 0x00, sizeof (VppTestContext));
97 }
98
99 static void
100 vpp_test_set_crop (VppTestContext * ctx, gint l, gint r, gint t, gint b)
101 {
102   GST_LOG ("%d %d %d %0d", l, r, t, b);
103   g_object_set (ctx->vpp, "crop-left", l, "crop-right", r,
104       "crop-top", t, "crop-bottom", b, NULL);
105 }
106
107 static void
108 vpp_test_set_orientation (VppTestContext * ctx, GstVideoOrientationMethod m)
109 {
110   GST_LOG ("%u", m);
111   g_object_set (ctx->vpp, "video-direction", m, NULL);
112 }
113
114 static void
115 vpp_test_set_dimensions (VppTestContext * ctx, gint w, gint h)
116 {
117   GstCaps *caps = gst_caps_new_simple ("video/x-raw",
118       "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, NULL);
119   GST_LOG ("%dx%d", w, h);
120   g_object_set (ctx->filter, "caps", caps, NULL);
121   gst_caps_unref (caps);
122 }
123
124 static GstPadProbeReturn
125 cb_mouse_event (GstPad * pad, GstPadProbeInfo * info, gpointer data)
126 {
127   VppTestCoordinate *coord = data;
128   gdouble x = 0, y = 0;
129   GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
130
131   if (GST_EVENT_TYPE (event) == GST_EVENT_NAVIGATION) {
132     switch (gst_navigation_event_get_type (event)) {
133       case GST_NAVIGATION_EVENT_MOUSE_MOVE:
134         if (gst_navigation_event_parse_mouse_move_event (event, &x, &y)) {
135           coord->x = x;
136           coord->y = y;
137         }
138         break;
139       case GST_NAVIGATION_EVENT_MOUSE_BUTTON_PRESS:
140       case GST_NAVIGATION_EVENT_MOUSE_BUTTON_RELEASE:
141         if (gst_navigation_event_parse_mouse_button_event (event, NULL, &x, &y)) {
142           coord->x = x;
143           coord->y = y;
144         }
145         break;
146       default:
147         break;
148     }
149   }
150
151   return GST_PAD_PROBE_OK;
152 }
153
154 static void
155 vpp_test_mouse_events (VppTestContext * ctx,
156     const VppTestCoordinateParams * const params, const size_t nparams)
157 {
158   GstStructure *structure;
159   GstEvent *event;
160   VppTestCoordinate probed = { 0, };
161   guint i, j;
162
163   /* probe mouse events propagated up from vaapipostproc */
164   GstPad *pad = gst_element_get_static_pad (ctx->source, "src");
165   gulong id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
166       (GstPadProbeCallback) cb_mouse_event, &probed, NULL);
167
168   const char *mouse_events[] = {
169     "mouse-move",
170     "mouse-button-press",
171     "mouse-button-release",
172   };
173
174   fail_unless (gst_element_set_state (ctx->pipeline, GST_STATE_PAUSED)
175       != GST_STATE_CHANGE_FAILURE);
176   fail_unless (gst_element_get_state (ctx->pipeline, NULL, NULL, -1)
177       == GST_STATE_CHANGE_SUCCESS);
178
179   for (i = 0; i < nparams; ++i) {
180     for (j = 0; j < G_N_ELEMENTS (mouse_events); ++j) {
181       probed.x = probed.y = -1;
182
183       GST_LOG ("sending %s event %fx%f", mouse_events[j], params[i].send.x,
184           params[i].send.y);
185       structure = gst_structure_new ("application/x-gst-navigation", "event",
186           G_TYPE_STRING, mouse_events[j],
187           "pointer_x", G_TYPE_DOUBLE, params[i].send.x,
188           "pointer_y", G_TYPE_DOUBLE, params[i].send.y, NULL);
189       event = gst_event_new_navigation (structure);
190       gst_element_send_event (ctx->pipeline, event);
191
192       GST_LOG ("probed %s event %fx%f", mouse_events[j], probed.x, probed.y);
193       GST_LOG ("expect %s event %fx%f", mouse_events[j], params[i].expect.x,
194           params[i].expect.y);
195
196       fail_unless (params[i].expect.x == probed.x);
197       fail_unless (params[i].expect.y == probed.y);
198     }
199   }
200
201   gst_element_set_state (ctx->pipeline, GST_STATE_NULL);
202
203   gst_pad_remove_probe (pad, id);
204   gst_object_unref (pad);
205 }
206
207 static void
208 vpp_test_crop_mouse_events (VppTestContext * ctx, gint w, gint h, gint l,
209     gint r, gint t, gint b)
210 {
211   const gdouble xmin = 0.0;
212   const gdouble ymin = 0.0;
213   const gdouble xmax = w - (l + r) - 1;
214   const gdouble ymax = h - (t + b) - 1;
215   const gdouble xctr = xmax / 2;
216   const gdouble yctr = ymax / 2;
217   const gdouble xrand = g_random_double_range (xmin, xmax);
218   const gdouble yrand = g_random_double_range (ymin, ymax);
219
220   const gdouble e_xmin = xmin + l;
221   const gdouble e_ymin = ymin + t;
222   const gdouble e_xmax = xmax + l;
223   const gdouble e_ymax = ymax + t;
224   const gdouble e_xctr = xctr + l;
225   const gdouble e_yctr = yctr + t;
226   const gdouble e_xrand = xrand + l;
227   const gdouble e_yrand = yrand + t;
228
229   const VppTestCoordinateParams params[] = {
230     {{xmin, ymin}, {e_xmin, e_ymin}},   /* left-top */
231     {{xmin, yctr}, {e_xmin, e_yctr}},   /* left-center */
232     {{xmin, ymax}, {e_xmin, e_ymax}},   /* left-bottom */
233
234     {{xmax, ymin}, {e_xmax, e_ymin}},   /* right-top */
235     {{xmax, yctr}, {e_xmax, e_yctr}},   /* right-center */
236     {{xmax, ymax}, {e_xmax, e_ymax}},   /* right-bottom */
237
238     {{xctr, ymin}, {e_xctr, e_ymin}},   /* center-top */
239     {{xctr, yctr}, {e_xctr, e_yctr}},   /* center */
240     {{xctr, ymax}, {e_xctr, e_ymax}},   /* center-bottom */
241
242     {{xrand, yrand}, {e_xrand, e_yrand}},       /* random */
243   };
244
245   vpp_test_set_dimensions (ctx, w, h);
246   vpp_test_set_crop (ctx, l, r, t, b);
247   vpp_test_mouse_events (ctx, params, G_N_ELEMENTS (params));
248 }
249
250 GST_START_TEST (test_crop_mouse_events)
251 {
252   VppTestContext ctx;
253
254   vpp_test_init_context (&ctx);
255
256   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 0);
257   vpp_test_crop_mouse_events (&ctx, 160, 160, 1, 0, 0, 0);
258   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 1, 0, 0);
259   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 1, 0);
260   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 1);
261   vpp_test_crop_mouse_events (&ctx, 160, 160, 63, 0, 0, 0);
262   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 63, 0, 0);
263   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 63, 0);
264   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 63);
265   vpp_test_crop_mouse_events (&ctx, 160, 160, 63, 0, 0, 1);
266   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 63, 1, 0);
267   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 1, 63, 0);
268   vpp_test_crop_mouse_events (&ctx, 160, 160, 1, 0, 0, 63);
269   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 0, 0, 0);
270   vpp_test_crop_mouse_events (&ctx, 160, 160, 32, 0, 0, 128);
271   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 32, 128, 0);
272   vpp_test_crop_mouse_events (&ctx, 160, 160, 0, 128, 32, 0);
273   vpp_test_crop_mouse_events (&ctx, 160, 160, 128, 0, 0, 32);
274   vpp_test_crop_mouse_events (&ctx, 160, 160, 1, 1, 1, 1);
275   vpp_test_crop_mouse_events (&ctx, 160, 160, 63, 63, 63, 63);
276   vpp_test_crop_mouse_events (&ctx, 160, 160, 64, 64, 64, 64);
277
278   vpp_test_deinit_context (&ctx);
279 }
280
281 GST_END_TEST;
282
283 static void
284 vpp_test_orientation_mouse_events (VppTestContext * ctx, gint w, gint h)
285 {
286   size_t i;
287   const gdouble xmin = 0.0;
288   const gdouble ymin = 0.0;
289   const gdouble xmax = w - 1;
290   const gdouble ymax = h - 1;
291   const VppTestCoordinateParams params[8][4] = {
292     /* (0) identity */
293     {
294           {{xmin, ymin}, {xmin, ymin}},
295           {{xmax, ymin}, {xmax, ymin}},
296           {{xmin, ymax}, {xmin, ymax}},
297           {{xmax, ymax}, {xmax, ymax}},
298         },
299     /* (1) 90 Rotation */
300     {
301           {{ymin, xmin}, {xmin, ymax}},
302           {{ymax, xmin}, {xmin, ymin}},
303           {{ymin, xmax}, {xmax, ymax}},
304           {{ymax, xmax}, {xmax, ymin}},
305         },
306     /* (2) 180 Rotation */
307     {
308           {{xmin, ymin}, {xmax, ymax}},
309           {{xmax, ymin}, {xmin, ymax}},
310           {{xmin, ymax}, {xmax, ymin}},
311           {{xmax, ymax}, {xmin, ymin}},
312         },
313     /* (3) 270 Rotation */
314     {
315           {{ymin, xmin}, {xmax, ymin}},
316           {{ymax, xmin}, {xmax, ymax}},
317           {{ymin, xmax}, {xmin, ymin}},
318           {{ymax, xmax}, {xmin, ymax}},
319         },
320     /* (4) Horizontal Flip */
321     {
322           {{xmin, ymin}, {xmax, ymin}},
323           {{xmax, ymin}, {xmin, ymin}},
324           {{xmin, ymax}, {xmax, ymax}},
325           {{xmax, ymax}, {xmin, ymax}},
326         },
327     /* (5) Vertical Flip */
328     {
329           {{xmin, ymin}, {xmin, ymax}},
330           {{xmax, ymin}, {xmax, ymax}},
331           {{xmin, ymax}, {xmin, ymin}},
332           {{xmax, ymax}, {xmax, ymin}},
333         },
334     /* (6) Vertical Flip + 90 Rotation */
335     {
336           {{ymin, xmin}, {xmin, ymin}},
337           {{ymax, xmin}, {xmin, ymax}},
338           {{ymin, xmax}, {xmax, ymin}},
339           {{ymax, xmax}, {xmax, ymax}},
340         },
341     /* (7) Horizontal Flip + 90 Rotation */
342     {
343           {{ymin, xmin}, {xmax, ymax}},
344           {{ymax, xmin}, {xmax, ymin}},
345           {{ymin, xmax}, {xmin, ymax}},
346           {{ymax, xmax}, {xmin, ymin}},
347         },
348   };
349
350   vpp_test_set_dimensions (ctx, w, h);
351
352   for (i = 0; i < 8; ++i) {
353     vpp_test_set_orientation (ctx, i);
354     vpp_test_mouse_events (ctx, params[i], 4);
355   }
356 }
357
358 GST_START_TEST (test_orientation_mouse_events)
359 {
360   VppTestContext ctx;
361
362   vpp_test_init_context (&ctx);
363
364   vpp_test_orientation_mouse_events (&ctx, 160, 320);
365   vpp_test_orientation_mouse_events (&ctx, 161, 320);
366   vpp_test_orientation_mouse_events (&ctx, 160, 321);
367   vpp_test_orientation_mouse_events (&ctx, 161, 321);
368
369   vpp_test_orientation_mouse_events (&ctx, 320, 160);
370   vpp_test_orientation_mouse_events (&ctx, 320, 161);
371   vpp_test_orientation_mouse_events (&ctx, 321, 160);
372   vpp_test_orientation_mouse_events (&ctx, 321, 161);
373
374   vpp_test_deinit_context (&ctx);
375 }
376
377 GST_END_TEST;
378
379 static Suite *
380 vaapipostproc_suite (void)
381 {
382   Suite *s = suite_create ("vaapipostproc");
383   TCase *tc_chain = tcase_create ("general");
384
385   suite_add_tcase (s, tc_chain);
386   tcase_add_test (tc_chain, test_make);
387   tcase_add_test (tc_chain, test_crop_mouse_events);
388   tcase_add_test (tc_chain, test_orientation_mouse_events);
389
390   return s;
391 }
392
393 GST_CHECK_MAIN (vaapipostproc);