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 newsegment_event_catcher (GstObject * pad, GstEvent * event,
488 gpointer * user_data)
490 GstEvent **last_event = (GstEvent **) user_data;
491 fail_unless (event != NULL);
492 fail_unless (GST_IS_EVENT (event));
493 fail_unless (user_data != NULL);
495 if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
497 gst_event_unref (*last_event);
498 *last_event = gst_event_copy (event);
504 /* basesrc_seek_events_rate_update:
505 * - make sure we get expected newsegment after sending a seek event
507 GST_START_TEST (basesrc_seek_events_rate_update)
509 GstStateChangeReturn state_ret;
510 GstElement *src, *sink, *pipe;
515 GstEvent *newseg_event = NULL;
520 pipe = gst_pipeline_new ("pipeline");
521 sink = gst_element_factory_make ("fakesink", "sink");
522 src = gst_element_factory_make ("fakesrc", "src");
524 g_assert (pipe != NULL);
525 g_assert (sink != NULL);
526 g_assert (src != NULL);
528 fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
529 fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
531 fail_unless (gst_element_link (src, sink) == TRUE);
533 bus = gst_element_get_bus (pipe);
535 /* set up event probe to catch new segment event */
536 probe_pad = gst_element_get_static_pad (sink, "sink");
537 fail_unless (probe_pad != NULL);
539 probe = gst_pad_add_event_probe (probe_pad,
540 G_CALLBACK (newsegment_event_catcher), &newseg_event);
542 /* prepare the seek */
543 rate_seek = gst_event_new_seek (0.5, GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
544 GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE,
545 GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
547 GST_INFO ("going to playing");
550 gst_element_set_state (pipe, GST_STATE_PLAYING);
551 state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
552 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
554 GST_INFO ("seeking");
557 event_ret = gst_element_send_event (pipe, rate_seek);
558 fail_unless (event_ret == TRUE);
560 /* wait a second, then do controlled shutdown */
561 g_usleep (GST_USECOND * 1);
563 /* shut down source only (should send EOS event) ... */
564 gst_element_set_state (src, GST_STATE_NULL);
565 state_ret = gst_element_get_state (src, NULL, NULL, -1);
566 fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
568 fail_unless (gst_element_set_locked_state (src, TRUE) == TRUE);
570 /* ... and wait for the EOS message from the sink */
571 msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
572 fail_unless (msg != NULL);
573 fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
574 fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
576 gst_element_set_state (pipe, GST_STATE_NULL);
577 gst_element_get_state (pipe, NULL, NULL, -1);
579 GST_INFO ("stopped");
581 /* check that we have go the event */
582 fail_unless (newseg_event != NULL);
584 gst_event_parse_new_segment (newseg_event, NULL, &rate, NULL, NULL, NULL,
586 fail_unless (rate == 0.5);
588 gst_pad_remove_event_probe (probe_pad, probe);
589 gst_object_unref (probe_pad);
590 gst_message_unref (msg);
591 gst_event_unref (newseg_event);
592 gst_object_unref (bus);
593 gst_object_unref (pipe);
600 gst_basesrc_suite (void)
602 Suite *s = suite_create ("GstBaseSrc");
603 TCase *tc = tcase_create ("general");
605 suite_add_tcase (s, tc);
606 tcase_add_test (tc, basesrc_eos_events_pull);
607 tcase_add_test (tc, basesrc_eos_events_push);
608 tcase_add_test (tc, basesrc_eos_events_push_live_op);
609 tcase_add_test (tc, basesrc_eos_events_pull_live_op);
610 tcase_add_test (tc, basesrc_eos_events_push_live_eos);
611 tcase_add_test (tc, basesrc_eos_events_pull_live_eos);
612 tcase_add_test (tc, basesrc_seek_events_rate_update);
617 GST_CHECK_MAIN (gst_basesrc);