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 n = gst_caps_get_size (caps);
49 ret = g_new0 (GstCaps *, n + 1);
51 for (i = 0; i < n; i++) {
52 s = gst_caps_get_structure (caps, i);
53 ret[i] = gst_caps_new_empty ();
54 gst_caps_append_structure (ret[i], gst_structure_copy (s));
55 GST_LOG ("method %d supports: %" GST_PTR_FORMAT, method, s);
58 gst_caps_unref (caps);
64 on_sink_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad,
67 guint *n_buffers = user_data;
69 *n_buffers = *n_buffers + 1;
73 caps_is_supported (const GstCaps * caps)
79 GST_DEBUG ("have caps %" GST_PTR_FORMAT, caps);
81 s = gst_caps_get_structure (caps, 0);
82 format = gst_structure_get_string (s, "format");
83 fail_if (format == NULL);
85 fmt = gst_video_format_from_string (format);
86 fail_if (fmt == GST_VIDEO_FORMAT_UNKNOWN);
88 return (fmt == GST_VIDEO_FORMAT_ARGB64 || fmt == GST_VIDEO_FORMAT_AYUV64
89 || fmt == GST_VIDEO_FORMAT_GRAY8 || fmt == GST_VIDEO_FORMAT_GRAY16_BE
90 || GST_VIDEO_FORMAT_GRAY16_LE);
94 run_test (const GstCaps * caps, gint src_width, gint src_height,
95 gint dest_width, gint dest_height, gint method,
96 GCallback src_handoff, gpointer src_handoff_user_data,
97 GCallback sink_handoff, gpointer sink_handoff_user_data)
100 GstElement *src, *videoconvert, *capsfilter1, *identity, *scale,
107 /* skip formats that videoconvert can't handle */
108 if (caps_is_supported (caps))
111 pipeline = gst_element_factory_make ("pipeline", "pipeline");
112 fail_unless (pipeline != NULL);
114 src = gst_element_factory_make ("videotestsrc", "src");
115 fail_unless (src != NULL);
116 g_object_set (G_OBJECT (src), "num-buffers", 1, NULL);
118 videoconvert = gst_element_factory_make ("videoconvert", "csp");
119 fail_unless (videoconvert != NULL);
121 capsfilter1 = gst_element_factory_make ("capsfilter", "filter1");
122 fail_unless (capsfilter1 != NULL);
123 copy = gst_caps_copy (caps);
124 gst_caps_set_simple (copy, "width", G_TYPE_INT, src_width, "height",
125 G_TYPE_INT, src_height, "framerate", GST_TYPE_FRACTION, 30, 1, NULL);
126 g_object_set (G_OBJECT (capsfilter1), "caps", copy, NULL);
127 gst_caps_unref (copy);
129 identity = gst_element_factory_make ("identity", "identity");
130 fail_unless (identity != NULL);
132 g_object_set (G_OBJECT (identity), "signal-handoffs", TRUE, NULL);
133 g_signal_connect (identity, "handoff", G_CALLBACK (src_handoff),
134 src_handoff_user_data);
137 scale = gst_element_factory_make ("videoscale", "scale");
138 fail_unless (scale != NULL);
139 g_object_set (G_OBJECT (scale), "method", method, NULL);
141 capsfilter2 = gst_element_factory_make ("capsfilter", "filter2");
142 fail_unless (capsfilter2 != NULL);
143 copy = gst_caps_copy (caps);
144 gst_caps_set_simple (copy, "width", G_TYPE_INT, dest_width, "height",
145 G_TYPE_INT, dest_height, NULL);
146 g_object_set (G_OBJECT (capsfilter2), "caps", copy, NULL);
147 gst_caps_unref (copy);
149 sink = gst_element_factory_make ("fakesink", "sink");
150 fail_unless (sink != NULL);
151 g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, "async", FALSE, NULL);
152 g_signal_connect (sink, "handoff", G_CALLBACK (on_sink_handoff), &n_buffers);
154 g_signal_connect (sink, "handoff", G_CALLBACK (sink_handoff),
155 sink_handoff_user_data);
158 gst_bin_add_many (GST_BIN (pipeline), src, videoconvert, capsfilter1,
159 identity, scale, capsfilter2, sink, NULL);
161 fail_unless (gst_element_link_pads_full (src, "src", videoconvert, "sink",
163 fail_unless (gst_element_link_pads_full (videoconvert, "src", capsfilter1,
164 "sink", LINK_CHECK_FLAGS));
165 fail_unless (gst_element_link_pads_full (capsfilter1, "src", identity, "sink",
167 fail_unless (gst_element_link_pads_full (identity, "src", scale, "sink",
169 fail_unless (gst_element_link_pads_full (scale, "src", capsfilter2, "sink",
171 fail_unless (gst_element_link_pads_full (capsfilter2, "src", sink, "sink",
174 bus = gst_element_get_bus (pipeline);
175 fail_unless (bus != NULL);
177 fail_unless (gst_element_set_state (pipeline,
178 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
180 msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
181 GST_MESSAGE_EOS | GST_MESSAGE_ERROR | GST_MESSAGE_WARNING);
183 fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_EOS);
185 fail_unless (gst_element_set_state (pipeline,
186 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
188 fail_unless (n_buffers == 1);
190 gst_object_unref (pipeline);
191 gst_message_unref (msg);
192 gst_object_unref (bus);
196 on_sink_handoff_passthrough (GstElement * element, GstBuffer * buffer,
197 GstPad * pad, gpointer user_data)
199 GList **list = user_data;
201 *list = g_list_prepend (*list, gst_buffer_ref (buffer));
205 on_src_handoff_passthrough (GstElement * element, GstBuffer * buffer,
208 GList **list = user_data;
210 *list = g_list_prepend (*list, gst_buffer_ref (buffer));
214 test_passthrough (int method)
216 GList *l1, *l2, *src_buffers = NULL, *sink_buffers = NULL;
217 GstCaps **allowed_caps = NULL, **p;
218 static const gint src_width = 640, src_height = 480;
219 static const gint dest_width = 640, dest_height = 480;
221 p = allowed_caps = videoscale_get_allowed_caps_for_method (method);
226 for (method = 0; method < 3; method++) {
227 /* skip formats that videoconvert can't handle */
228 if (caps_is_supported (caps))
231 GST_DEBUG ("Running test for caps '%" GST_PTR_FORMAT "'"
232 " from %dx%u to %dx%d with method %d", caps, src_width, src_height,
233 dest_width, dest_height, method);
234 run_test (caps, src_width, src_height,
235 dest_width, dest_height, method,
236 G_CALLBACK (on_src_handoff_passthrough), &src_buffers,
237 G_CALLBACK (on_sink_handoff_passthrough), &sink_buffers);
239 fail_unless (src_buffers && sink_buffers);
240 fail_unless_equals_int (g_list_length (src_buffers),
241 g_list_length (sink_buffers));
243 for (l1 = src_buffers, l2 = sink_buffers; l1 && l2;
244 l1 = l1->next, l2 = l2->next) {
245 GstBuffer *a = l1->data;
246 GstBuffer *b = l2->data;
247 GstMapInfo mapa, mapb;
249 gst_buffer_map (a, &mapa, GST_MAP_READ);
250 gst_buffer_map (b, &mapb, GST_MAP_READ);
251 fail_unless_equals_int (mapa.size, mapb.size);
252 fail_unless (mapa.data == mapb.data);
253 gst_buffer_unmap (b, &mapb);
254 gst_buffer_unmap (a, &mapa);
256 gst_buffer_unref (a);
257 gst_buffer_unref (b);
259 g_list_free (src_buffers);
261 g_list_free (sink_buffers);
264 gst_caps_unref (caps);
267 g_free (allowed_caps);
270 GST_START_TEST (test_passthrough_method_0)
272 test_passthrough (0);
277 GST_START_TEST (test_passthrough_method_1)
279 test_passthrough (1);
284 GST_START_TEST (test_passthrough_method_2)
286 test_passthrough (2);
291 GST_START_TEST (test_passthrough_method_3)
293 test_passthrough (3);
298 #define CREATE_TEST(name,method,src_width,src_height,dest_width,dest_height) \
299 GST_START_TEST (name) \
301 GstCaps **allowed_caps = NULL, **p; \
303 p = allowed_caps = videoscale_get_allowed_caps_for_method (method); \
306 GstCaps *caps = *p; \
308 GST_DEBUG ("Running test for caps '%" GST_PTR_FORMAT "'" \
309 " from %dx%u to %dx%d with method %d", caps, src_width, src_height, \
310 dest_width, dest_height, method); \
311 run_test (caps, src_width, src_height, \
312 dest_width, dest_height, method, \
313 NULL, NULL, NULL, NULL); \
314 gst_caps_unref (caps); \
317 g_free (allowed_caps); \
322 CREATE_TEST (test_downscale_640x480_320x240_method_0, 0, 640, 480, 320, 240);
323 CREATE_TEST (test_downscale_640x480_320x240_method_1, 1, 640, 480, 320, 240);
324 CREATE_TEST (test_downscale_640x480_320x240_method_2, 2, 640, 480, 320, 240);
325 CREATE_TEST (test_downscale_640x480_320x240_method_3, 3, 640, 480, 320, 240);
326 CREATE_TEST (test_upscale_320x240_640x480_method_0, 0, 320, 240, 640, 480);
327 CREATE_TEST (test_upscale_320x240_640x480_method_1, 1, 320, 240, 640, 480);
328 CREATE_TEST (test_upscale_320x240_640x480_method_2, 2, 320, 240, 640, 480);
329 CREATE_TEST (test_upscale_320x240_640x480_method_3, 3, 320, 240, 640, 480);
330 CREATE_TEST (test_downscale_640x480_1x1_method_0, 0, 640, 480, 1, 1);
331 CREATE_TEST (test_downscale_640x480_1x1_method_1, 1, 640, 480, 1, 1);
332 CREATE_TEST (test_downscale_640x480_1x1_method_2, 2, 640, 480, 1, 1);
333 CREATE_TEST (test_downscale_640x480_1x1_method_3, 3, 640, 480, 1, 1);
334 CREATE_TEST (test_upscale_1x1_640x480_method_0, 0, 1, 1, 640, 480);
335 CREATE_TEST (test_upscale_1x1_640x480_method_1, 1, 1, 1, 640, 480);
336 CREATE_TEST (test_upscale_1x1_640x480_method_2, 2, 1, 1, 640, 480);
337 CREATE_TEST (test_upscale_1x1_640x480_method_3, 3, 1, 1, 640, 480);
338 CREATE_TEST (test_downscale_641x481_111x30_method_0, 0, 641, 481, 111, 30);
339 CREATE_TEST (test_downscale_641x481_111x30_method_1, 1, 641, 481, 111, 30);
340 CREATE_TEST (test_downscale_641x481_111x30_method_2, 2, 641, 481, 111, 30);
341 CREATE_TEST (test_downscale_641x481_111x30_method_3, 3, 641, 481, 111, 30);
342 CREATE_TEST (test_upscale_111x30_641x481_method_0, 0, 111, 30, 641, 481);
343 CREATE_TEST (test_upscale_111x30_641x481_method_1, 1, 111, 30, 641, 481);
344 CREATE_TEST (test_upscale_111x30_641x481_method_2, 2, 111, 30, 641, 481);
345 CREATE_TEST (test_upscale_111x30_641x481_method_3, 2, 111, 30, 641, 481);
346 CREATE_TEST (test_downscale_641x481_30x111_method_0, 0, 641, 481, 30, 111);
347 CREATE_TEST (test_downscale_641x481_30x111_method_1, 1, 641, 481, 30, 111);
348 CREATE_TEST (test_downscale_641x481_30x111_method_2, 2, 641, 481, 30, 111);
349 CREATE_TEST (test_downscale_641x481_30x111_method_3, 3, 641, 481, 30, 111);
350 CREATE_TEST (test_upscale_30x111_641x481_method_0, 0, 30, 111, 641, 481);
351 CREATE_TEST (test_upscale_30x111_641x481_method_1, 1, 30, 111, 641, 481);
352 CREATE_TEST (test_upscale_30x111_641x481_method_2, 2, 30, 111, 641, 481);
353 CREATE_TEST (test_upscale_30x111_641x481_method_3, 3, 30, 111, 641, 481);
354 CREATE_TEST (test_downscale_640x480_320x1_method_0, 0, 640, 480, 320, 1);
355 CREATE_TEST (test_downscale_640x480_320x1_method_1, 1, 640, 480, 320, 1);
356 CREATE_TEST (test_downscale_640x480_320x1_method_2, 2, 640, 480, 320, 1);
357 CREATE_TEST (test_downscale_640x480_320x1_method_3, 3, 640, 480, 320, 1);
358 CREATE_TEST (test_upscale_320x1_640x480_method_0, 0, 320, 1, 640, 480);
359 CREATE_TEST (test_upscale_320x1_640x480_method_1, 1, 320, 1, 640, 480);
360 CREATE_TEST (test_upscale_320x1_640x480_method_2, 2, 320, 1, 640, 480);
361 CREATE_TEST (test_upscale_320x1_640x480_method_3, 3, 320, 1, 640, 480);
362 CREATE_TEST (test_downscale_640x480_1x240_method_0, 0, 640, 480, 1, 240);
363 CREATE_TEST (test_downscale_640x480_1x240_method_1, 1, 640, 480, 1, 240);
364 CREATE_TEST (test_downscale_640x480_1x240_method_2, 2, 640, 480, 1, 240);
365 CREATE_TEST (test_downscale_640x480_1x240_method_3, 3, 640, 480, 1, 240);
366 CREATE_TEST (test_upscale_1x240_640x480_method_0, 0, 1, 240, 640, 480);
367 CREATE_TEST (test_upscale_1x240_640x480_method_1, 1, 1, 240, 640, 480);
368 CREATE_TEST (test_upscale_1x240_640x480_method_2, 2, 1, 240, 640, 480);
369 CREATE_TEST (test_upscale_1x240_640x480_method_3, 3, 1, 240, 640, 480);
377 } TestNegotiationData;
380 _test_negotiation_message (GstBus * bus, GstMessage * message,
381 TestNegotiationData * data)
386 switch (GST_MESSAGE_TYPE (message)) {
387 case GST_MESSAGE_ERROR:
388 gst_message_parse_error (message, &err, &debug);
389 gst_object_default_error (GST_MESSAGE_SRC (message), err, debug);
392 g_assert_not_reached ();
394 case GST_MESSAGE_WARNING:
395 gst_message_parse_warning (message, &err, &debug);
396 gst_object_default_error (GST_MESSAGE_SRC (message), err, debug);
399 g_assert_not_reached ();
401 case GST_MESSAGE_EOS:
402 g_main_loop_quit (data->loop);
410 _test_negotiation_notify_caps (GObject * src, GParamSpec * pspec,
411 TestNegotiationData * data)
416 gint par_n = 0, par_d = 0;
418 g_object_get (src, "caps", &caps, NULL);
422 s = gst_caps_get_structure (caps, 0);
424 fail_unless (gst_structure_get_int (s, "width", &width));
425 fail_unless (gst_structure_get_int (s, "height", &height));
426 fail_unless (gst_structure_get_fraction (s, "pixel-aspect-ratio", &par_n,
427 &par_d) || (data->par_n == 1 && data->par_d == 1));
429 gst_caps_unref (caps);
431 fail_unless_equals_int (width, data->width);
432 fail_unless_equals_int (height, data->height);
433 if (par_n != 0 || par_d != 0) {
434 fail_unless_equals_int (par_n, data->par_n);
435 fail_unless_equals_int (par_d, data->par_d);
438 data->ok = (width == data->width) && (height == data->height)
439 && (par_n == data->par_n) && (par_d == data->par_d);
441 g_main_loop_quit (data->loop);
445 _test_negotiation (const gchar * src_templ, const gchar * sink_templ,
446 gint width, gint height, gint par_n, gint par_d)
448 GstElement *pipeline;
449 GstElement *src, *capsfilter1, *scale, *capsfilter2, *sink;
453 TestNegotiationData data = { 0, 0, 0, 0, FALSE, NULL };
456 GST_DEBUG ("Running test for src templ caps '%s' and sink templ caps '%s'",
457 src_templ, sink_templ);
459 pipeline = gst_element_factory_make ("pipeline", "pipeline");
460 fail_unless (pipeline != NULL);
462 src = gst_element_factory_make ("videotestsrc", "src");
463 fail_unless (src != NULL);
464 g_object_set (G_OBJECT (src), "num-buffers", 1, NULL);
466 capsfilter1 = gst_element_factory_make ("capsfilter", "filter1");
467 fail_unless (capsfilter1 != NULL);
468 caps = gst_caps_from_string (src_templ);
469 fail_unless (caps != NULL);
470 g_object_set (G_OBJECT (capsfilter1), "caps", caps, NULL);
471 gst_caps_unref (caps);
473 scale = gst_element_factory_make ("videoscale", "scale");
474 fail_unless (scale != NULL);
476 capsfilter2 = gst_element_factory_make ("capsfilter", "filter2");
477 fail_unless (capsfilter2 != NULL);
478 caps = gst_caps_from_string (sink_templ);
479 fail_unless (caps != NULL);
480 g_object_set (G_OBJECT (capsfilter2), "caps", caps, NULL);
481 gst_caps_unref (caps);
483 pad = gst_element_get_static_pad (capsfilter2, "sink");
484 fail_unless (pad != NULL);
485 g_signal_connect (pad, "notify::caps",
486 G_CALLBACK (_test_negotiation_notify_caps), &data);
487 gst_object_unref (pad);
489 sink = gst_element_factory_make ("fakesink", "sink");
490 fail_unless (sink != NULL);
491 g_object_set (sink, "async", FALSE, NULL);
493 gst_bin_add_many (GST_BIN (pipeline), src, capsfilter1, scale, capsfilter2,
496 fail_unless (gst_element_link_pads_full (src, "src", capsfilter1, "sink",
498 fail_unless (gst_element_link_pads_full (capsfilter1, "src", scale, "sink",
500 fail_unless (gst_element_link_pads_full (scale, "src", capsfilter2, "sink",
502 fail_unless (gst_element_link_pads_full (capsfilter2, "src", sink, "sink",
505 loop = g_main_loop_new (NULL, FALSE);
507 bus = gst_element_get_bus (pipeline);
508 fail_unless (bus != NULL);
509 gst_bus_add_signal_watch (bus);
513 data.height = height;
518 g_signal_connect (bus, "message", G_CALLBACK (_test_negotiation_message),
521 gst_object_unref (bus);
523 fail_unless (gst_element_set_state (pipeline,
524 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
526 g_main_loop_run (loop);
528 fail_unless (data.ok == TRUE);
530 fail_unless (gst_element_set_state (pipeline,
531 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
533 gst_object_unref (pipeline);
534 g_main_loop_unref (loop);
537 GST_START_TEST (test_negotiation)
540 ("video/x-raw,format=(string)AYUV,width=720,height=576,pixel-aspect-ratio=16/15",
541 "video/x-raw,format=(string)AYUV,width=768,height=576", 768, 576, 1, 1);
544 ("video/x-raw,format=(string)AYUV,width=320,height=240",
545 "video/x-raw,format=(string)AYUV,width=640,height=320", 640, 320, 2, 3);
548 ("video/x-raw,format=(string)AYUV,width=320,height=240",
549 "video/x-raw,format=(string)AYUV,width=640,height=320,pixel-aspect-ratio=[0/1, 1/1]",
553 ("video/x-raw,format=(string)AYUV,width=1920,height=2560,pixel-aspect-ratio=1/1",
554 "video/x-raw,format=(string)AYUV,width=[1, 2048],height=[1, 2048],pixel-aspect-ratio=1/1",
558 ("video/x-raw,format=(string)AYUV,width=1920,height=2560,pixel-aspect-ratio=1/1",
559 "video/x-raw,format=(string)AYUV,width=[1, 2048],height=[1, 2048]",
563 ("video/x-raw,format=(string)AYUV,width=1920,height=2560",
564 "video/x-raw,format=(string)AYUV,width=[1, 2048],height=[1, 2048]",
568 ("video/x-raw,format=(string)AYUV,width=1920,height=2560",
569 "video/x-raw,format=(string)AYUV,width=1200,height=[1, 2048],pixel-aspect-ratio=1/1",
572 /* Doesn't keep DAR but must be possible! */
574 ("video/x-raw,format=(string)AYUV,width=320,height=240,pixel-aspect-ratio=1/1",
575 "video/x-raw,format=(string)AYUV,width=200,height=200,pixel-aspect-ratio=1/2",
581 #define GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK \
582 (gst_test_reverse_negotiation_sink_get_type())
583 #define GST_TEST_REVERSE_NEGOTIATION_SINK(obj) \
584 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK,GstTestReverseNegotiationSink))
585 #define GST_TEST_REVERSE_NEGOTIATION_SINK_CLASS(klass) \
586 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK,GstTestReverseNegotiationSinkClass))
587 #define GST_IS_TEST_REVERSE_NEGOTIATION_SINK(obj) \
588 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK))
589 #define GST_IS_TEST_REVERSE_NEGOTIATION_SINK_CLASS(klass) \
590 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK))
591 #define GST_TEST_REVERSE_NEGOTIATION_SINK_CAST(obj) ((GstTestReverseNegotiationSink *)obj)
593 typedef struct _GstTestReverseNegotiationSink GstTestReverseNegotiationSink;
594 typedef struct _GstTestReverseNegotiationSinkClass
595 GstTestReverseNegotiationSinkClass;
596 struct _GstTestReverseNegotiationSink
602 struct _GstTestReverseNegotiationSinkClass
604 GstBaseSinkClass parent_class;
607 GType gst_test_reverse_negotiation_sink_get_type (void);
609 G_DEFINE_TYPE (GstTestReverseNegotiationSink,
610 gst_test_reverse_negotiation_sink, GST_TYPE_BASE_SINK);
612 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
615 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("xRGB")));
619 gst_test_reverse_negotiation_sink_buffer_alloc (GstBaseSink * bsink,
620 guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf)
622 GstTestReverseNegotiationSink *sink =
623 GST_TEST_REVERSE_NEGOTIATION_SINK (bsink);
627 fail_unless (gst_video_format_parse_caps (caps, &fmt, &width, &height));
629 if (sink->nbuffers < 2) {
631 gst_buffer_new_and_alloc (gst_video_format_get_size (fmt, width,
633 gst_buffer_set_caps (*buf, caps);
637 fail_unless (gst_video_parse_caps_framerate (caps, &fps_n, &fps_d));
642 gst_buffer_new_and_alloc (gst_video_format_get_size (fmt, width,
644 caps = gst_video_format_new_caps (fmt, width, height, fps_n, fps_d, 1, 1);
645 gst_buffer_set_caps (*buf, caps);
646 gst_caps_unref (caps);
654 gst_test_reverse_negotiation_sink_render (GstBaseSink * bsink,
657 GstTestReverseNegotiationSink *sink =
658 GST_TEST_REVERSE_NEGOTIATION_SINK (bsink);
662 caps = gst_pad_get_current_caps (GST_BASE_SINK_PAD (bsink));
664 fail_unless (caps != NULL);
665 fail_unless (gst_video_info_from_caps (&info, caps));
669 /* The third buffer is still in the old size
670 * because the videoconverts can't convert
673 if (sink->nbuffers > 3) {
674 fail_unless_equals_int (GST_VIDEO_INFO_WIDTH (&info), 512);
675 fail_unless_equals_int (GST_VIDEO_INFO_HEIGHT (&info), 128);
678 gst_caps_unref (caps);
684 gst_test_reverse_negotiation_sink_class_init (GstTestReverseNegotiationSinkClass
687 GstElementClass *gstelement_class;
688 GstBaseSinkClass *gstbase_sink_class;
690 gstelement_class = GST_ELEMENT_CLASS (klass);
691 gstbase_sink_class = GST_BASE_SINK_CLASS (klass);
693 gst_element_class_set_details_simple (gstelement_class,
694 "Test Reverse Negotiation Sink",
696 "Some test sink", "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
697 gst_element_class_add_pad_template (gstelement_class,
698 gst_static_pad_template_get (&sinktemplate));
701 gstbase_sink_class->buffer_alloc =
702 GST_DEBUG_FUNCPTR (gst_test_reverse_negotiation_sink_buffer_alloc);
704 gstbase_sink_class->render =
705 GST_DEBUG_FUNCPTR (gst_test_reverse_negotiation_sink_render);
709 gst_test_reverse_negotiation_sink_init (GstTestReverseNegotiationSink * sink)
716 _test_reverse_negotiation_message (GstBus * bus, GstMessage * message,
722 switch (GST_MESSAGE_TYPE (message)) {
723 case GST_MESSAGE_ERROR:
724 gst_message_parse_error (message, &err, &debug);
725 gst_object_default_error (GST_MESSAGE_SRC (message), err, debug);
728 g_assert_not_reached ();
730 case GST_MESSAGE_WARNING:
731 gst_message_parse_warning (message, &err, &debug);
732 gst_object_default_error (GST_MESSAGE_SRC (message), err, debug);
735 g_assert_not_reached ();
737 case GST_MESSAGE_EOS:
738 g_main_loop_quit (loop);
747 GST_START_TEST (test_reverse_negotiation)
749 GstElement *pipeline;
750 GstElement *src, *csp1, *scale, *csp2, *sink;
754 pipeline = gst_element_factory_make ("pipeline", "pipeline");
755 fail_unless (pipeline != NULL);
757 src = gst_element_factory_make ("videotestsrc", "src");
758 fail_unless (src != NULL);
759 g_object_set (G_OBJECT (src), "num-buffers", 8, NULL);
761 csp1 = gst_element_factory_make ("videoconvert", "csp1");
762 fail_unless (csp1 != NULL);
764 scale = gst_element_factory_make ("videoscale", "scale");
765 fail_unless (scale != NULL);
767 csp2 = gst_element_factory_make ("videoconvert", "csp2");
768 fail_unless (csp2 != NULL);
770 sink = g_object_new (GST_TYPE_TEST_REVERSE_NEGOTIATION_SINK, NULL);
771 fail_unless (sink != NULL);
772 g_object_set (sink, "async", FALSE, NULL);
774 gst_bin_add_many (GST_BIN (pipeline), src, csp1, scale, csp2, sink, NULL);
776 fail_unless (gst_element_link_pads_full (src, "src", csp1, "sink",
778 fail_unless (gst_element_link_pads_full (csp1, "src", scale, "sink",
780 fail_unless (gst_element_link_pads_full (scale, "src", csp2, "sink",
782 fail_unless (gst_element_link_pads_full (csp2, "src", sink, "sink",
785 loop = g_main_loop_new (NULL, FALSE);
787 bus = gst_element_get_bus (pipeline);
788 fail_unless (bus != NULL);
789 gst_bus_add_signal_watch (bus);
791 g_signal_connect (bus, "message",
792 G_CALLBACK (_test_reverse_negotiation_message), loop);
794 gst_object_unref (bus);
796 fail_unless (gst_element_set_state (pipeline,
797 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
799 g_main_loop_run (loop);
801 fail_unless (gst_element_set_state (pipeline,
802 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
804 gst_object_unref (pipeline);
805 g_main_loop_unref (loop);
811 GST_START_TEST (test_basetransform_negotiation)
813 GstElement *pipeline, *src, *sink, *scale, *capsfilter1, *capsfilter2;
817 pipeline = gst_pipeline_new (NULL);
818 src = gst_element_factory_make ("videotestsrc", NULL);
819 capsfilter1 = gst_element_factory_make ("capsfilter", NULL);
820 scale = gst_element_factory_make ("videoscale", NULL);
821 capsfilter2 = gst_element_factory_make ("capsfilter", NULL);
822 sink = gst_element_factory_make ("fakesink", NULL);
823 fail_unless (pipeline && src && capsfilter1 && scale && capsfilter2 && sink);
825 g_object_set (src, "num-buffers", 3, NULL);
827 caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING,
828 "UYVY", "width", G_TYPE_INT, 352,
829 "height", G_TYPE_INT, 288, "framerate", GST_TYPE_FRACTION, 30, 1,
830 "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL);
831 g_object_set (capsfilter1, "caps", caps, NULL);
832 gst_caps_unref (caps);
834 /* same caps, just different pixel-aspect-ratio */
835 caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING,
836 "UYVY", "width", G_TYPE_INT, 352,
837 "height", G_TYPE_INT, 288, "framerate", GST_TYPE_FRACTION, 30, 1,
838 "pixel-aspect-ratio", GST_TYPE_FRACTION, 12, 11, NULL);
839 g_object_set (capsfilter2, "caps", caps, NULL);
840 gst_caps_unref (caps);
842 gst_bin_add_many (GST_BIN (pipeline), src, capsfilter1, scale, capsfilter2,
844 fail_unless (gst_element_link_many (src, capsfilter1, scale, capsfilter2,
847 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
848 GST_STATE_CHANGE_ASYNC);
850 msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipeline), -1,
851 GST_MESSAGE_EOS | GST_MESSAGE_ERROR);
852 fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_EOS);
853 gst_message_unref (msg);
855 gst_element_set_state (pipeline, GST_STATE_NULL);
856 gst_object_unref (pipeline);
861 #ifndef tcase_skip_broken_test
862 #define tcase_skip_broken_test(chain,test_func) \
863 if (0) { tcase_add_test(chain,test_func); } else { \
864 GST_ERROR ("FIXME: skipping test %s because it's broken.", G_STRINGIFY (test_func)); \
869 videoscale_suite (void)
871 Suite *s = suite_create ("videoscale");
872 TCase *tc_chain = tcase_create ("general");
874 suite_add_tcase (s, tc_chain);
875 tcase_set_timeout (tc_chain, 180);
876 tcase_add_test (tc_chain, test_passthrough_method_0);
877 tcase_add_test (tc_chain, test_passthrough_method_1);
878 tcase_add_test (tc_chain, test_passthrough_method_2);
879 tcase_add_test (tc_chain, test_passthrough_method_3);
880 tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_0);
881 tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_1);
882 tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_2);
883 tcase_add_test (tc_chain, test_downscale_640x480_320x240_method_3);
884 tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_0);
885 tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_1);
886 tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_2);
887 tcase_add_test (tc_chain, test_upscale_320x240_640x480_method_3);
888 tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_0);
889 tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_1);
890 tcase_add_test (tc_chain, test_downscale_640x480_1x1_method_2);
891 tcase_skip_broken_test (tc_chain, test_downscale_640x480_1x1_method_3);
892 tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_0);
893 tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_1);
894 tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_2);
895 tcase_add_test (tc_chain, test_upscale_1x1_640x480_method_3);
896 tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_0);
897 tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_1);
898 tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_2);
899 tcase_add_test (tc_chain, test_downscale_641x481_111x30_method_3);
900 tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_0);
901 tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_1);
902 tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_2);
903 tcase_add_test (tc_chain, test_upscale_111x30_641x481_method_3);
904 tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_0);
905 tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_1);
906 tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_2);
907 tcase_add_test (tc_chain, test_downscale_641x481_30x111_method_3);
908 tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_0);
909 tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_1);
910 tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_2);
911 tcase_add_test (tc_chain, test_upscale_30x111_641x481_method_3);
912 tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_0);
913 tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_1);
914 tcase_add_test (tc_chain, test_downscale_640x480_320x1_method_2);
915 tcase_skip_broken_test (tc_chain, test_downscale_640x480_320x1_method_3);
916 tcase_add_test (tc_chain, test_upscale_320x1_640x480_method_0);
917 tcase_add_test (tc_chain, test_upscale_320x1_640x480_method_1);
918 tcase_add_test (tc_chain, test_upscale_320x1_640x480_method_2);
919 tcase_skip_broken_test (tc_chain, test_upscale_320x1_640x480_method_3);
920 tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_0);
921 tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_1);
922 tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_2);
923 tcase_add_test (tc_chain, test_downscale_640x480_1x240_method_3);
924 tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_0);
925 tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_1);
926 tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_2);
927 tcase_add_test (tc_chain, test_upscale_1x240_640x480_method_3);
928 tcase_add_test (tc_chain, test_negotiation);
930 tcase_add_test (tc_chain, test_reverse_negotiation);
932 tcase_add_test (tc_chain, test_basetransform_negotiation);
934 GST_ERROR ("FIXME: test 64-bpp formats as well");
938 GST_CHECK_MAIN (videoscale);