3 * some unit tests for GstBaseSrc
5 * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
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.
27 #include <gst/check/gstcheck.h>
28 #include <gst/base/gstbasesrc.h>
31 eos_event_counter (GstObject * pad, GstEvent * event, guint * p_num_eos)
33 fail_unless (event != NULL);
34 fail_unless (GST_IS_EVENT (event));
36 if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
42 /* basesrc_eos_events_push_live_op:
43 * - make sure source does send an EOS event when operating in push
44 * mode and being set to READY explicitly (like one might with
47 GST_START_TEST (basesrc_eos_events_push_live_op)
49 GstStateChangeReturn state_ret;
50 GstElement *src, *sink, *pipe;
54 guint probe, num_eos = 0;
56 pipe = gst_pipeline_new ("pipeline");
57 sink = gst_element_factory_make ("fakesink", "sink");
58 src = gst_element_factory_make ("fakesrc", "src");
60 g_assert (pipe != NULL);
61 g_assert (sink != NULL);
62 g_assert (src != NULL);
64 fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
65 fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
67 fail_unless (gst_element_link (src, sink) == TRUE);
69 g_object_set (sink, "can-activate-push", TRUE, NULL);
70 g_object_set (sink, "can-activate-pull", FALSE, NULL);
72 g_object_set (src, "can-activate-push", TRUE, NULL);
73 g_object_set (src, "can-activate-pull", FALSE, NULL);
75 /* set up event probe to count EOS events */
76 srcpad = gst_element_get_static_pad (src, "src");
77 fail_unless (srcpad != NULL);
79 probe = gst_pad_add_event_probe (srcpad,
80 G_CALLBACK (eos_event_counter), &num_eos);
82 bus = gst_element_get_bus (pipe);
84 gst_element_set_state (pipe, GST_STATE_PLAYING);
85 state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
86 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
88 /* wait a second, then do controlled shutdown */
89 g_usleep (GST_USECOND * 1);
91 /* shut down source only (should send EOS event) ... */
92 gst_element_set_state (src, GST_STATE_NULL);
93 state_ret = gst_element_get_state (src, NULL, NULL, -1);
94 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
96 fail_unless (gst_element_set_locked_state (src, TRUE) == TRUE);
98 /* ... and wait for the EOS message from the sink */
99 msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
100 fail_unless (msg != NULL);
101 fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
102 fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
104 /* should be exactly one EOS event */
105 fail_unless (num_eos == 1);
107 gst_element_set_state (pipe, GST_STATE_NULL);
108 gst_element_get_state (pipe, NULL, NULL, -1);
110 /* make sure source hasn't sent a second one when going PAUSED => READY */
111 fail_unless (num_eos == 1);
113 gst_pad_remove_event_probe (srcpad, probe);
114 gst_object_unref (srcpad);
115 gst_message_unref (msg);
116 gst_object_unref (bus);
117 gst_object_unref (pipe);
122 /* basesrc_eos_events_push:
123 * - make sure source only sends one EOS when operating in push-mode,
124 * reaching the max number of buffers, and is then shut down.
126 GST_START_TEST (basesrc_eos_events_push)
128 GstStateChangeReturn state_ret;
129 GstElement *src, *sink, *pipe;
133 guint probe, num_eos = 0;
135 pipe = gst_pipeline_new ("pipeline");
136 sink = gst_element_factory_make ("fakesink", "sink");
137 src = gst_element_factory_make ("fakesrc", "src");
139 g_assert (pipe != NULL);
140 g_assert (sink != NULL);
141 g_assert (src != NULL);
143 fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
144 fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
146 fail_unless (gst_element_link (src, sink) == TRUE);
148 g_object_set (sink, "can-activate-push", TRUE, NULL);
149 g_object_set (sink, "can-activate-pull", FALSE, NULL);
151 g_object_set (src, "can-activate-push", TRUE, NULL);
152 g_object_set (src, "can-activate-pull", FALSE, NULL);
153 g_object_set (src, "num-buffers", 8, NULL);
155 /* set up event probe to count EOS events */
156 srcpad = gst_element_get_static_pad (src, "src");
157 fail_unless (srcpad != NULL);
159 probe = gst_pad_add_event_probe (srcpad,
160 G_CALLBACK (eos_event_counter), &num_eos);
162 bus = gst_element_get_bus (pipe);
164 gst_element_set_state (pipe, GST_STATE_PLAYING);
165 state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
166 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
168 msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
169 fail_unless (msg != NULL);
170 fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
171 fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
173 /* should be exactly one EOS event */
174 fail_unless (num_eos == 1);
176 gst_element_set_state (pipe, GST_STATE_NULL);
177 gst_element_get_state (pipe, NULL, NULL, -1);
179 /* make sure source hasn't sent a second one when going PAUSED => READY */
180 fail_unless (num_eos == 1);
182 gst_pad_remove_event_probe (srcpad, probe);
183 gst_object_unref (srcpad);
184 gst_message_unref (msg);
185 gst_object_unref (bus);
186 gst_object_unref (pipe);
191 /* basesrc_eos_events_pull_live_op:
192 * - make sure source doesn't send an EOS event when operating in
193 * pull mode and being set to READY explicitly (like one might with
196 GST_START_TEST (basesrc_eos_events_pull_live_op)
198 GstStateChangeReturn state_ret;
199 GstElement *src, *sink, *pipe;
201 guint probe, num_eos = 0;
203 pipe = gst_pipeline_new ("pipeline");
204 sink = gst_element_factory_make ("fakesink", "sink");
205 src = gst_element_factory_make ("fakesrc", "src");
207 g_assert (pipe != NULL);
208 g_assert (sink != NULL);
209 g_assert (src != NULL);
211 fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
212 fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
214 fail_unless (gst_element_link (src, sink) == TRUE);
216 g_object_set (sink, "can-activate-push", FALSE, NULL);
217 g_object_set (sink, "can-activate-pull", TRUE, NULL);
219 g_object_set (src, "can-activate-push", FALSE, NULL);
220 g_object_set (src, "can-activate-pull", TRUE, NULL);
222 /* set up event probe to count EOS events */
223 srcpad = gst_element_get_static_pad (src, "src");
224 fail_unless (srcpad != NULL);
226 probe = gst_pad_add_event_probe (srcpad,
227 G_CALLBACK (eos_event_counter), &num_eos);
229 gst_element_set_state (pipe, GST_STATE_PLAYING);
230 state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
231 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
233 /* wait a second, then do controlled shutdown */
234 g_usleep (GST_USECOND * 1);
236 /* shut down source only ... */
237 gst_element_set_state (src, GST_STATE_NULL);
238 state_ret = gst_element_get_state (src, NULL, NULL, -1);
239 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
241 fail_unless (gst_element_set_locked_state (src, TRUE) == TRUE);
243 /* source shouldn't have sent any EOS event in pull mode */
244 fail_unless (num_eos == 0);
246 gst_element_set_state (pipe, GST_STATE_NULL);
247 gst_element_get_state (pipe, NULL, NULL, -1);
249 /* make sure source hasn't sent an EOS when going PAUSED => READY either */
250 fail_unless (num_eos == 0);
252 gst_pad_remove_event_probe (srcpad, probe);
253 gst_object_unref (srcpad);
254 gst_object_unref (pipe);
259 /* basesrc_eos_events_pull:
260 * - makes sure source doesn't send EOS event when reaching the max.
261 * number of buffers configured in pull-mode
262 * - make sure source doesn't send EOS event either when being shut down
263 * (PAUSED => READY state change) after EOSing in pull mode
265 GST_START_TEST (basesrc_eos_events_pull)
267 GstStateChangeReturn state_ret;
268 GstElement *src, *sink, *pipe;
272 guint probe, num_eos = 0;
274 pipe = gst_pipeline_new ("pipeline");
275 sink = gst_element_factory_make ("fakesink", "sink");
276 src = gst_element_factory_make ("fakesrc", "src");
278 g_assert (pipe != NULL);
279 g_assert (sink != NULL);
280 g_assert (src != NULL);
282 fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
283 fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
285 fail_unless (gst_element_link (src, sink) == TRUE);
287 g_object_set (sink, "can-activate-push", FALSE, NULL);
288 g_object_set (sink, "can-activate-pull", TRUE, NULL);
290 g_object_set (src, "can-activate-push", FALSE, NULL);
291 g_object_set (src, "can-activate-pull", TRUE, NULL);
292 g_object_set (src, "num-buffers", 8, NULL);
294 /* set up event probe to count EOS events */
295 srcpad = gst_element_get_static_pad (src, "src");
296 fail_unless (srcpad != NULL);
298 probe = gst_pad_add_event_probe (srcpad,
299 G_CALLBACK (eos_event_counter), &num_eos);
301 bus = gst_element_get_bus (pipe);
303 gst_element_set_state (pipe, GST_STATE_PLAYING);
304 state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
305 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
307 msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
308 fail_unless (msg != NULL);
309 fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
310 fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
312 /* source shouldn't have sent any EOS event in pull mode */
313 fail_unless (num_eos == 0);
315 gst_element_set_state (pipe, GST_STATE_NULL);
316 gst_element_get_state (pipe, NULL, NULL, -1);
318 /* make sure source hasn't sent an EOS when going PAUSED => READY either */
319 fail_unless (num_eos == 0);
321 gst_pad_remove_event_probe (srcpad, probe);
322 gst_object_unref (srcpad);
323 gst_message_unref (msg);
324 gst_object_unref (bus);
325 gst_object_unref (pipe);
331 /* basesrc_eos_events_push_live_eos:
332 * - make sure the source stops and emits EOS when we send an EOS event to the
335 GST_START_TEST (basesrc_eos_events_push_live_eos)
337 GstStateChangeReturn state_ret;
338 GstElement *src, *sink, *pipe;
342 guint probe, num_eos = 0;
345 pipe = gst_pipeline_new ("pipeline");
346 sink = gst_element_factory_make ("fakesink", "sink");
347 src = gst_element_factory_make ("fakesrc", "src");
349 g_assert (pipe != NULL);
350 g_assert (sink != NULL);
351 g_assert (src != NULL);
353 fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
354 fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
356 fail_unless (gst_element_link (src, sink) == TRUE);
358 g_object_set (sink, "can-activate-push", TRUE, NULL);
359 g_object_set (sink, "can-activate-pull", FALSE, NULL);
361 g_object_set (src, "can-activate-push", TRUE, NULL);
362 g_object_set (src, "can-activate-pull", FALSE, NULL);
364 /* set up event probe to count EOS events */
365 srcpad = gst_element_get_static_pad (src, "src");
366 fail_unless (srcpad != NULL);
368 probe = gst_pad_add_event_probe (srcpad,
369 G_CALLBACK (eos_event_counter), &num_eos);
371 bus = gst_element_get_bus (pipe);
373 gst_element_set_state (pipe, GST_STATE_PLAYING);
374 state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
375 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
377 /* wait a second, then emit the EOS */
378 g_usleep (GST_USECOND * 1);
380 /* shut down source only (should send EOS event) ... */
381 res = gst_element_send_event (pipe, gst_event_new_eos ());
382 fail_unless (res == TRUE);
384 /* ... and wait for the EOS message from the sink */
385 msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
386 fail_unless (msg != NULL);
387 fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
388 fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
390 /* should be exactly one EOS event */
391 fail_unless (num_eos == 1);
393 gst_element_set_state (pipe, GST_STATE_NULL);
394 gst_element_get_state (pipe, NULL, NULL, -1);
396 /* make sure source hasn't sent a second one when going PAUSED => READY */
397 fail_unless (num_eos == 1);
399 gst_pad_remove_event_probe (srcpad, probe);
400 gst_object_unref (srcpad);
401 gst_message_unref (msg);
402 gst_object_unref (bus);
403 gst_object_unref (pipe);
408 /* basesrc_eos_events_pull_live_eos:
409 * - make sure the source stops and emits EOS when we send an EOS event to the
412 GST_START_TEST (basesrc_eos_events_pull_live_eos)
414 GstStateChangeReturn state_ret;
415 GstElement *src, *sink, *pipe;
419 guint probe, num_eos = 0;
422 pipe = gst_pipeline_new ("pipeline");
423 sink = gst_element_factory_make ("fakesink", "sink");
424 src = gst_element_factory_make ("fakesrc", "src");
426 g_assert (pipe != NULL);
427 g_assert (sink != NULL);
428 g_assert (src != NULL);
430 fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
431 fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
433 fail_unless (gst_element_link (src, sink) == TRUE);
435 g_object_set (sink, "can-activate-push", FALSE, NULL);
436 g_object_set (sink, "can-activate-pull", TRUE, NULL);
438 g_object_set (src, "can-activate-push", FALSE, NULL);
439 g_object_set (src, "can-activate-pull", TRUE, NULL);
441 /* set up event probe to count EOS events */
442 srcpad = gst_element_get_static_pad (src, "src");
443 fail_unless (srcpad != NULL);
445 probe = gst_pad_add_event_probe (srcpad,
446 G_CALLBACK (eos_event_counter), &num_eos);
448 bus = gst_element_get_bus (pipe);
450 gst_element_set_state (pipe, GST_STATE_PLAYING);
451 state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
452 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
454 /* wait a second, then emit the EOS */
455 g_usleep (GST_USECOND * 1);
457 /* shut down source only (should send EOS event) ... */
458 res = gst_element_send_event (pipe, gst_event_new_eos ());
459 fail_unless (res == TRUE);
461 /* ... and wait for the EOS message from the sink */
462 msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
463 fail_unless (msg != NULL);
464 fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
465 fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
467 /* no EOS in pull mode */
468 fail_unless (num_eos == 0);
470 gst_element_set_state (pipe, GST_STATE_NULL);
471 gst_element_get_state (pipe, NULL, NULL, -1);
473 /* make sure source hasn't sent a second one when going PAUSED => READY */
474 fail_unless (num_eos == 0);
476 gst_pad_remove_event_probe (srcpad, probe);
477 gst_object_unref (srcpad);
478 gst_message_unref (msg);
479 gst_object_unref (bus);
480 gst_object_unref (pipe);
487 segment_event_catcher (GstObject * pad, GstEvent * event, gpointer * user_data)
489 GstEvent **last_event = (GstEvent **) user_data;
490 fail_unless (event != NULL);
491 fail_unless (GST_IS_EVENT (event));
492 fail_unless (user_data != NULL);
494 if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
496 gst_event_unref (*last_event);
497 *last_event = gst_event_copy (event);
503 /* basesrc_seek_events_rate_update:
504 * - make sure we get expected segment after sending a seek event
506 GST_START_TEST (basesrc_seek_events_rate_update)
508 GstStateChangeReturn state_ret;
509 GstElement *src, *sink, *pipe;
514 GstEvent *seg_event = NULL;
519 pipe = gst_pipeline_new ("pipeline");
520 sink = gst_element_factory_make ("fakesink", "sink");
521 src = gst_element_factory_make ("fakesrc", "src");
523 g_assert (pipe != NULL);
524 g_assert (sink != NULL);
525 g_assert (src != NULL);
527 fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
528 fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
530 fail_unless (gst_element_link (src, sink) == TRUE);
532 bus = gst_element_get_bus (pipe);
534 /* set up event probe to catch new segment event */
535 probe_pad = gst_element_get_static_pad (sink, "sink");
536 fail_unless (probe_pad != NULL);
538 probe = gst_pad_add_event_probe (probe_pad,
539 G_CALLBACK (segment_event_catcher), &seg_event);
541 /* prepare the seek */
542 rate_seek = gst_event_new_seek (0.5, GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
543 GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE,
544 GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
546 GST_INFO ("going to playing");
549 gst_element_set_state (pipe, GST_STATE_PLAYING);
550 state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
551 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
553 GST_INFO ("seeking");
556 event_ret = gst_element_send_event (pipe, rate_seek);
557 fail_unless (event_ret == TRUE);
559 /* wait a second, then do controlled shutdown */
560 g_usleep (GST_USECOND * 1);
562 /* shut down source only (should send EOS event) ... */
563 gst_element_set_state (src, GST_STATE_NULL);
564 state_ret = gst_element_get_state (src, NULL, NULL, -1);
565 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
567 fail_unless (gst_element_set_locked_state (src, TRUE) == TRUE);
569 /* ... and wait for the EOS message from the sink */
570 msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
571 fail_unless (msg != NULL);
572 fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
573 fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
575 gst_element_set_state (pipe, GST_STATE_NULL);
576 gst_element_get_state (pipe, NULL, NULL, -1);
578 GST_INFO ("stopped");
580 /* check that we have go the event */
581 fail_unless (seg_event != NULL);
583 gst_event_parse_segment (seg_event, &segment);
584 fail_unless (segment.rate == 0.5);
586 gst_pad_remove_event_probe (probe_pad, probe);
587 gst_object_unref (probe_pad);
588 gst_message_unref (msg);
589 gst_event_unref (seg_event);
590 gst_object_unref (bus);
591 gst_object_unref (pipe);
598 gst_basesrc_suite (void)
600 Suite *s = suite_create ("GstBaseSrc");
601 TCase *tc = tcase_create ("general");
603 suite_add_tcase (s, tc);
604 tcase_add_test (tc, basesrc_eos_events_pull);
605 tcase_add_test (tc, basesrc_eos_events_push);
606 tcase_add_test (tc, basesrc_eos_events_push_live_op);
607 tcase_add_test (tc, basesrc_eos_events_pull_live_op);
608 tcase_add_test (tc, basesrc_eos_events_push_live_eos);
609 tcase_add_test (tc, basesrc_eos_events_pull_live_eos);
610 tcase_add_test (tc, basesrc_seek_events_rate_update);
615 GST_CHECK_MAIN (gst_basesrc);