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)
31 GstStructure G_GNUC_UNUSED *structure;
32 gboolean interlaced = FALSE;
34 fail_unless (gst_caps_is_fixed (caps));
35 structure = gst_caps_get_structure (caps, 0);
36 fail_unless (gst_video_format_parse_caps_interlaced (caps, &interlaced));
40 GST_START_TEST (test_create_and_unref)
42 GstElement *deinterlace;
44 deinterlace = gst_element_factory_make ("deinterlace", NULL);
45 fail_unless (deinterlace != NULL);
47 gst_element_set_state (deinterlace, GST_STATE_NULL);
48 gst_object_unref (deinterlace);
53 #define CAPS_VIDEO_COMMON \
54 "width=(int)800, height=(int)600, framerate=(fraction)15/1"
56 #define CAPS_IMAGE_COMMON \
57 "width=(int)3200, height=(int)3400, framerate=(fraction)0/1"
61 CAPS_VIDEO_COMMON ", " \
64 #define CAPS_YUY2_INTERLACED \
66 "interlaced=(boolean)true"
70 CAPS_VIDEO_COMMON ", " \
73 #define CAPS_YVYU_INTERLACED \
75 "interlaced=(boolean)true"
77 #define CAPS_YUY2_IMAGE \
79 CAPS_IMAGE_COMMON ", " \
82 #define CAPS_YUY2_INTERLACED_IMAGE \
83 CAPS_YUY2_IMAGE ", " \
84 "interlaced=(boolean)true"
86 #define CAPS_YVYU_IMAGE \
88 CAPS_IMAGE_COMMON ", " \
91 #define CAPS_YVYU_INTERLACED_IMAGE \
92 CAPS_YVYU_IMAGE ", " \
93 "interlaced=(boolean)true"
95 static GstElement *deinterlace;
96 static GstPad *srcpad;
97 static GstPad *sinkpad;
99 static GstElement *pipeline;
101 /* sets up deinterlace and shortcut pointers to its pads */
103 setup_deinterlace (void)
105 deinterlace = gst_element_factory_make ("deinterlace", NULL);
106 fail_unless (deinterlace != NULL);
108 sinkpad = gst_element_get_static_pad (deinterlace, "sink");
109 fail_unless (sinkpad != NULL);
110 srcpad = gst_element_get_static_pad (deinterlace, "src");
111 fail_unless (srcpad != NULL);
114 /* sets up a basic test pipeline containing:
116 * videotestsrc ! capsfilter ! deinterlace ! fakesink
118 * The parameters set the capsfilter caps and the num-buffers
119 * property of videotestsrc
121 * It is useful for adding buffer probes to deinterlace pads
122 * and validating inputs/outputs
125 setup_test_pipeline (gint mode, GstCaps * infiltercaps, GstCaps * outfiltercaps,
129 GstElement *infilter;
130 GstElement *outfilter;
133 setup_deinterlace ();
135 pipeline = gst_pipeline_new ("pipeline");
136 src = gst_element_factory_make ("videotestsrc", NULL);
137 infilter = gst_element_factory_make ("capsfilter", "infilter");
138 outfilter = gst_element_factory_make ("capsfilter", "outfilter");
139 sink = gst_element_factory_make ("fakesink", NULL);
140 fail_if (src == NULL);
141 fail_if (infilter == NULL);
142 fail_if (outfilter == NULL);
143 fail_if (sink == NULL);
145 fail_unless (gst_bin_add (GST_BIN (pipeline), src));
146 fail_unless (gst_bin_add (GST_BIN (pipeline), infilter));
147 fail_unless (gst_bin_add (GST_BIN (pipeline), deinterlace));
148 fail_unless (gst_bin_add (GST_BIN (pipeline), outfilter));
149 fail_unless (gst_bin_add (GST_BIN (pipeline), sink));
151 /* set the properties */
152 g_object_set (deinterlace, "mode", mode, NULL);
154 g_object_set (src, "num-buffers", numbuffers, NULL);
156 g_object_set (infilter, "caps", infiltercaps, NULL);
158 g_object_set (outfilter, "caps", outfiltercaps, NULL);
160 fail_unless (gst_element_link_many (src, infilter, deinterlace, outfilter,
163 gst_caps_unref (infiltercaps);
165 gst_caps_unref (outfiltercaps);
169 * Checks if 2 buffers are equal
171 * Equals means same caps and same data
174 test_buffer_equals (GstBuffer * buf_a, GstBuffer * buf_b)
179 if (GST_BUFFER_SIZE (buf_a) != GST_BUFFER_SIZE (buf_b))
182 caps_a = gst_buffer_get_caps (buf_a);
183 caps_b = gst_buffer_get_caps (buf_b);
185 if (!gst_caps_is_equal (caps_a, caps_b))
188 gst_caps_unref (caps_a);
189 gst_caps_unref (caps_b);
191 return memcmp (GST_BUFFER_DATA (buf_a), GST_BUFFER_DATA (buf_b),
192 GST_BUFFER_SIZE (buf_a)) == 0;
196 sinkpad_enqueue_buffer (GstPad * pad, GstBuffer * buf, gpointer data)
198 GQueue *queue = (GQueue *) data;
200 /* enqueue a copy for being compared later */
201 g_queue_push_tail (queue, gst_buffer_copy (buf));
207 * pad buffer probe that compares the buffer with the top one
208 * in the GQueue passed as the user data
211 srcpad_dequeue_and_compare_buffer (GstPad * pad, GstBuffer * buf, gpointer data)
213 GQueue *queue = (GQueue *) data;
214 GstBuffer *queue_buf;
216 queue_buf = (GstBuffer *) g_queue_pop_head (queue);
217 fail_if (queue_buf == NULL);
219 fail_unless (test_buffer_equals (buf, queue_buf));
221 gst_buffer_unref (queue_buf);
227 * Utility function that sets up a pipeline with deinterlace for
228 * validanting that it operates in passthrough mode when receiving
229 * data with 'infiltercaps' as the input caps and operating in 'mode' mode
232 deinterlace_check_passthrough (gint mode, const gchar * infiltercaps)
236 GstCaps *incaps = NULL;
239 incaps = gst_caps_from_string (infiltercaps);
241 setup_test_pipeline (mode, incaps, NULL, 20);
243 queue = g_queue_new ();
245 /* set up probes for testing */
246 gst_pad_add_buffer_probe (sinkpad, (GCallback) sinkpad_enqueue_buffer, queue);
247 gst_pad_add_buffer_probe (srcpad,
248 (GCallback) srcpad_dequeue_and_compare_buffer, queue);
250 fail_unless (gst_element_set_state (pipeline, GST_STATE_PLAYING) !=
251 GST_STATE_CHANGE_FAILURE);
253 msg = gst_bus_poll (GST_ELEMENT_BUS (pipeline), GST_MESSAGE_EOS, -1);
254 gst_message_unref (msg);
256 /* queue should be empty */
257 fail_unless (g_queue_is_empty (queue));
259 fail_unless (gst_element_set_state (pipeline, GST_STATE_NULL) ==
260 GST_STATE_CHANGE_SUCCESS);
261 gst_object_unref (pipeline);
262 g_queue_free (queue);
266 * Sets the caps on deinterlace sinkpad and validates the
267 * caps that is set on the srcpad
270 deinterlace_set_caps_and_check (GstCaps * input, gboolean must_deinterlace)
272 GstCaps *othercaps = NULL;
274 fail_unless (gst_pad_set_caps (sinkpad, input));
275 g_object_get (srcpad, "caps", &othercaps, NULL);
277 if (must_deinterlace) {
278 fail_if (gst_caps_is_interlaced (othercaps));
282 fail_unless (gst_caps_is_interlaced (input) ==
283 gst_caps_is_interlaced (othercaps));
285 othercaps = gst_caps_make_writable (othercaps);
286 s = gst_caps_get_structure (othercaps, 0);
287 gst_structure_remove_field (s, "interlaced");
289 input = gst_caps_make_writable (input);
290 s = gst_caps_get_structure (input, 0);
291 gst_structure_remove_field (s, "interlaced");
293 fail_unless (gst_caps_is_equal (input, othercaps));
295 gst_caps_unref (input);
296 gst_caps_unref (othercaps);
300 deinterlace_set_string_caps_and_check (const gchar * input,
301 gboolean must_deinterlace)
303 deinterlace_set_caps_and_check (gst_caps_from_string (input),
307 GST_START_TEST (test_mode_auto_accept_caps)
309 setup_deinterlace ();
312 g_object_set (deinterlace, "mode", 0, NULL);
313 fail_unless (gst_element_set_state (deinterlace, GST_STATE_PLAYING) ==
314 GST_STATE_CHANGE_SUCCESS);
316 /* try to set non interlaced caps */
317 deinterlace_set_string_caps_and_check (CAPS_YVYU, FALSE);
318 deinterlace_set_string_caps_and_check (CAPS_YUY2, FALSE);
319 deinterlace_set_string_caps_and_check (CAPS_YVYU_IMAGE, FALSE);
320 deinterlace_set_string_caps_and_check (CAPS_YUY2_IMAGE, FALSE);
322 /* now try to set interlaced caps */
323 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED, TRUE);
324 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED, TRUE);
325 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED_IMAGE, TRUE);
326 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED_IMAGE, TRUE);
329 gst_object_unref (sinkpad);
330 gst_object_unref (srcpad);
331 fail_unless (gst_element_set_state (deinterlace, GST_STATE_NULL) ==
332 GST_STATE_CHANGE_SUCCESS);
333 gst_object_unref (deinterlace);
338 GST_START_TEST (test_mode_forced_accept_caps)
340 setup_deinterlace ();
343 g_object_set (deinterlace, "mode", 1, NULL);
344 fail_unless (gst_element_set_state (deinterlace, GST_STATE_PLAYING) ==
345 GST_STATE_CHANGE_SUCCESS);
347 /* try to set non interlaced caps */
348 deinterlace_set_string_caps_and_check (CAPS_YVYU, TRUE);
349 deinterlace_set_string_caps_and_check (CAPS_YUY2, TRUE);
350 deinterlace_set_string_caps_and_check (CAPS_YVYU_IMAGE, TRUE);
351 deinterlace_set_string_caps_and_check (CAPS_YUY2_IMAGE, TRUE);
353 /* now try to set interlaced caps */
354 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED, TRUE);
355 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED, TRUE);
356 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED_IMAGE, TRUE);
357 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED_IMAGE, TRUE);
360 gst_object_unref (sinkpad);
361 gst_object_unref (srcpad);
362 fail_unless (gst_element_set_state (deinterlace, GST_STATE_NULL) ==
363 GST_STATE_CHANGE_SUCCESS);
364 gst_object_unref (deinterlace);
369 GST_START_TEST (test_mode_disabled_accept_caps)
371 setup_deinterlace ();
374 g_object_set (deinterlace, "mode", 2, NULL);
375 fail_unless (gst_element_set_state (deinterlace, GST_STATE_PLAYING) ==
376 GST_STATE_CHANGE_SUCCESS);
378 /* try to set non interlaced caps */
379 deinterlace_set_string_caps_and_check (CAPS_YVYU, FALSE);
380 deinterlace_set_string_caps_and_check (CAPS_YUY2, FALSE);
381 deinterlace_set_string_caps_and_check (CAPS_YVYU_IMAGE, FALSE);
382 deinterlace_set_string_caps_and_check (CAPS_YUY2_IMAGE, FALSE);
384 /* now try to set interlaced caps */
385 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED, FALSE);
386 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED, FALSE);
387 deinterlace_set_string_caps_and_check (CAPS_YVYU_INTERLACED_IMAGE, FALSE);
388 deinterlace_set_string_caps_and_check (CAPS_YUY2_INTERLACED_IMAGE, FALSE);
391 gst_object_unref (sinkpad);
392 gst_object_unref (srcpad);
393 fail_unless (gst_element_set_state (deinterlace, GST_STATE_NULL) ==
394 GST_STATE_CHANGE_SUCCESS);
395 gst_object_unref (deinterlace);
400 GST_START_TEST (test_mode_disabled_passthrough)
402 /* 2 is disabled mode */
403 deinterlace_check_passthrough (2, CAPS_YUY2_INTERLACED);
404 deinterlace_check_passthrough (2, CAPS_YVYU_INTERLACED);
405 deinterlace_check_passthrough (2, CAPS_YUY2);
406 deinterlace_check_passthrough (2, CAPS_YVYU);
408 deinterlace_check_passthrough (2, CAPS_YUY2_INTERLACED_IMAGE);
409 deinterlace_check_passthrough (2, CAPS_YVYU_INTERLACED_IMAGE);
410 deinterlace_check_passthrough (2, CAPS_YUY2_IMAGE);
411 deinterlace_check_passthrough (2, CAPS_YVYU_IMAGE);
416 GST_START_TEST (test_mode_auto_deinterlaced_passthrough)
419 deinterlace_check_passthrough (0, CAPS_YUY2);
420 deinterlace_check_passthrough (0, CAPS_YVYU);
421 deinterlace_check_passthrough (0, CAPS_YUY2_IMAGE);
422 deinterlace_check_passthrough (0, CAPS_YVYU_IMAGE);
428 deinterlace_suite (void)
430 Suite *s = suite_create ("deinterlace");
431 TCase *tc_chain = tcase_create ("general");
433 suite_add_tcase (s, tc_chain);
434 tcase_set_timeout (tc_chain, 180);
435 tcase_add_test (tc_chain, test_create_and_unref);
436 tcase_add_test (tc_chain, test_mode_auto_accept_caps);
437 tcase_add_test (tc_chain, test_mode_forced_accept_caps);
438 tcase_add_test (tc_chain, test_mode_disabled_accept_caps);
439 tcase_add_test (tc_chain, test_mode_disabled_passthrough);
440 tcase_add_test (tc_chain, test_mode_auto_deinterlaced_passthrough);
445 GST_CHECK_MAIN (deinterlace);