1 /* GStreamer unit tests for the deinterlace element
2 * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
25 #include <gst/check/gstcheck.h>
26 #include <gst/video/video.h>
29 gst_caps_is_interlaced (GstCaps * caps)
33 fail_unless (gst_caps_is_fixed (caps));
34 fail_unless (gst_video_info_from_caps (&info, caps));
36 return GST_VIDEO_INFO_IS_INTERLACED (&info);
39 GST_START_TEST (test_create_and_unref)
41 GstElement *deinterlace;
43 deinterlace = gst_element_factory_make ("deinterlace", NULL);
44 fail_unless (deinterlace != NULL);
46 gst_element_set_state (deinterlace, GST_STATE_NULL);
47 gst_object_unref (deinterlace);
52 #define CAPS_VIDEO_COMMON \
53 "width=(int)800, height=(int)600, framerate=(fraction)15/1"
55 #define CAPS_IMAGE_COMMON \
56 "width=(int)3200, height=(int)3400, framerate=(fraction)0/1"
60 CAPS_VIDEO_COMMON ", " \
63 #define CAPS_YUY2_INTERLACED \
65 "interlace-mode=interleaved"
69 CAPS_VIDEO_COMMON ", " \
72 #define CAPS_YVYU_INTERLACED \
74 "interlace-mode=interleaved"
76 #define CAPS_YUY2_IMAGE \
78 CAPS_IMAGE_COMMON ", " \
81 #define CAPS_YUY2_INTERLACED_IMAGE \
82 CAPS_YUY2_IMAGE ", " \
83 "interlace-mode=interleaved"
85 #define CAPS_YVYU_IMAGE \
87 CAPS_IMAGE_COMMON ", " \
90 #define CAPS_YVYU_INTERLACED_IMAGE \
91 CAPS_YVYU_IMAGE ", " \
92 "interlace-mode=interleaved"
94 static GstElement *deinterlace;
95 static GstPad *srcpad;
96 static GstPad *sinkpad;
98 static GstElement *pipeline;
100 /* sets up deinterlace and shortcut pointers to its pads */
102 setup_deinterlace (void)
104 deinterlace = gst_element_factory_make ("deinterlace", NULL);
105 fail_unless (deinterlace != NULL);
107 sinkpad = gst_element_get_static_pad (deinterlace, "sink");
108 fail_unless (sinkpad != NULL);
109 srcpad = gst_element_get_static_pad (deinterlace, "src");
110 fail_unless (srcpad != NULL);
113 /* sets up a basic test pipeline containing:
115 * videotestsrc ! capsfilter ! deinterlace ! fakesink
117 * The parameters set the capsfilter caps and the num-buffers
118 * property of videotestsrc
120 * It is useful for adding buffer probes to deinterlace pads
121 * and validating inputs/outputs
124 setup_test_pipeline (gint mode, GstCaps * infiltercaps, GstCaps * outfiltercaps,
128 GstElement *infilter;
129 GstElement *outfilter;
132 setup_deinterlace ();
134 pipeline = gst_pipeline_new ("pipeline");
135 src = gst_element_factory_make ("videotestsrc", NULL);
136 infilter = gst_element_factory_make ("capsfilter", "infilter");
137 outfilter = gst_element_factory_make ("capsfilter", "outfilter");
138 sink = gst_element_factory_make ("fakesink", NULL);
139 fail_if (src == NULL);
140 fail_if (infilter == NULL);
141 fail_if (outfilter == NULL);
142 fail_if (sink == NULL);
144 fail_unless (gst_bin_add (GST_BIN (pipeline), src));
145 fail_unless (gst_bin_add (GST_BIN (pipeline), infilter));
146 fail_unless (gst_bin_add (GST_BIN (pipeline), deinterlace));
147 fail_unless (gst_bin_add (GST_BIN (pipeline), outfilter));
148 fail_unless (gst_bin_add (GST_BIN (pipeline), sink));
150 /* set the properties */
151 g_object_set (deinterlace, "mode", mode, NULL);
153 g_object_set (src, "num-buffers", numbuffers, NULL);
155 g_object_set (infilter, "caps", infiltercaps, NULL);
157 g_object_set (outfilter, "caps", outfiltercaps, NULL);
159 fail_unless (gst_element_link_many (src, infilter, deinterlace, outfilter,
162 gst_caps_unref (infiltercaps);
164 gst_caps_unref (outfiltercaps);
168 * Checks if 2 buffers are equal
170 * Equals means same data
173 test_buffer_equals (GstBuffer * buf_a, GstBuffer * buf_b)
176 gboolean res = FALSE;
178 gst_buffer_map (buf_a, &m1, GST_MAP_READ);
179 gst_buffer_map (buf_b, &m2, GST_MAP_READ);
181 if (m1.size == m2.size) {
182 res = memcmp (m1.data, m2.data, m1.size) == 0;
184 gst_buffer_unmap (buf_a, &m1);
185 gst_buffer_unmap (buf_b, &m2);
190 static GstPadProbeReturn
191 sinkpad_enqueue_buffer (GstPad * pad, GstPadProbeInfo * info, gpointer data)
193 GQueue *queue = (GQueue *) data;
194 GstBuffer *buf = GST_PAD_PROBE_INFO_BUFFER (info);
196 /* enqueue a copy for being compared later */
197 g_queue_push_tail (queue, gst_buffer_copy (buf));
199 return GST_PAD_PROBE_OK;
203 * pad buffer probe that compares the buffer with the top one
204 * in the GQueue passed as the user data
206 static GstPadProbeReturn
207 srcpad_dequeue_and_compare_buffer (GstPad * pad, GstPadProbeInfo * info,
210 GQueue *queue = (GQueue *) data;
211 GstBuffer *buf = GST_PAD_PROBE_INFO_BUFFER (info);
212 GstBuffer *queue_buf;
214 queue_buf = (GstBuffer *) g_queue_pop_head (queue);
215 fail_if (queue_buf == NULL);
217 fail_unless (test_buffer_equals (buf, queue_buf));
219 gst_buffer_unref (queue_buf);
221 return GST_PAD_PROBE_OK;
225 * Utility function that sets up a pipeline with deinterlace for
226 * validanting that it operates in passthrough mode when receiving
227 * data with 'infiltercaps' as the input caps and operating in 'mode' mode
230 deinterlace_check_passthrough (gint mode, const gchar * infiltercaps)
234 GstCaps *incaps = NULL;
237 incaps = gst_caps_from_string (infiltercaps);
239 setup_test_pipeline (mode, incaps, NULL, 20);
241 queue = g_queue_new ();
243 /* set up probes for testing */
244 gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_BUFFER, sinkpad_enqueue_buffer,
246 gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_BUFFER,
247 srcpad_dequeue_and_compare_buffer, queue, NULL);
249 fail_unless (gst_element_set_state (pipeline, GST_STATE_PLAYING) !=
250 GST_STATE_CHANGE_FAILURE);
252 msg = gst_bus_poll (GST_ELEMENT_BUS (pipeline),
253 GST_MESSAGE_ERROR | GST_MESSAGE_EOS, -1);
254 if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
255 GST_ERROR ("ERROR: %" GST_PTR_FORMAT, msg);
256 fail ("Unexpected error message");
258 gst_message_unref (msg);
260 /* queue should be empty */
261 fail_unless (g_queue_is_empty (queue));
263 fail_unless (gst_element_set_state (pipeline, GST_STATE_NULL) ==
264 GST_STATE_CHANGE_SUCCESS);
265 gst_object_unref (pipeline);
266 g_queue_free (queue);
270 * Sets the caps on deinterlace sinkpad and validates the
271 * caps that is set on the srcpad
274 deinterlace_set_caps_and_check (GstCaps * input, gboolean must_deinterlace)
276 GstCaps *othercaps = NULL;
278 fail_unless (gst_pad_set_caps (sinkpad, input));
279 g_object_get (srcpad, "caps", &othercaps, NULL);
281 if (must_deinterlace) {
282 fail_if (gst_caps_is_interlaced (othercaps));
286 fail_unless (gst_caps_is_interlaced (input) ==
287 gst_caps_is_interlaced (othercaps));
289 othercaps = gst_caps_make_writable (othercaps);
290 s = gst_caps_get_structure (othercaps, 0);
291 gst_structure_remove_field (s, "interlace-mode");
293 input = gst_caps_make_writable (input);
294 s = gst_caps_get_structure (input, 0);
295 gst_structure_remove_field (s, "interlace-mode");
297 fail_unless (gst_caps_is_equal (input, othercaps));
299 gst_caps_unref (input);
300 gst_caps_unref (othercaps);
304 deinterlace_set_string_caps_and_check (const gchar * input,
305 gboolean must_deinterlace)
307 deinterlace_set_caps_and_check (gst_caps_from_string (input),
311 GST_START_TEST (test_mode_auto_accept_caps)
313 setup_deinterlace ();
316 g_object_set (deinterlace, "mode", 0, NULL);
317 fail_unless (gst_element_set_state (deinterlace, GST_STATE_PLAYING) ==
318 GST_STATE_CHANGE_SUCCESS);
320 /* try to set non interlaced caps */
321 deinterlace_set_string_caps_and_check (CAPS_YVYU, FALSE);
322 deinterlace_set_string_caps_and_check (CAPS_YUY2, FALSE);
323 deinterlace_set_string_caps_and_check (CAPS_YVYU_IMAGE, FALSE);
324 deinterlace_set_string_caps_and_check (CAPS_YUY2_IMAGE, FALSE);
326 /* now try to set interlaced caps */
327 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED, TRUE);
328 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED, TRUE);
329 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED_IMAGE, TRUE);
330 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED_IMAGE, TRUE);
333 gst_object_unref (sinkpad);
334 gst_object_unref (srcpad);
335 fail_unless (gst_element_set_state (deinterlace, GST_STATE_NULL) ==
336 GST_STATE_CHANGE_SUCCESS);
337 gst_object_unref (deinterlace);
342 GST_START_TEST (test_mode_forced_accept_caps)
344 setup_deinterlace ();
347 g_object_set (deinterlace, "mode", 1, NULL);
348 fail_unless (gst_element_set_state (deinterlace, GST_STATE_PLAYING) ==
349 GST_STATE_CHANGE_SUCCESS);
351 /* try to set non interlaced caps */
352 deinterlace_set_string_caps_and_check (CAPS_YVYU, TRUE);
353 deinterlace_set_string_caps_and_check (CAPS_YUY2, TRUE);
354 deinterlace_set_string_caps_and_check (CAPS_YVYU_IMAGE, TRUE);
355 deinterlace_set_string_caps_and_check (CAPS_YUY2_IMAGE, TRUE);
357 /* now try to set interlaced caps */
358 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED, TRUE);
359 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED, TRUE);
360 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED_IMAGE, TRUE);
361 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED_IMAGE, TRUE);
364 gst_object_unref (sinkpad);
365 gst_object_unref (srcpad);
366 fail_unless (gst_element_set_state (deinterlace, GST_STATE_NULL) ==
367 GST_STATE_CHANGE_SUCCESS);
368 gst_object_unref (deinterlace);
373 GST_START_TEST (test_mode_disabled_accept_caps)
375 setup_deinterlace ();
378 g_object_set (deinterlace, "mode", 2, NULL);
379 fail_unless (gst_element_set_state (deinterlace, GST_STATE_PLAYING) ==
380 GST_STATE_CHANGE_SUCCESS);
382 /* try to set non interlaced caps */
383 deinterlace_set_string_caps_and_check (CAPS_YVYU, FALSE);
384 deinterlace_set_string_caps_and_check (CAPS_YUY2, FALSE);
385 deinterlace_set_string_caps_and_check (CAPS_YVYU_IMAGE, FALSE);
386 deinterlace_set_string_caps_and_check (CAPS_YUY2_IMAGE, FALSE);
388 /* now try to set interlaced caps */
389 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED, FALSE);
390 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED, FALSE);
391 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED_IMAGE, FALSE);
392 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED_IMAGE, FALSE);
395 gst_object_unref (sinkpad);
396 gst_object_unref (srcpad);
397 fail_unless (gst_element_set_state (deinterlace, GST_STATE_NULL) ==
398 GST_STATE_CHANGE_SUCCESS);
399 gst_object_unref (deinterlace);
404 GST_START_TEST (test_mode_disabled_passthrough)
406 /* 2 is disabled mode */
407 deinterlace_check_passthrough (2, CAPS_YUY2_INTERLACED);
408 deinterlace_check_passthrough (2, CAPS_YVYU_INTERLACED);
409 deinterlace_check_passthrough (2, CAPS_YUY2);
410 deinterlace_check_passthrough (2, CAPS_YVYU);
412 deinterlace_check_passthrough (2, CAPS_YUY2_INTERLACED_IMAGE);
413 deinterlace_check_passthrough (2, CAPS_YVYU_INTERLACED_IMAGE);
414 deinterlace_check_passthrough (2, CAPS_YUY2_IMAGE);
415 deinterlace_check_passthrough (2, CAPS_YVYU_IMAGE);
420 GST_START_TEST (test_mode_auto_deinterlaced_passthrough)
423 deinterlace_check_passthrough (0, CAPS_YUY2);
424 deinterlace_check_passthrough (0, CAPS_YVYU);
425 deinterlace_check_passthrough (0, CAPS_YUY2_IMAGE);
426 deinterlace_check_passthrough (0, CAPS_YVYU_IMAGE);
432 deinterlace_suite (void)
434 Suite *s = suite_create ("deinterlace");
435 TCase *tc_chain = tcase_create ("general");
437 suite_add_tcase (s, tc_chain);
438 tcase_set_timeout (tc_chain, 180);
440 if (!gst_registry_check_feature_version (gst_registry_get (), "deinterlace",
441 GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO)) {
442 GST_ERROR ("FIXME: port deinterlace element");
446 tcase_add_test (tc_chain, test_create_and_unref);
447 tcase_add_test (tc_chain, test_mode_auto_accept_caps);
448 tcase_add_test (tc_chain, test_mode_forced_accept_caps);
449 tcase_add_test (tc_chain, test_mode_disabled_accept_caps);
450 tcase_add_test (tc_chain, test_mode_disabled_passthrough);
451 tcase_add_test (tc_chain, test_mode_auto_deinterlaced_passthrough);
456 GST_CHECK_MAIN (deinterlace);