3 * unit test for videoscale
5 * Copyright (C) <2009,2010> Sebastian Dröge <sebastian.droege@collabora.co.uk>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
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 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #include <gst/video/video.h>
24 #include <gst/base/gstbasesink.h>
26 #include <gst/check/gstcheck.h>
29 /* kids, don't do this at home, skipping checks is *BAD* */
30 #define LINK_CHECK_FLAGS GST_PAD_LINK_CHECK_NOTHING
33 videoscale_get_allowed_caps_for_method (int method)
41 scale = gst_element_factory_make ("videoscale", "vscale");
42 g_object_set (scale, "method", method, NULL);
43 pad = gst_element_get_static_pad (scale, "sink");
44 caps = gst_pad_query_caps (pad, NULL);
45 gst_object_unref (pad);
46 gst_object_unref (scale);
48 caps = gst_caps_normalize (caps);
49 n = gst_caps_get_size (caps);
50 ret = g_new0 (GstCaps *, n + 1);
52 for (i = 0; i < n; i++) {
53 s = gst_caps_get_structure (caps, i);
54 ret[i] = gst_caps_new_empty ();
55 gst_caps_append_structure (ret[i], gst_structure_copy (s));
56 GST_LOG ("method %d supports: %" GST_PTR_FORMAT, method, s);
59 gst_caps_unref (caps);
65 on_sink_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad,
68 guint *n_buffers = user_data;
70 *n_buffers = *n_buffers + 1;
74 caps_is_supported (const GstCaps * caps)
80 GST_DEBUG ("have caps %" GST_PTR_FORMAT, caps);
82 s = gst_caps_get_structure (caps, 0);
83 format = gst_structure_get_string (s, "format");
84 fail_if (format == NULL);
86 fmt = gst_video_format_from_string (format);
87 fail_if (fmt == GST_VIDEO_FORMAT_UNKNOWN);
89 return (fmt == GST_VIDEO_FORMAT_ARGB64 || fmt == GST_VIDEO_FORMAT_AYUV64
90 || fmt == GST_VIDEO_FORMAT_GRAY8 || fmt == GST_VIDEO_FORMAT_GRAY16_BE
91 || fmt == GST_VIDEO_FORMAT_GRAY16_LE);
95 run_test (const GstCaps * caps, gint src_width, gint src_height,
96 gint dest_width, gint dest_height, gint method,
97 GCallback src_handoff, gpointer src_handoff_user_data,
98 GCallback sink_handoff, gpointer sink_handoff_user_data)
100 GstElement *pipeline;
101 GstElement *src, *videoconvert, *capsfilter1, *identity, *scale,
108 /* skip formats that videoconvert can't handle */
109 if (caps_is_supported (caps))
112 pipeline = gst_element_factory_make ("pipeline", "pipeline");
113 fail_unless (pipeline != NULL);
115 src = gst_element_factory_make ("videotestsrc", "src");
116 fail_unless (src != NULL);
117 g_object_set (G_OBJECT (src), "num-buffers", 1, NULL);
119 videoconvert = gst_element_factory_make ("videoconvert", "csp");
120 fail_unless (videoconvert != NULL);
122 capsfilter1 = gst_element_factory_make ("capsfilter", "filter1");
123 fail_unless (capsfilter1 != NULL);
124 copy = gst_caps_copy (caps);
125 gst_caps_set_simple (copy, "width", G_TYPE_INT, src_width, "height",
126 G_TYPE_INT, src_height, "framerate", GST_TYPE_FRACTION, 30, 1, NULL);
127 g_object_set (G_OBJECT (capsfilter1), "caps", copy, NULL);
128 gst_caps_unref (copy);
130 identity = gst_element_factory_make ("identity", "identity");
131 fail_unless (identity != NULL);
133 g_object_set (G_OBJECT (identity), "signal-handoffs", TRUE, NULL);
134 g_signal_connect (identity, "handoff", G_CALLBACK (src_handoff),
135 src_handoff_user_data);
138 scale = gst_element_factory_make ("videoscale", "scale");
139 fail_unless (scale != NULL);
140 g_object_set (G_OBJECT (scale), "method", method, NULL);
142 capsfilter2 = gst_element_factory_make ("capsfilter", "filter2");
143 fail_unless (capsfilter2 != NULL);
144 copy = gst_caps_copy (caps);
145 gst_caps_set_simple (copy, "width", G_TYPE_INT, dest_width, "height",
146 G_TYPE_INT, dest_height, NULL);
147 g_object_set (G_OBJECT (capsfilter2), "caps", copy, NULL);
148 gst_caps_unref (copy);
150 sink = gst_element_factory_make ("fakesink", "sink");
151 fail_unless (sink != NULL);
152 g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, "async", FALSE, NULL);
153 g_signal_connect (sink, "handoff", G_CALLBACK (on_sink_handoff), &n_buffers);
155 g_signal_connect (sink, "handoff", G_CALLBACK (sink_handoff),
156 sink_handoff_user_data);
159 gst_bin_add_many (GST_BIN (pipeline), src, videoconvert, capsfilter1,
160 identity, scale, capsfilter2, sink, NULL);
162 fail_unless (gst_element_link_pads_full (src, "src", videoconvert, "sink",
164 fail_unless (gst_element_link_pads_full (videoconvert, "src", capsfilter1,
165 "sink", LINK_CHECK_FLAGS));
166 fail_unless (gst_element_link_pads_full (capsfilter1, "src", identity, "sink",
168 fail_unless (gst_element_link_pads_full (identity, "src", scale, "sink",
170 fail_unless (gst_element_link_pads_full (scale, "src", capsfilter2, "sink",
172 fail_unless (gst_element_link_pads_full (capsfilter2, "src", sink, "sink",
175 bus = gst_element_get_bus (pipeline);
176 fail_unless (bus != NULL);
178 fail_unless (gst_element_set_state (pipeline,
179 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
181 msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
182 GST_MESSAGE_EOS | GST_MESSAGE_ERROR | GST_MESSAGE_WARNING);
184 fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_EOS);
186 fail_unless (gst_element_set_state (pipeline,
187 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
189 fail_unless (n_buffers == 1);
191 gst_object_unref (pipeline);
192 gst_message_unref (msg);
193 gst_object_unref (bus);
197 on_sink_handoff_passthrough (GstElement * element, GstBuffer * buffer,
198 GstPad * pad, gpointer user_data)
200 GList **list = user_data;
202 *list = g_list_prepend (*list, gst_buffer_ref (buffer));
206 on_src_handoff_passthrough (GstElement * element, GstBuffer * buffer,
209 GList **list = user_data;
211 *list = g_list_prepend (*list, gst_buffer_ref (buffer));
215 test_passthrough (int method)
217 GList *l1, *l2, *src_buffers = NULL, *sink_buffers = NULL;
218 GstCaps **allowed_caps = NULL, **p;
219 static const gint src_width = 640, src_height = 480;
220 static const gint dest_width = 640, dest_height = 480;
222 p = allowed_caps = videoscale_get_allowed_caps_for_method (method);
227 /* skip formats that videoconvert can't handle */
228 if (caps_is_supported (caps)) {
232 GST_DEBUG ("Running test for caps '%" GST_PTR_FORMAT "'"
233 " from %dx%u to %dx%d with method %d", caps, src_width, src_height,
234 dest_width, dest_height, method);
235 run_test (caps, src_width, src_height,
236 dest_width, dest_height, method,
237 G_CALLBACK (on_src_handoff_passthrough), &src_buffers,
238 G_CALLBACK (on_sink_handoff_passthrough), &sink_buffers);
240 fail_unless (src_buffers && sink_buffers);
241 fail_unless_equals_int (g_list_length (src_buffers),
242 g_list_length (sink_buffers));
244 for (l1 = src_buffers, l2 = sink_buffers; l1 && l2;
245 l1 = l1->next, l2 = l2->next) {
246 GstBuffer *a = l1->data;
247 GstBuffer *b = l2->data;
248 GstMapInfo mapa, mapb;
250 gst_buffer_map (a, &mapa, GST_MAP_READ);
251 gst_buffer_map (b, &mapb, GST_MAP_READ);
252 fail_unless_equals_int (mapa.size, mapb.size);
253 fail_unless (mapa.data == mapb.data);
254 gst_buffer_unmap (b, &mapb);
255 gst_buffer_unmap (a, &mapa);
257 gst_buffer_unref (a);
258 gst_buffer_unref (b);
260 g_list_free (src_buffers);
262 g_list_free (sink_buffers);
266 gst_caps_unref (caps);
269 g_free (allowed_caps);
272 GST_START_TEST (test_passthrough_method_0)
274 test_passthrough (0);
279 GST_START_TEST (test_passthrough_method_1)
281 test_passthrough (1);
286 GST_START_TEST (test_passthrough_method_2)
288 test_passthrough (2);
293 GST_START_TEST (test_passthrough_method_3)
295 test_passthrough (3);
300 #define CREATE_TEST(name,method,src_width,src_height,dest_width,dest_height) \
301 GST_START_TEST (name) \
303 GstCaps **allowed_caps = NULL, **p; \
305 p = allowed_caps = videoscale_get_allowed_caps_for_method (method); \
308 GstCaps *caps = *p; \
310 GST_DEBUG ("Running test for caps '%" GST_PTR_FORMAT "'" \
311 " from %dx%u to %dx%d with method %d", caps, src_width, src_height, \
312 dest_width, dest_height, method); \
313 run_test (caps, src_width, src_height, \
314 dest_width, dest_height, method, \
315 NULL, NULL, NULL, NULL); \
316 gst_caps_unref (caps); \
319 g_free (allowed_caps); \
324 CREATE_TEST (test_downscale_640x480_320x240_method_0, 0, 640, 480, 320, 240);
325 CREATE_TEST (test_downscale_640x480_320x240_method_1, 1, 640, 480, 320, 240);
326 CREATE_TEST (test_downscale_640x480_320x240_method_2, 2, 640, 480, 320, 240);
327 CREATE_TEST (test_downscale_640x480_320x240_method_3, 3, 640, 480, 320, 240);
328 CREATE_TEST (test_upscale_320x240_640x480_method_0, 0, 320, 240, 640, 480);
329 CREATE_TEST (test_upscale_320x240_640x480_method_1, 1, 320, 240, 640, 480);
330 CREATE_TEST (test_upscale_320x240_640x480_method_2, 2, 320, 240, 640, 480);
331 CREATE_TEST (test_upscale_320x240_640x480_method_3, 3, 320, 240, 640, 480);
332 CREATE_TEST (test_downscale_640x480_1x1_method_0, 0, 640, 480, 1, 1);
333 CREATE_TEST (test_downscale_640x480_1x1_method_1, 1, 640, 480, 1, 1);
334 CREATE_TEST (test_downscale_640x480_1x1_method_2, 2, 640, 480, 1, 1);
335 CREATE_TEST (test_downscale_640x480_1x1_method_3, 3, 640, 480, 1, 1);
336 CREATE_TEST (test_upscale_1x1_640x480_method_0, 0, 1, 1, 640, 480);
337 CREATE_TEST (test_upscale_1x1_640x480_method_1, 1, 1, 1, 640, 480);
338 CREATE_TEST (test_upscale_1x1_640x480_method_2, 2, 1, 1, 640, 480);
339 CREATE_TEST (test_upscale_1x1_640x480_method_3, 3, 1, 1, 640, 480);
340 CREATE_TEST (test_downscale_641x481_111x30_method_0, 0, 641, 481, 111, 30);
341 CREATE_TEST (test_downscale_641x481_111x30_method_1, 1, 641, 481, 111, 30);
342 CREATE_TEST (test_downscale_641x481_111x30_method_2, 2, 641, 481, 111, 30);
343 CREATE_TEST (test_downscale_641x481_111x30_method_3, 3, 641, 481, 111, 30);
344 CREATE_TEST (test_upscale_111x30_641x481_method_0, 0, 111, 30, 641, 481);
345 CREATE_TEST (test_upscale_111x30_641x481_method_1, 1, 111, 30, 641, 481);
346 CREATE_TEST (test_upscale_111x30_641x481_method_2, 2, 111, 30, 641, 481);
347 CREATE_TEST (test_upscale_111x30_641x481_method_3, 2, 111, 30, 641, 481);
348 CREATE_TEST (test_downscale_641x481_30x111_method_0, 0, 641, 481, 30, 111);
349 CREATE_TEST (test_downscale_641x481_30x111_method_1, 1, 641, 481, 30, 111);
350 CREATE_TEST (test_downscale_641x481_30x111_method_2, 2, 641, 481, 30, 111);
351 CREATE_TEST (test_downscale_641x481_30x111_method_3, 3, 641, 481, 30, 111);
352 CREATE_TEST (test_upscale_30x111_641x481_method_0, 0, 30, 111, 641, 481);
353 CREATE_TEST (test_upscale_30x111_641x481_method_1, 1, 30, 111, 641, 481);
354 CREATE_TEST (test_upscale_30x111_641x481_method_2, 2, 30, 111, 641, 481);
355 CREATE_TEST (test_upscale_30x111_641x481_method_3, 3, 30, 111, 641, 481);
356 CREATE_TEST (test_downscale_640x480_320x1_method_0, 0, 640, 480, 320, 1);
357 CREATE_TEST (test_downscale_640x480_320x1_method_1, 1, 640, 480, 320, 1);
358 CREATE_TEST (test_downscale_640x480_320x1_method_2, 2, 640, 480, 320, 1);
359 CREATE_TEST (test_downscale_640x480_320x1_method_3, 3, 640, 480, 320, 1);
360 CREATE_TEST (test_upscale_320x1_640x480_method_0, 0, 320, 1, 640, 480);
361 CREATE_TEST (test_upscale_320x1_640x480_method_1, 1, 320, 1, 640, 480);
362 CREATE_TEST (test_upscale_320x1_640x480_method_2, 2, 320, 1, 640, 480);
363 CREATE_TEST (test_upscale_320x1_640x480_method_3, 3, 320, 1, 640, 480);
364 CREATE_TEST (test_downscale_640x480_1x240_method_0, 0, 640, 480, 1, 240);
365 CREATE_TEST (test_downscale_640x480_1x240_method_1, 1, 640, 480, 1, 240);
366 CREATE_TEST (test_downscale_640x480_1x240_method_2, 2, 640, 480, 1, 240);
367 CREATE_TEST (test_downscale_640x480_1x240_method_3, 3, 640, 480, 1, 240);
368 CREATE_TEST (test_upscale_1x240_640x480_method_0, 0, 1, 240, 640, 480);
369 CREATE_TEST (test_upscale_1x240_640x480_method_1, 1, 1, 240, 640, 480);
370 CREATE_TEST (test_upscale_1x240_640x480_method_2, 2, 1, 240, 640, 480);
371 CREATE_TEST (test_upscale_1x240_640x480_method_3, 3, 1, 240, 640, 480);
379 } TestNegotiationData;
382 _test_negotiation_message (GstBus * bus, GstMessage * message,
383 TestNegotiationData * data)
388 switch (GST_MESSAGE_TYPE (message)) {
389 case GST_MESSAGE_ERROR:
390 gst_message_parse_error (message, &err, &debug);
391 gst_object_default_error (GST_MESSAGE_SRC (message), err, debug);
394 g_assert_not_reached ();
396 case GST_MESSAGE_WARNING:
397 gst_message_parse_warning (message, &err, &debug);
398 gst_object_default_error (GST_MESSAGE_SRC (message), err, debug);
401 g_assert_not_reached ();
403 case GST_MESSAGE_EOS:
404 g_main_loop_quit (data->loop);
412 _test_negotiation_notify_caps (GObject * src, GParamSpec * pspec,
413 TestNegotiationData * data)
418 gint par_n = 0, par_d = 0;
420 g_object_get (src, "caps", &caps, NULL);
424 s = gst_caps_get_structure (caps, 0);
426 fail_unless (gst_structure_get_int (s, "width", &width));
427 fail_unless (gst_structure_get_int (s, "height", &height));
428 fail_unless (gst_structure_get_fraction (s, "pixel-aspect-ratio", &par_n,
429 &par_d) || (data->par_n == 1 && data->par_d == 1));
431 gst_caps_unref (caps);
433 fail_unless_equals_int (width, data->width);
434 fail_unless_equals_int (height, data->height);
435 if (par_n != 0 || par_d != 0) {
436 fail_unless_equals_int (par_n, data->par_n);
437 fail_unless_equals_int (par_d, data->par_d);
440 data->ok = (width == data->width) && (height == data->height)
441 && (par_n == data->par_n) && (par_d == data->par_d);
443 g_main_loop_quit (data->loop);
447 _test_negotiation (const gchar * src_templ, const gchar * sink_templ,
448 gint width, gint height, gint par_n, gint par_d)
450 GstElement *pipeline;
451 GstElement *src, *capsfilter1, *scale, *capsfilter2, *sink;
455 TestNegotiationData data = { 0, 0, 0, 0, FALSE, NULL };
458 GST_DEBUG ("Running test for src templ caps '%s' and sink templ caps '%s'",
459 src_templ, sink_templ);
461 pipeline = gst_element_factory_make ("pipeline", "pipeline");
462 fail_unless (pipeline != NULL);
464 src = gst_element_factory_make ("videotestsrc", "src");
465 fail_unless (src != NULL);
466 g_object_set (G_OBJECT (src), "num-buffers", 1, NULL);
468 capsfilter1 = gst_element_factory_make ("capsfilter", "filter1");
469 fail_unless (capsfilter1 != NULL);
470 caps = gst_caps_from_string (src_templ);
471 fail_unless (caps != NULL);
472 g_object_set (G_OBJECT (capsfilter1), "caps", caps, NULL);
473 gst_caps_unref (caps);
475 scale = gst_element_factory_make ("videoscale", "scale");
476 fail_unless (scale != NULL);
478 capsfilter2 = gst_element_factory_make ("capsfilter", "filter2");
479 fail_unless (capsfilter2 != NULL);
480 caps = gst_caps_from_string (sink_templ);
481 fail_unless (caps != NULL);
482 g_object_set (G_OBJECT (capsfilter2), "caps", caps, NULL);
483 gst_caps_unref (caps);
485 pad = gst_element_get_static_pad (capsfilter2, "sink");
486 fail_unless (pad != NULL);
487 g_signal_connect (pad, "notify::caps",
488 G_CALLBACK (_test_negotiation_notify_caps), &data);
489 gst_object_unref (pad);
491 sink = gst_element_factory_make ("fakesink", "sink");
492 fail_unless (sink != NULL);
493 g_object_set (sink, "async", FALSE, NULL);
495 gst_bin_add_many (GST_BIN (pipeline), src, capsfilter1, scale, capsfilter2,
498 fail_unless (gst_element_link_pads_full (src, "src", capsfilter1, "sink",
500 fail_unless (gst_element_link_pads_full (capsfilter1, "src", scale, "sink",
502 fail_unless (gst_element_link_pads_full (scale, "src", capsfilter2, "sink",
504 fail_unless (gst_element_link_pads_full (capsfilter2, "src", sink, "sink",
507 loop = g_main_loop_new (NULL, FALSE);
509 bus = gst_element_get_bus (pipeline);
510 fail_unless (bus != NULL);
511 gst_bus_add_signal_watch (bus);
515 data.height = height;
520 g_signal_connect (bus, "message", G_CALLBACK (_test_negotiation_message),
523 gst_object_unref (bus);
525 fail_unless (gst_element_set_state (pipeline,
526 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
528 g_main_loop_run (loop);
530 fail_unless (data.ok == TRUE);
532 fail_unless (gst_element_set_state (pipeline,
533 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
535 gst_object_unref (pipeline);
536 g_main_loop_unref (loop);
539 GST_START_TEST (test_negotiation)
542 ("video/x-raw,format=(string)AYUV,width=720,height=576,pixel-aspect-ratio=16/15",
543 "video/x-raw,format=(string)AYUV,width=768,height=576", 768, 576, 1, 1);
546 ("video/x-raw,format=(string)AYUV,width=320,height=240",
547 "video/x-raw,format=(string)AYUV,width=640,height=320", 640, 320, 2, 3);
550 ("video/x-raw,format=(string)AYUV,width=320,height=240",
551 "video/x-raw,format=(string)AYUV,width=640,height=320,pixel-aspect-ratio=[0/1, 1/1]",
555 ("video/x-raw,format=(string)AYUV,width=1920,height=2560,pixel-aspect-ratio=1/1",
556 "video/x-raw,format=(string)AYUV,width=[1, 2048],height=[1, 2048],pixel-aspect-ratio=1/1",
560 ("video/x-raw,format=(string)AYUV,width=1920,height=2560,pixel-aspect-ratio=1/1",
561 "video/x-raw,format=(string)AYUV,width=[1, 2048],height=[1, 2048]",
565 ("video/x-raw,format=(string)AYUV,width=1920,height=2560",
566 "video/x-raw,format=(string)AYUV,width=[1, 2048],height=[1, 2048]",
570 ("video/x-raw,format=(string)AYUV,width=1920,height=2560",
571 "video/x-raw,format=(string)AYUV,width=1200,height=[1, 2048],pixel-aspect-ratio=1/1",
574 /* Doesn't keep DAR but must be possible! */
576 ("video/x-raw,format=(string)AYUV,width=320,height=240,pixel-aspect-ratio=1/1",
577 "video/x-raw,format=(string)AYUV,width=200,height=200,pixel-aspect-ratio=1/2",
583 #define GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK \
584 (gst_test_reverse_negotiation_sink_get_type())
585 #define GST_TEST_REVERSE_NEGOTIATION_SINK(obj) \
586 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK,GstTestReverseNegotiationSink))
587 #define GST_TEST_REVERSE_NEGOTIATION_SINK_CLASS(klass) \
588 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK,GstTestReverseNegotiationSinkClass))
589 #define GST_IS_TEST_REVERSE_NEGOTIATION_SINK(obj) \
590 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK))
591 #define GST_IS_TEST_REVERSE_NEGOTIATION_SINK_CLASS(klass) \
592 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK))
593 #define GST_TEST_REVERSE_NEGOTIATION_SINK_CAST(obj) ((GstTestReverseNegotiationSink *)obj)
595 typedef struct _GstTestReverseNegotiationSink GstTestReverseNegotiationSink;
596 typedef struct _GstTestReverseNegotiationSinkClass
597 GstTestReverseNegotiationSinkClass;
598 struct _GstTestReverseNegotiationSink
604 struct _GstTestReverseNegotiationSinkClass
606 GstBaseSinkClass parent_class;
609 GType gst_test_reverse_negotiation_sink_get_type (void);
611 G_DEFINE_TYPE (GstTestReverseNegotiationSink,
612 gst_test_reverse_negotiation_sink, GST_TYPE_BASE_SINK);
614 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
617 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("xRGB")));
621 gst_test_reverse_negotiation_sink_buffer_alloc (GstBaseSink * bsink,
622 guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf)
624 GstTestReverseNegotiationSink *sink =
625 GST_TEST_REVERSE_NEGOTIATION_SINK (bsink);
629 fail_unless (gst_video_format_parse_caps (caps, &fmt, &width, &height));
631 if (sink->nbuffers < 2) {
633 gst_buffer_new_and_alloc (gst_video_format_get_size (fmt, width,
635 gst_buffer_set_caps (*buf, caps);
639 fail_unless (gst_video_parse_caps_framerate (caps, &fps_n, &fps_d));
644 gst_buffer_new_and_alloc (gst_video_format_get_size (fmt, width,
646 caps = gst_video_format_new_caps (fmt, width, height, fps_n, fps_d, 1, 1);
647 gst_buffer_set_caps (*buf, caps);
648 gst_caps_unref (caps);
656 gst_test_reverse_negotiation_sink_render (GstBaseSink * bsink,
659 GstTestReverseNegotiationSink *sink =
660 GST_TEST_REVERSE_NEGOTIATION_SINK (bsink);
664 caps = gst_pad_get_current_caps (GST_BASE_SINK_PAD (bsink));
666 fail_unless (caps != NULL);
667 fail_unless (gst_video_info_from_caps (&info, caps));
671 /* The third buffer is still in the old size
672 * because the videoconverts can't convert
675 if (sink->nbuffers > 3) {
676 fail_unless_equals_int (GST_VIDEO_INFO_WIDTH (&info), 512);
677 fail_unless_equals_int (GST_VIDEO_INFO_HEIGHT (&info), 128);
680 gst_caps_unref (caps);
686 gst_test_reverse_negotiation_sink_class_init (GstTestReverseNegotiationSinkClass
689 GstElementClass *gstelement_class;
690 GstBaseSinkClass *gstbase_sink_class;
692 gstelement_class = GST_ELEMENT_CLASS (klass);
693 gstbase_sink_class = GST_BASE_SINK_CLASS (klass);
695 gst_element_class_set_details_simple (gstelement_class,
696 "Test Reverse Negotiation Sink",
698 "Some test sink", "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
699 gst_element_class_add_pad_template (gstelement_class,
700 gst_static_pad_template_get (&sinktemplate));
703 gstbase_sink_class->buffer_alloc =
704 GST_DEBUG_FUNCPTR (gst_test_reverse_negotiation_sink_buffer_alloc);
706 gstbase_sink_class->render =
707 GST_DEBUG_FUNCPTR (gst_test_reverse_negotiation_sink_render);
711 gst_test_reverse_negotiation_sink_init (GstTestReverseNegotiationSink * sink)
718 _test_reverse_negotiation_message (GstBus * bus, GstMessage * message,
724 switch (GST_MESSAGE_TYPE (message)) {
725 case GST_MESSAGE_ERROR:
726 gst_message_parse_error (message, &err, &debug);
727 gst_object_default_error (GST_MESSAGE_SRC (message), err, debug);
730 g_assert_not_reached ();
732 case GST_MESSAGE_WARNING:
733 gst_message_parse_warning (message, &err, &debug);
734 gst_object_default_error (GST_MESSAGE_SRC (message), err, debug);
737 g_assert_not_reached ();
739 case GST_MESSAGE_EOS:
740 g_main_loop_quit (loop);
749 GST_START_TEST (test_reverse_negotiation)
751 GstElement *pipeline;
752 GstElement *src, *csp1, *scale, *csp2, *sink;
756 pipeline = gst_element_factory_make ("pipeline", "pipeline");
757 fail_unless (pipeline != NULL);
759 src = gst_element_factory_make ("videotestsrc", "src");
760 fail_unless (src != NULL);
761 g_object_set (G_OBJECT (src), "num-buffers", 8, NULL);
763 csp1 = gst_element_factory_make ("videoconvert", "csp1");
764 fail_unless (csp1 != NULL);
766 scale = gst_element_factory_make ("videoscale", "scale");
767 fail_unless (scale != NULL);
769 csp2 = gst_element_factory_make ("videoconvert", "csp2");
770 fail_unless (csp2 != NULL);
772 sink = g_object_new (GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK, NULL);
773 fail_unless (sink != NULL);
774 g_object_set (sink, "async", FALSE, NULL);
776 gst_bin_add_many (GST_BIN (pipeline), src, csp1, scale, csp2, sink, NULL);
778 fail_unless (gst_element_link_pads_full (src, "src", csp1, "sink",
780 fail_unless (gst_element_link_pads_full (csp1, "src", scale, "sink",
782 fail_unless (gst_element_link_pads_full (scale, "src", csp2, "sink",
784 fail_unless (gst_element_link_pads_full (csp2, "src", sink, "sink",
787 loop = g_main_loop_new (NULL, FALSE);
789 bus = gst_element_get_bus (pipeline);
790 fail_unless (bus != NULL);
791 gst_bus_add_signal_watch (bus);
793 g_signal_connect (bus, "message",
794 G_CALLBACK (_test_reverse_negotiation_message), loop);
796 gst_object_unref (bus);
798 fail_unless (gst_element_set_state (pipeline,
799 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
801 g_main_loop_run (loop);
803 fail_unless (gst_element_set_state (pipeline,
804 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
806 gst_object_unref (pipeline);
807 g_main_loop_unref (loop);
813 GST_START_TEST (test_basetransform_negotiation)
815 GstElement *pipeline, *src, *sink, *scale, *capsfilter1, *capsfilter2;
819 pipeline = gst_pipeline_new (NULL);
820 src = gst_element_factory_make ("videotestsrc", NULL);
821 capsfilter1 = gst_element_factory_make ("capsfilter", NULL);
822 scale = gst_element_factory_make ("videoscale", NULL);
823 capsfilter2 = gst_element_factory_make ("capsfilter", NULL);
824 sink = gst_element_factory_make ("fakesink", NULL);
825 fail_unless (pipeline && src && capsfilter1 && scale && capsfilter2 && sink);
827 g_object_set (src, "num-buffers", 3, NULL);
829 caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING,
830 "UYVY", "width", G_TYPE_INT, 352,
831 "height", G_TYPE_INT, 288, "framerate", GST_TYPE_FRACTION, 30, 1,
832 "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL);
833 g_object_set (capsfilter1, "caps", caps, NULL);
834 gst_caps_unref (caps);
836 /* same caps, just different pixel-aspect-ratio */
837 caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING,
838 "UYVY", "width", G_TYPE_INT, 352,
839 "height", G_TYPE_INT, 288, "framerate", GST_TYPE_FRACTION, 30, 1,
840 "pixel-aspect-ratio", GST_TYPE_FRACTION, 12, 11, NULL);
841 g_object_set (capsfilter2, "caps", caps, NULL);
842 gst_caps_unref (caps);
844 gst_bin_add_many (GST_BIN (pipeline), src, capsfilter1, scale, capsfilter2,
846 fail_unless (gst_element_link_many (src, capsfilter1, scale, capsfilter2,
849 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
850 GST_STATE_CHANGE_ASYNC);
852 msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipeline), -1,
853 GST_MESSAGE_EOS | GST_MESSAGE_ERROR);
854 fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_EOS);
855 gst_message_unref (msg);
857 gst_element_set_state (pipeline, GST_STATE_NULL);
858 gst_object_unref (pipeline);
863 #ifndef tcase_skip_broken_test
864 #define tcase_skip_broken_test(chain,test_func) \
865 if (0) { tcase_add_test(chain,test_func); } else { \
866 GST_ERROR ("FIXME: skipping test %s because it's broken.", G_STRINGIFY (test_func)); \
871 videoscale_suite (void)
873 Suite *s = suite_create ("videoscale");
874 TCase *tc_chain = tcase_create ("general");
876 suite_add_tcase (s, tc_chain);
877 tcase_set_timeout (tc_chain, 180);
878 tcase_add_test (tc_chain, test_passthrough_method_0);
879 tcase_add_test (tc_chain, test_passthrough_method_1);
880 tcase_add_test (tc_chain, test_passthrough_method_2);
881 tcase_add_test (tc_chain, test_passthrough_method_3);
882 tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_0);
883 tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_1);
884 tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_2);
885 tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_3);
886 tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_0);
887 tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_1);
888 tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_2);
889 tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_3);
890 tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_0);
891 tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_1);
892 tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_2);
893 tcase_skip_broken_test (tc_chain, test_downscale_640x480_1x1_method_3);
894 tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_0);
895 tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_1);
896 tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_2);
897 tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_3);
898 tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_0);
899 tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_1);
900 tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_2);
901 tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_3);
902 tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_0);
903 tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_1);
904 tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_2);
905 tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_3);
906 tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_0);
907 tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_1);
908 tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_2);
909 tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_3);
910 tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_0);
911 tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_1);
912 tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_2);
913 tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_3);
914 tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_0);
915 tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_1);
916 tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_2);
917 tcase_skip_broken_test (tc_chain, test_downscale_640x480_320x1_method_3);
918 tcase_add_test (tc_chain, test_upscale_320x1_640x480_method_0);
919 tcase_add_test (tc_chain, test_upscale_320x1_640x480_method_1);
920 tcase_add_test (tc_chain, test_upscale_320x1_640x480_method_2);
921 tcase_skip_broken_test (tc_chain, test_upscale_320x1_640x480_method_3);
922 tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_0);
923 tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_1);
924 tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_2);
925 tcase_skip_broken_test (tc_chain, test_downscale_640x480_1x240_method_3);
926 tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_0);
927 tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_1);
928 tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_2);
929 tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_3);
930 tcase_add_test (tc_chain, test_negotiation);
932 tcase_add_test (tc_chain, test_reverse_negotiation);
934 tcase_add_test (tc_chain, test_basetransform_negotiation);
936 GST_ERROR ("FIXME: test 64-bpp formats as well");
940 GST_CHECK_MAIN (videoscale);