2 * Copyright (C) 2010 Sebastian Dröge <sebastian.droege@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.
22 #include <gst/check/gstcheck.h>
23 #include <gst/video/video.h>
26 bus_handler (GstBus * bus, GstMessage * message, gpointer data)
28 GMainLoop *loop = (GMainLoop *) data;
30 switch (message->type) {
32 g_main_loop_quit (loop);
34 case GST_MESSAGE_WARNING:
35 case GST_MESSAGE_ERROR:{
39 if (message->type == GST_MESSAGE_WARNING)
40 gst_message_parse_warning (message, &gerror, &debug);
42 gst_message_parse_error (message, &gerror, &debug);
43 g_error ("error from %s: %s (%s)\n",
44 GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)), gerror->message,
45 GST_STR_NULL (debug));
46 gst_message_unref (message);
47 g_error_free (gerror);
49 g_main_loop_quit (loop);
60 setup_imagefreeze (const GstCaps * caps1, const GstCaps * caps2,
61 GCallback sink_handoff, gpointer sink_handoff_data)
64 GstElement *videotestsrc, *capsfilter1, *imagefreeze, *capsfilter2, *fakesink;
66 pipeline = gst_pipeline_new ("pipeline");
67 fail_unless (pipeline != NULL);
69 videotestsrc = gst_element_factory_make ("videotestsrc", "src");
70 fail_unless (videotestsrc != NULL);
71 g_object_set (videotestsrc, "num-buffers", 1, NULL);
73 capsfilter1 = gst_element_factory_make ("capsfilter", "filter1");
74 fail_unless (capsfilter1 != NULL);
75 g_object_set (capsfilter1, "caps", caps1, NULL);
77 imagefreeze = gst_element_factory_make ("imagefreeze", "freeze");
78 fail_unless (imagefreeze != NULL);
80 capsfilter2 = gst_element_factory_make ("capsfilter", "filter2");
81 fail_unless (capsfilter2 != NULL);
82 g_object_set (capsfilter2, "caps", caps2, NULL);
84 fakesink = gst_element_factory_make ("fakesink", "sink");
85 fail_unless (fakesink != NULL);
86 g_object_set (fakesink, "signal-handoffs", TRUE, "async", FALSE, NULL);
89 g_signal_connect (fakesink, "handoff", sink_handoff, sink_handoff_data);
91 gst_bin_add_many (GST_BIN (pipeline), videotestsrc, capsfilter1, imagefreeze,
92 capsfilter2, fakesink, NULL);
94 fail_unless (gst_element_link_pads (videotestsrc, "src", capsfilter1,
96 fail_unless (gst_element_link_pads (capsfilter1, "src", imagefreeze, "sink"));
97 fail_unless (gst_element_link_pads (imagefreeze, "src", capsfilter2, "sink"));
98 fail_unless (gst_element_link_pads (capsfilter2, "src", fakesink, "sink"));
104 sink_handoff_cb_0_1 (GstElement * object, GstBuffer * buffer, GstPad * pad,
107 guint *n_buffers = (guint *) user_data;
109 if (*n_buffers == G_MAXUINT)
112 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer), 0);
113 fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), GST_CLOCK_TIME_NONE);
114 fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buffer), 0);
115 fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (buffer), 1);
117 *n_buffers = *n_buffers + 1;
120 GST_START_TEST (test_imagefreeze_0_1)
122 GstElement *pipeline;
123 GstCaps *caps1, *caps2;
126 guint n_buffers = G_MAXUINT;
130 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
132 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 0, 1, 1, 1);
135 setup_imagefreeze (caps1, caps2, G_CALLBACK (sink_handoff_cb_0_1),
138 loop = g_main_loop_new (NULL, TRUE);
139 fail_unless (loop != NULL);
141 bus = gst_element_get_bus (pipeline);
142 fail_unless (bus != NULL);
143 bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
144 gst_object_unref (bus);
147 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
148 GST_STATE_CHANGE_SUCCESS);
150 g_main_loop_run (loop);
152 fail_unless_equals_int (n_buffers, 1);
154 gst_element_set_state (pipeline, GST_STATE_NULL);
156 gst_object_unref (pipeline);
157 g_main_loop_unref (loop);
158 gst_caps_unref (caps1);
159 gst_caps_unref (caps2);
160 g_source_remove (bus_watch);
166 sink_handoff_cb_25_1_0ms_400ms (GstElement * object, GstBuffer * buffer,
167 GstPad * pad, gpointer user_data)
169 guint *n_buffers = (guint *) user_data;
171 if (*n_buffers == G_MAXUINT)
174 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
175 *n_buffers * 40 * GST_MSECOND);
176 fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 40 * GST_MSECOND);
177 fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buffer), *n_buffers);
178 fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (buffer), *n_buffers + 1);
180 *n_buffers = *n_buffers + 1;
183 GST_START_TEST (test_imagefreeze_25_1_0ms_400ms)
185 GstElement *pipeline;
186 GstCaps *caps1, *caps2;
189 guint n_buffers = G_MAXUINT;
193 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
195 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
198 setup_imagefreeze (caps1, caps2,
199 G_CALLBACK (sink_handoff_cb_25_1_0ms_400ms), &n_buffers);
201 loop = g_main_loop_new (NULL, TRUE);
202 fail_unless (loop != NULL);
204 bus = gst_element_get_bus (pipeline);
205 fail_unless (bus != NULL);
206 bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
207 gst_object_unref (bus);
209 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
210 GST_STATE_CHANGE_SUCCESS);
212 fail_unless (gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME,
213 GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET,
218 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
219 GST_STATE_CHANGE_SUCCESS);
221 g_main_loop_run (loop);
223 fail_unless_equals_int (n_buffers, 10);
225 gst_element_set_state (pipeline, GST_STATE_NULL);
227 gst_object_unref (pipeline);
228 g_main_loop_unref (loop);
229 gst_caps_unref (caps1);
230 gst_caps_unref (caps2);
231 g_source_remove (bus_watch);
237 sink_handoff_cb_25_1_200ms_400ms (GstElement * object, GstBuffer * buffer,
238 GstPad * pad, gpointer user_data)
240 guint *n_buffers = (guint *) user_data;
242 if (*n_buffers == G_MAXUINT)
245 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
246 200 * GST_MSECOND + *n_buffers * 40 * GST_MSECOND);
247 fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 40 * GST_MSECOND);
248 fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buffer), 5 + *n_buffers);
249 fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (buffer),
252 *n_buffers = *n_buffers + 1;
255 GST_START_TEST (test_imagefreeze_25_1_200ms_400ms)
257 GstElement *pipeline;
258 GstCaps *caps1, *caps2;
261 guint n_buffers = G_MAXUINT;
265 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
267 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
270 setup_imagefreeze (caps1, caps2,
271 G_CALLBACK (sink_handoff_cb_25_1_200ms_400ms), &n_buffers);
273 loop = g_main_loop_new (NULL, TRUE);
274 fail_unless (loop != NULL);
276 bus = gst_element_get_bus (pipeline);
277 fail_unless (bus != NULL);
278 bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
279 gst_object_unref (bus);
281 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
282 GST_STATE_CHANGE_SUCCESS);
284 fail_unless (gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME,
285 GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 200 * GST_MSECOND,
286 GST_SEEK_TYPE_SET, 400 * GST_MSECOND));
290 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
291 GST_STATE_CHANGE_SUCCESS);
293 g_main_loop_run (loop);
295 fail_unless_equals_int (n_buffers, 5);
297 gst_element_set_state (pipeline, GST_STATE_NULL);
299 gst_object_unref (pipeline);
300 g_main_loop_unref (loop);
301 gst_caps_unref (caps1);
302 gst_caps_unref (caps2);
303 g_source_remove (bus_watch);
309 sink_handoff_cb_25_1_400ms_0ms (GstElement * object, GstBuffer * buffer,
310 GstPad * pad, gpointer user_data)
312 guint *n_buffers = (guint *) user_data;
314 if (*n_buffers == G_MAXUINT)
317 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
318 400 * GST_MSECOND - (*n_buffers + 1) * 40 * GST_MSECOND);
319 fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 40 * GST_MSECOND);
320 fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buffer), 10 - (*n_buffers + 1));
321 fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (buffer),
322 10 - (*n_buffers + 1) + 1);
324 *n_buffers = *n_buffers + 1;
327 GST_START_TEST (test_imagefreeze_25_1_400ms_0ms)
329 GstElement *pipeline;
330 GstCaps *caps1, *caps2;
333 guint n_buffers = G_MAXUINT;
337 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
339 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
342 setup_imagefreeze (caps1, caps2,
343 G_CALLBACK (sink_handoff_cb_25_1_400ms_0ms), &n_buffers);
345 loop = g_main_loop_new (NULL, TRUE);
346 fail_unless (loop != NULL);
348 bus = gst_element_get_bus (pipeline);
349 fail_unless (bus != NULL);
350 bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
351 gst_object_unref (bus);
353 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
354 GST_STATE_CHANGE_SUCCESS);
356 fail_unless (gst_element_seek (pipeline, -1.0, GST_FORMAT_TIME,
357 GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET,
362 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
363 GST_STATE_CHANGE_SUCCESS);
365 g_main_loop_run (loop);
367 fail_unless_equals_int (n_buffers, 10);
369 gst_element_set_state (pipeline, GST_STATE_NULL);
371 gst_object_unref (pipeline);
372 g_main_loop_unref (loop);
373 gst_caps_unref (caps1);
374 gst_caps_unref (caps2);
375 g_source_remove (bus_watch);
381 sink_handoff_cb_25_1_220ms_380ms (GstElement * object, GstBuffer * buffer,
382 GstPad * pad, gpointer user_data)
384 guint *n_buffers = (guint *) user_data;
386 if (*n_buffers == G_MAXUINT)
389 if (*n_buffers == 0) {
390 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
392 fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 20 * GST_MSECOND);
393 } else if (*n_buffers == 4) {
394 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
396 fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 20 * GST_MSECOND);
398 fail_unless_equals_uint64 (GST_BUFFER_TIMESTAMP (buffer),
399 200 * GST_MSECOND + *n_buffers * 40 * GST_MSECOND);
400 fail_unless_equals_uint64 (GST_BUFFER_DURATION (buffer), 40 * GST_MSECOND);
403 fail_unless_equals_uint64 (GST_BUFFER_OFFSET (buffer), 5 + *n_buffers);
404 fail_unless_equals_uint64 (GST_BUFFER_OFFSET_END (buffer),
407 *n_buffers = *n_buffers + 1;
410 GST_START_TEST (test_imagefreeze_25_1_220ms_380ms)
412 GstElement *pipeline;
413 GstCaps *caps1, *caps2;
416 guint n_buffers = G_MAXUINT;
420 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
422 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
425 setup_imagefreeze (caps1, caps2,
426 G_CALLBACK (sink_handoff_cb_25_1_220ms_380ms), &n_buffers);
428 loop = g_main_loop_new (NULL, TRUE);
429 fail_unless (loop != NULL);
431 bus = gst_element_get_bus (pipeline);
432 fail_unless (bus != NULL);
433 bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
434 gst_object_unref (bus);
436 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
437 GST_STATE_CHANGE_SUCCESS);
439 fail_unless (gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME,
440 GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 220 * GST_MSECOND,
441 GST_SEEK_TYPE_SET, 380 * GST_MSECOND));
445 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
446 GST_STATE_CHANGE_SUCCESS);
448 g_main_loop_run (loop);
450 fail_unless_equals_int (n_buffers, 5);
452 gst_element_set_state (pipeline, GST_STATE_NULL);
454 gst_object_unref (pipeline);
455 g_main_loop_unref (loop);
456 gst_caps_unref (caps1);
457 gst_caps_unref (caps2);
458 g_source_remove (bus_watch);
463 static GstBuffer *test_buffer = NULL;
466 test_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
469 fail_if (test_buffer != NULL);
471 test_buffer = gst_buffer_new_and_alloc (size);
472 gst_buffer_set_caps (test_buffer, caps);
474 *buf = gst_buffer_ref (test_buffer);
480 sink_handoff_cb_bufferalloc (GstElement * object, GstBuffer * buffer,
481 GstPad * pad, gpointer user_data)
483 guint *n_buffers = (guint *) user_data;
485 if (*n_buffers == G_MAXUINT)
488 fail_unless (buffer->parent != NULL);
489 fail_unless (test_buffer != NULL);
490 fail_unless (buffer->parent == test_buffer);
492 *n_buffers = *n_buffers + 1;
495 GST_START_TEST (test_imagefreeze_bufferalloc)
497 GstElement *pipeline;
500 GstCaps *caps1, *caps2;
503 guint n_buffers = G_MAXUINT;
507 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
509 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
512 setup_imagefreeze (caps1, caps2, G_CALLBACK (sink_handoff_cb_bufferalloc),
515 sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
516 fail_unless (sink != NULL);
517 sinkpad = gst_element_get_static_pad (sink, "sink");
518 fail_unless (sinkpad != NULL);
519 gst_pad_set_bufferalloc_function (sinkpad, test_bufferalloc);
520 gst_object_unref (sinkpad);
521 gst_object_unref (sink);
523 loop = g_main_loop_new (NULL, TRUE);
524 fail_unless (loop != NULL);
526 bus = gst_element_get_bus (pipeline);
527 fail_unless (bus != NULL);
528 bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
529 gst_object_unref (bus);
531 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
532 GST_STATE_CHANGE_SUCCESS);
534 fail_unless (gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME,
535 GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET,
539 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
540 GST_STATE_CHANGE_SUCCESS);
542 g_main_loop_run (loop);
544 fail_unless (test_buffer != NULL);
545 fail_unless (n_buffers >= 1);
547 gst_element_set_state (pipeline, GST_STATE_NULL);
549 gst_buffer_unref (test_buffer);
552 gst_object_unref (pipeline);
553 g_main_loop_unref (loop);
554 gst_caps_unref (caps1);
555 gst_caps_unref (caps2);
556 g_source_remove (bus_watch);
561 GST_START_TEST (test_imagefreeze_eos)
563 GstElement *pipeline;
565 GstCaps *caps1, *caps2;
568 GstFormat fmt = GST_FORMAT_TIME;
573 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
575 gst_video_format_new_caps (GST_VIDEO_FORMAT_xRGB, 640, 480, 25, 1, 1, 1);
577 pipeline = setup_imagefreeze (caps1, caps2, NULL, NULL);
579 src = gst_bin_get_by_name (GST_BIN (pipeline), "src");
580 fail_unless (src != NULL);
581 g_object_set (src, "num-buffers", 100, NULL);
583 loop = g_main_loop_new (NULL, TRUE);
584 fail_unless (loop != NULL);
586 bus = gst_element_get_bus (pipeline);
587 fail_unless (bus != NULL);
588 bus_watch = gst_bus_add_watch (bus, bus_handler, loop);
589 gst_object_unref (bus);
591 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
592 GST_STATE_CHANGE_SUCCESS);
594 fail_unless (gst_element_seek (pipeline, 1.0, GST_FORMAT_TIME,
595 GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET,
598 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
599 GST_STATE_CHANGE_SUCCESS);
601 g_main_loop_run (loop);
603 fail_unless (gst_element_query_position (src, &fmt, &position));
604 fail_unless_equals_uint64 (position, 40 * GST_MSECOND);
606 gst_element_set_state (pipeline, GST_STATE_NULL);
608 gst_object_unref (src);
609 gst_object_unref (pipeline);
610 g_main_loop_unref (loop);
611 gst_caps_unref (caps1);
612 gst_caps_unref (caps2);
613 g_source_remove (bus_watch);
619 imagefreeze_suite (void)
621 Suite *s = suite_create ("imagefreeze");
622 TCase *tc_chain = tcase_create ("linear");
624 /* time out after 120s, not the default 3 */
625 tcase_set_timeout (tc_chain, 120);
627 suite_add_tcase (s, tc_chain);
628 tcase_add_test (tc_chain, test_imagefreeze_0_1);
629 tcase_add_test (tc_chain, test_imagefreeze_25_1_0ms_400ms);
630 tcase_add_test (tc_chain, test_imagefreeze_25_1_200ms_400ms);
631 tcase_add_test (tc_chain, test_imagefreeze_25_1_400ms_0ms);
632 tcase_add_test (tc_chain, test_imagefreeze_25_1_220ms_380ms);
634 tcase_add_test (tc_chain, test_imagefreeze_bufferalloc);
635 tcase_add_test (tc_chain, test_imagefreeze_eos);
640 GST_CHECK_MAIN (imagefreeze);