• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  *
3  * some unit tests for GstBaseSrc
4  *
5  * Copyright (C) 2006-2017 Tim-Philipp Müller <tim centricular net>
6  *
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.
11  *
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.
16  *
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., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 #include <gst/gst.h>
27 #include <gst/check/gstcheck.h>
28 #include <gst/check/gstconsistencychecker.h>
29 #include <gst/base/gstbasesrc.h>
30 
31 static GstPadProbeReturn
eos_event_counter(GstObject * pad,GstPadProbeInfo * info,guint * p_num_eos)32 eos_event_counter (GstObject * pad, GstPadProbeInfo * info, guint * p_num_eos)
33 {
34   GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
35 
36   fail_unless (event != NULL);
37   fail_unless (GST_IS_EVENT (event));
38 
39   if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
40     *p_num_eos += 1;
41 
42   return GST_PAD_PROBE_OK;
43 }
44 
45 /* basesrc_eos_events_push_live_op:
46  *  - make sure source does send an EOS event when operating in push
47  *    mode and being set to READY explicitly (like one might with
48  *    live sources)
49  */
GST_START_TEST(basesrc_eos_events_push_live_op)50 GST_START_TEST (basesrc_eos_events_push_live_op)
51 {
52   GstStateChangeReturn state_ret;
53   GstElement *src, *sink, *pipe;
54   GstMessage *msg;
55   GstBus *bus;
56   GstPad *srcpad;
57   guint probe, num_eos = 0;
58   GstStreamConsistency *consistency;
59   GstEvent *eos_event;
60   guint32 eos_event_seqnum;
61 
62   pipe = gst_pipeline_new ("pipeline");
63   sink = gst_element_factory_make ("fakesink", "sink");
64   src = gst_element_factory_make ("fakesrc", "src");
65 
66   g_assert (pipe != NULL);
67   g_assert (sink != NULL);
68   g_assert (src != NULL);
69 
70   fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
71   fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
72 
73   fail_unless (gst_element_link (src, sink) == TRUE);
74 
75   g_object_set (sink, "can-activate-push", TRUE, NULL);
76   g_object_set (sink, "can-activate-pull", FALSE, NULL);
77 
78   g_object_set (src, "can-activate-push", TRUE, NULL);
79   g_object_set (src, "can-activate-pull", FALSE, NULL);
80 
81   /* set up event probe to count EOS events */
82   srcpad = gst_element_get_static_pad (src, "src");
83   fail_unless (srcpad != NULL);
84 
85   consistency = gst_consistency_checker_new (srcpad);
86 
87   probe = gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH,
88       (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
89 
90   bus = gst_element_get_bus (pipe);
91 
92   gst_element_set_state (pipe, GST_STATE_PLAYING);
93   state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
94   fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
95 
96   /* wait a second, then do controlled shutdown */
97   g_usleep (GST_USECOND * 1);
98 
99   /* shut down pipeline (should send EOS message) ... */
100   eos_event = gst_event_new_eos ();
101   eos_event_seqnum = gst_event_get_seqnum (eos_event);
102   gst_element_send_event (pipe, eos_event);
103 
104   /* ... and wait for the EOS message from the sink */
105   msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
106   fail_unless (msg != NULL);
107   fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
108   fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
109 
110   /* should be exactly one EOS event */
111   fail_unless (num_eos == 1);
112   fail_unless (gst_message_get_seqnum (msg) == eos_event_seqnum);
113 
114   gst_element_set_state (pipe, GST_STATE_NULL);
115   gst_element_get_state (pipe, NULL, NULL, -1);
116 
117   /* make sure source hasn't sent a second one when going PAUSED => READY */
118   fail_unless (num_eos == 1);
119 
120   gst_consistency_checker_free (consistency);
121 
122   gst_pad_remove_probe (srcpad, probe);
123   gst_object_unref (srcpad);
124   gst_message_unref (msg);
125   gst_object_unref (bus);
126   gst_object_unref (pipe);
127 }
128 
129 GST_END_TEST;
130 
131 
132 
133 /* basesrc_eos_events_push:
134  *  - make sure source only sends one EOS when operating in push-mode,
135  *    reaching the max number of buffers, and is then shut down.
136  */
GST_START_TEST(basesrc_eos_events_push)137 GST_START_TEST (basesrc_eos_events_push)
138 {
139   GstStateChangeReturn state_ret;
140   GstElement *src, *sink, *pipe;
141   GstMessage *msg;
142   GstBus *bus;
143   GstPad *srcpad;
144   guint probe, num_eos = 0;
145   GstStreamConsistency *consistency;
146 
147   pipe = gst_pipeline_new ("pipeline");
148   sink = gst_element_factory_make ("fakesink", "sink");
149   src = gst_element_factory_make ("fakesrc", "src");
150 
151   g_assert (pipe != NULL);
152   g_assert (sink != NULL);
153   g_assert (src != NULL);
154 
155   fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
156   fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
157 
158   fail_unless (gst_element_link (src, sink) == TRUE);
159 
160   g_object_set (sink, "can-activate-push", TRUE, NULL);
161   g_object_set (sink, "can-activate-pull", FALSE, NULL);
162 
163   g_object_set (src, "can-activate-push", TRUE, NULL);
164   g_object_set (src, "can-activate-pull", FALSE, NULL);
165   g_object_set (src, "num-buffers", 8, NULL);
166 
167   /* set up event probe to count EOS events */
168   srcpad = gst_element_get_static_pad (src, "src");
169   fail_unless (srcpad != NULL);
170 
171   consistency = gst_consistency_checker_new (srcpad);
172 
173   probe = gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH,
174       (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
175 
176   bus = gst_element_get_bus (pipe);
177 
178   gst_element_set_state (pipe, GST_STATE_PLAYING);
179   state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
180   fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
181 
182   msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
183   fail_unless (msg != NULL);
184   fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
185   fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
186 
187   /* should be exactly one EOS event */
188   fail_unless (num_eos == 1);
189 
190   gst_element_set_state (pipe, GST_STATE_NULL);
191   gst_element_get_state (pipe, NULL, NULL, -1);
192 
193   /* make sure source hasn't sent a second one when going PAUSED => READY */
194   fail_unless (num_eos == 1);
195 
196   gst_consistency_checker_free (consistency);
197 
198   gst_pad_remove_probe (srcpad, probe);
199   gst_object_unref (srcpad);
200   gst_message_unref (msg);
201   gst_object_unref (bus);
202   gst_object_unref (pipe);
203 }
204 
205 GST_END_TEST;
206 
207 /* basesrc_eos_events_pull_live_op:
208  *  - make sure source doesn't send an EOS event when operating in
209  *    pull mode and being set to READY explicitly (like one might with
210  *    live sources)
211  */
GST_START_TEST(basesrc_eos_events_pull_live_op)212 GST_START_TEST (basesrc_eos_events_pull_live_op)
213 {
214   GstStateChangeReturn state_ret;
215   GstElement *src, *sink, *pipe;
216   GstPad *srcpad;
217   guint probe, num_eos = 0;
218 
219   pipe = gst_pipeline_new ("pipeline");
220   sink = gst_element_factory_make ("fakesink", "sink");
221   src = gst_element_factory_make ("fakesrc", "src");
222 
223   g_assert (pipe != NULL);
224   g_assert (sink != NULL);
225   g_assert (src != NULL);
226 
227   fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
228   fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
229 
230   fail_unless (gst_element_link (src, sink) == TRUE);
231 
232   g_object_set (sink, "can-activate-push", FALSE, NULL);
233   g_object_set (sink, "can-activate-pull", TRUE, NULL);
234 
235   g_object_set (src, "can-activate-push", FALSE, NULL);
236   g_object_set (src, "can-activate-pull", TRUE, NULL);
237 
238   /* set up event probe to count EOS events */
239   srcpad = gst_element_get_static_pad (src, "src");
240   fail_unless (srcpad != NULL);
241 
242   probe = gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH,
243       (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
244 
245   gst_element_set_state (pipe, GST_STATE_PLAYING);
246   state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
247   fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
248 
249   /* wait a second, then do controlled shutdown */
250   g_usleep (GST_USECOND * 1);
251 
252   /* shut down source only ... */
253   gst_element_set_state (src, GST_STATE_NULL);
254   state_ret = gst_element_get_state (src, NULL, NULL, -1);
255   fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
256 
257   fail_unless (gst_element_set_locked_state (src, TRUE) == TRUE);
258 
259   /* source shouldn't have sent any EOS event in pull mode */
260   fail_unless (num_eos == 0);
261 
262   gst_element_set_state (pipe, GST_STATE_NULL);
263   gst_element_get_state (pipe, NULL, NULL, -1);
264 
265   /* make sure source hasn't sent an EOS when going PAUSED => READY either */
266   fail_unless (num_eos == 0);
267 
268   gst_pad_remove_probe (srcpad, probe);
269   gst_object_unref (srcpad);
270   gst_object_unref (pipe);
271 }
272 
273 GST_END_TEST;
274 
275 /* basesrc_eos_events_pull:
276  *  - makes sure source doesn't send EOS event when reaching the max.
277  *    number of buffers configured in pull-mode
278  *  - make sure source doesn't send EOS event either when being shut down
279  *    (PAUSED => READY state change) after EOSing in pull mode
280  */
GST_START_TEST(basesrc_eos_events_pull)281 GST_START_TEST (basesrc_eos_events_pull)
282 {
283   GstStateChangeReturn state_ret;
284   GstElement *src, *sink, *pipe;
285   GstMessage *msg;
286   GstBus *bus;
287   GstPad *srcpad;
288   guint probe, num_eos = 0;
289 
290   pipe = gst_pipeline_new ("pipeline");
291   sink = gst_element_factory_make ("fakesink", "sink");
292   src = gst_element_factory_make ("fakesrc", "src");
293 
294   g_assert (pipe != NULL);
295   g_assert (sink != NULL);
296   g_assert (src != NULL);
297 
298   fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
299   fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
300 
301   fail_unless (gst_element_link (src, sink) == TRUE);
302 
303   g_object_set (sink, "can-activate-push", FALSE, NULL);
304   g_object_set (sink, "can-activate-pull", TRUE, NULL);
305 
306   g_object_set (src, "can-activate-push", FALSE, NULL);
307   g_object_set (src, "can-activate-pull", TRUE, NULL);
308   g_object_set (src, "num-buffers", 8, NULL);
309 
310   /* set up event probe to count EOS events */
311   srcpad = gst_element_get_static_pad (src, "src");
312   fail_unless (srcpad != NULL);
313 
314   probe = gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH,
315       (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
316 
317   bus = gst_element_get_bus (pipe);
318 
319   gst_element_set_state (pipe, GST_STATE_PLAYING);
320   state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
321   fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
322 
323   msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
324   fail_unless (msg != NULL);
325   fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
326   fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
327 
328   /* source shouldn't have sent any EOS event in pull mode */
329   fail_unless (num_eos == 0);
330 
331   gst_element_set_state (pipe, GST_STATE_NULL);
332   gst_element_get_state (pipe, NULL, NULL, -1);
333 
334   /* make sure source hasn't sent an EOS when going PAUSED => READY either */
335   fail_unless (num_eos == 0);
336 
337   gst_pad_remove_probe (srcpad, probe);
338   gst_object_unref (srcpad);
339   gst_message_unref (msg);
340   gst_object_unref (bus);
341   gst_object_unref (pipe);
342 }
343 
344 GST_END_TEST;
345 
346 
347 /* basesrc_eos_events_push_live_eos:
348  *  - make sure the source stops and emits EOS when we send an EOS event to the
349  *    pipeline.
350  */
GST_START_TEST(basesrc_eos_events_push_live_eos)351 GST_START_TEST (basesrc_eos_events_push_live_eos)
352 {
353   GstStateChangeReturn state_ret;
354   GstElement *src, *sink, *pipe;
355   GstMessage *msg;
356   GstBus *bus;
357   GstPad *srcpad;
358   guint probe, num_eos = 0;
359   gboolean res;
360 
361   pipe = gst_pipeline_new ("pipeline");
362   sink = gst_element_factory_make ("fakesink", "sink");
363   src = gst_element_factory_make ("fakesrc", "src");
364 
365   g_assert (pipe != NULL);
366   g_assert (sink != NULL);
367   g_assert (src != NULL);
368 
369   fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
370   fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
371 
372   fail_unless (gst_element_link (src, sink) == TRUE);
373 
374   g_object_set (sink, "can-activate-push", TRUE, NULL);
375   g_object_set (sink, "can-activate-pull", FALSE, NULL);
376 
377   g_object_set (src, "can-activate-push", TRUE, NULL);
378   g_object_set (src, "can-activate-pull", FALSE, NULL);
379 
380   /* set up event probe to count EOS events */
381   srcpad = gst_element_get_static_pad (src, "src");
382   fail_unless (srcpad != NULL);
383 
384   probe = gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH,
385       (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
386 
387   bus = gst_element_get_bus (pipe);
388 
389   gst_element_set_state (pipe, GST_STATE_PLAYING);
390   state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
391   fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
392 
393   /* wait a second, then emit the EOS */
394   g_usleep (GST_USECOND * 1);
395 
396   /* shut down source only (should send EOS event) ... */
397   res = gst_element_send_event (pipe, gst_event_new_eos ());
398   fail_unless (res == TRUE);
399 
400   /* ... and wait for the EOS message from the sink */
401   msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
402   fail_unless (msg != NULL);
403   fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
404   fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
405 
406   /* should be exactly one EOS event */
407   fail_unless (num_eos == 1);
408 
409   gst_element_set_state (pipe, GST_STATE_NULL);
410   gst_element_get_state (pipe, NULL, NULL, -1);
411 
412   /* make sure source hasn't sent a second one when going PAUSED => READY */
413   fail_unless (num_eos == 1);
414 
415   gst_pad_remove_probe (srcpad, probe);
416   gst_object_unref (srcpad);
417   gst_message_unref (msg);
418   gst_object_unref (bus);
419   gst_object_unref (pipe);
420 }
421 
422 GST_END_TEST;
423 
424 /* basesrc_eos_events_pull_live_eos:
425  *  - make sure the source stops and emits EOS when we send an EOS event to the
426  *    pipeline.
427  */
GST_START_TEST(basesrc_eos_events_pull_live_eos)428 GST_START_TEST (basesrc_eos_events_pull_live_eos)
429 {
430   GstStateChangeReturn state_ret;
431   GstElement *src, *sink, *pipe;
432   GstMessage *msg;
433   GstBus *bus;
434   GstPad *srcpad;
435   guint probe, num_eos = 0;
436   gboolean res;
437 
438   pipe = gst_pipeline_new ("pipeline");
439   sink = gst_element_factory_make ("fakesink", "sink");
440   src = gst_element_factory_make ("fakesrc", "src");
441 
442   g_assert (pipe != NULL);
443   g_assert (sink != NULL);
444   g_assert (src != NULL);
445 
446   fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
447   fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
448 
449   fail_unless (gst_element_link (src, sink) == TRUE);
450 
451   g_object_set (sink, "can-activate-push", FALSE, NULL);
452   g_object_set (sink, "can-activate-pull", TRUE, NULL);
453 
454   g_object_set (src, "can-activate-push", FALSE, NULL);
455   g_object_set (src, "can-activate-pull", TRUE, NULL);
456 
457   /* set up event probe to count EOS events */
458   srcpad = gst_element_get_static_pad (src, "src");
459   fail_unless (srcpad != NULL);
460 
461   probe = gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH,
462       (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
463 
464   bus = gst_element_get_bus (pipe);
465 
466   gst_element_set_state (pipe, GST_STATE_PLAYING);
467   state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
468   fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
469 
470   /* wait a second, then emit the EOS */
471   g_usleep (GST_USECOND * 1);
472 
473   /* shut down source only (should send EOS event) ... */
474   res = gst_element_send_event (pipe, gst_event_new_eos ());
475   fail_unless (res == TRUE);
476 
477   /* ... and wait for the EOS message from the sink */
478   msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
479   fail_unless (msg != NULL);
480   fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
481   fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
482 
483   /* no EOS in pull mode */
484   fail_unless (num_eos == 0);
485 
486   gst_element_set_state (pipe, GST_STATE_NULL);
487   gst_element_get_state (pipe, NULL, NULL, -1);
488 
489   /* make sure source hasn't sent a second one when going PAUSED => READY */
490   fail_unless (num_eos == 0);
491 
492   gst_pad_remove_probe (srcpad, probe);
493   gst_object_unref (srcpad);
494   gst_message_unref (msg);
495   gst_object_unref (bus);
496   gst_object_unref (pipe);
497 }
498 
499 GST_END_TEST;
500 
501 
502 static GstPadProbeReturn
segment_event_catcher(GstObject * pad,GstPadProbeInfo * info,gpointer * user_data)503 segment_event_catcher (GstObject * pad, GstPadProbeInfo * info,
504     gpointer * user_data)
505 {
506   GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
507   GstEvent **last_event = (GstEvent **) user_data;
508   fail_unless (event != NULL);
509   fail_unless (GST_IS_EVENT (event));
510   fail_unless (user_data != NULL);
511 
512   if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
513     g_mutex_lock (&check_mutex);
514     fail_unless (*last_event == NULL);
515     *last_event = gst_event_copy (event);
516     g_cond_signal (&check_cond);
517     g_mutex_unlock (&check_mutex);
518   }
519 
520   return GST_PAD_PROBE_OK;
521 }
522 
523 /* basesrc_seek_events_rate_update:
524  *  - make sure we get expected segment after sending a seek event
525  */
GST_START_TEST(basesrc_seek_events_rate_update)526 GST_START_TEST (basesrc_seek_events_rate_update)
527 {
528   GstStateChangeReturn state_ret;
529   GstElement *src, *sink, *pipe;
530   GstMessage *msg;
531   GstBus *bus;
532   GstPad *probe_pad;
533   guint probe;
534   GstEvent *seg_event = NULL;
535   GstEvent *rate_seek;
536   gboolean event_ret;
537   const GstSegment *segment;
538 
539   pipe = gst_pipeline_new ("pipeline");
540   sink = gst_element_factory_make ("fakesink", "sink");
541   src = gst_element_factory_make ("fakesrc", "src");
542 
543   g_assert (pipe != NULL);
544   g_assert (sink != NULL);
545   g_assert (src != NULL);
546 
547   fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
548   fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
549 
550   fail_unless (gst_element_link (src, sink) == TRUE);
551 
552   bus = gst_element_get_bus (pipe);
553 
554   /* set up event probe to catch new segment event */
555   probe_pad = gst_element_get_static_pad (sink, "sink");
556   fail_unless (probe_pad != NULL);
557 
558   probe = gst_pad_add_probe (probe_pad, GST_PAD_PROBE_TYPE_EVENT_BOTH,
559       (GstPadProbeCallback) segment_event_catcher, &seg_event, NULL);
560 
561   /* prepare the seek */
562   rate_seek = gst_event_new_seek (0.5, GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
563       GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE,
564       GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
565 
566   GST_INFO ("going to playing");
567 
568   /* play */
569   gst_element_set_state (pipe, GST_STATE_PLAYING);
570   state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
571   fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
572 
573   /* wait for the first segment to be posted, and flush it ... */
574   g_mutex_lock (&check_mutex);
575   while (seg_event == NULL)
576     g_cond_wait (&check_cond, &check_mutex);
577   gst_event_unref (seg_event);
578   seg_event = NULL;
579   g_mutex_unlock (&check_mutex);
580 
581   GST_INFO ("seeking");
582 
583   /* seek */
584   event_ret = gst_element_send_event (pipe, rate_seek);
585   fail_unless (event_ret == TRUE);
586 
587   /* wait for the updated segment to be posted, posting EOS make the loop
588    * thread exit before the updated segment is posted ... */
589   g_mutex_lock (&check_mutex);
590   while (seg_event == NULL)
591     g_cond_wait (&check_cond, &check_mutex);
592   g_mutex_unlock (&check_mutex);
593 
594   /* shut down pipeline only (should send EOS message) ... */
595   gst_element_send_event (pipe, gst_event_new_eos ());
596 
597   /* ... and wait for the EOS message from the sink */
598   msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
599   fail_unless (msg != NULL);
600   fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
601   fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
602 
603   gst_element_set_state (pipe, GST_STATE_NULL);
604   gst_element_get_state (pipe, NULL, NULL, -1);
605 
606   GST_INFO ("stopped");
607 
608   /* check that we have go the event */
609   fail_unless (seg_event != NULL);
610 
611   gst_event_parse_segment (seg_event, &segment);
612   fail_unless (segment->rate == 0.5);
613 
614   gst_pad_remove_probe (probe_pad, probe);
615   gst_object_unref (probe_pad);
616   gst_message_unref (msg);
617   gst_event_unref (seg_event);
618   gst_object_unref (bus);
619   gst_object_unref (pipe);
620 }
621 
622 GST_END_TEST;
623 
624 
625 typedef struct
626 {
627   gboolean seeked;
628   gint buffer_count;
629   GList *events;
630 } LastBufferSeekData;
631 
632 static GstPadProbeReturn
seek_on_buffer(GstObject * pad,GstPadProbeInfo * info,gpointer * user_data)633 seek_on_buffer (GstObject * pad, GstPadProbeInfo * info, gpointer * user_data)
634 {
635   LastBufferSeekData *data = (LastBufferSeekData *) user_data;
636 
637   fail_unless (user_data != NULL);
638 
639   if (info->type & GST_PAD_PROBE_TYPE_BUFFER) {
640     data->buffer_count++;
641 
642     if (!data->seeked) {
643       fail_unless (gst_pad_push_event (GST_PAD (pad),
644               gst_event_new_seek (1.0, GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH,
645                   GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 1)));
646       data->seeked = TRUE;
647     }
648   } else if (info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) {
649     data->events = g_list_append (data->events, gst_event_ref (info->data));
650   } else {
651     fail ("Should not be reached");
652   }
653   return GST_PAD_PROBE_OK;
654 }
655 
656 /* basesrc_seek_on_last_buffer:
657  *  - make sure basesrc doesn't go eos if a seek is sent
658  * after the last buffer push
659  *
660  * This is just a test and is a controlled environment.
661  * For testing purposes sending the seek from the streaming
662  * thread is ok but doing this in an application might not
663  * be a good idea.
664  */
GST_START_TEST(basesrc_seek_on_last_buffer)665 GST_START_TEST (basesrc_seek_on_last_buffer)
666 {
667   GstStateChangeReturn state_ret;
668   GstElement *src, *sink, *pipe;
669   GstMessage *msg;
670   GstBus *bus;
671   GstPad *probe_pad;
672   guint probe;
673   GstEvent *seek;
674   LastBufferSeekData seek_data;
675 
676   pipe = gst_pipeline_new ("pipeline");
677   sink = gst_element_factory_make ("fakesink", "sink");
678   src = gst_element_factory_make ("fakesrc", "src");
679 
680   g_assert (pipe != NULL);
681   g_assert (sink != NULL);
682   g_assert (src != NULL);
683 
684   /* use 'sizemax' buffers to avoid receiving empty buffers */
685   g_object_set (src, "sizetype", 2, NULL);
686 
687   fail_unless (gst_bin_add (GST_BIN (pipe), src) == TRUE);
688   fail_unless (gst_bin_add (GST_BIN (pipe), sink) == TRUE);
689 
690   fail_unless (gst_element_link (src, sink) == TRUE);
691 
692   bus = gst_element_get_bus (pipe);
693 
694   /* set up probe to catch the last buffer and send a seek event */
695   probe_pad = gst_element_get_static_pad (sink, "sink");
696   fail_unless (probe_pad != NULL);
697 
698   seek_data.buffer_count = 0;
699   seek_data.seeked = FALSE;
700   seek_data.events = NULL;
701 
702   probe =
703       gst_pad_add_probe (probe_pad,
704       GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
705       (GstPadProbeCallback) seek_on_buffer, &seek_data, NULL);
706 
707   /* prepare the segment so that it has only one buffer */
708   seek = gst_event_new_seek (1, GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
709       GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 1);
710 
711   gst_element_set_state (pipe, GST_STATE_READY);
712   fail_unless (gst_element_send_event (src, seek));
713 
714   GST_INFO ("going to playing");
715 
716   /* play */
717   gst_element_set_state (pipe, GST_STATE_PLAYING);
718   state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
719   fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
720 
721   /* ... and wait for the EOS message from the sink */
722   msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
723   fail_unless (msg != NULL);
724   fail_unless (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ERROR);
725   fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS);
726 
727   gst_element_set_state (pipe, GST_STATE_NULL);
728   gst_element_get_state (pipe, NULL, NULL, -1);
729 
730   GST_INFO ("stopped");
731 
732   /* check that we have go the event */
733   fail_unless (seek_data.buffer_count == 2);
734   fail_unless (seek_data.seeked);
735 
736   /* events: stream-start -> segment -> segment -> eos */
737   fail_unless (g_list_length (seek_data.events) == 4);
738   {
739     GstEvent *event;
740 
741     event = seek_data.events->data;
742     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
743     gst_event_unref (event);
744     seek_data.events = g_list_delete_link (seek_data.events, seek_data.events);
745 
746     event = seek_data.events->data;
747     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
748     gst_event_unref (event);
749     seek_data.events = g_list_delete_link (seek_data.events, seek_data.events);
750 
751     event = seek_data.events->data;
752     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
753     gst_event_unref (event);
754     seek_data.events = g_list_delete_link (seek_data.events, seek_data.events);
755 
756     event = seek_data.events->data;
757     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_EOS);
758     gst_event_unref (event);
759     seek_data.events = g_list_delete_link (seek_data.events, seek_data.events);
760   }
761 
762   gst_pad_remove_probe (probe_pad, probe);
763   gst_object_unref (probe_pad);
764   gst_message_unref (msg);
765   gst_object_unref (bus);
766   gst_object_unref (pipe);
767 }
768 
769 GST_END_TEST;
770 
771 typedef GstBaseSrc TestSrc;
772 typedef GstBaseSrcClass TestSrcClass;
773 
774 static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
775     GST_PAD_SRC,
776     GST_PAD_ALWAYS,
777     GST_STATIC_CAPS_ANY);
778 
779 static GType test_src_get_type (void);
780 
781 G_DEFINE_TYPE (TestSrc, test_src, GST_TYPE_BASE_SRC);
782 
783 static void
test_src_init(TestSrc * src)784 test_src_init (TestSrc * src)
785 {
786 }
787 
788 static GstFlowReturn
test_src_create(GstBaseSrc * src,guint64 offset,guint size,GstBuffer ** p_buf)789 test_src_create (GstBaseSrc * src, guint64 offset, guint size,
790     GstBuffer ** p_buf)
791 {
792   GstBuffer *buf;
793   static int num = 0;
794 
795   fail_if (*p_buf != NULL);
796 
797   buf = gst_buffer_new ();
798   GST_BUFFER_OFFSET (buf) = num++;
799 
800   if (num == 1 || g_random_boolean ()) {
801     GstBufferList *buflist = gst_buffer_list_new ();
802 
803     gst_buffer_list_add (buflist, buf);
804 
805     buf = gst_buffer_new ();
806     GST_BUFFER_OFFSET (buf) = num++;
807     gst_buffer_list_add (buflist, buf);
808     gst_base_src_submit_buffer_list (src, buflist);
809   } else {
810     *p_buf = buf;
811   }
812 
813   return GST_FLOW_OK;
814 }
815 
816 static void
test_src_class_init(TestSrcClass * klass)817 test_src_class_init (TestSrcClass * klass)
818 {
819   GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
820 
821   gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
822       &src_template);
823 
824   gstbasesrc_class->create = test_src_create;
825 }
826 
827 static GstPad *mysinkpad;
828 
829 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
830     GST_PAD_SINK,
831     GST_PAD_ALWAYS,
832     GST_STATIC_CAPS_ANY);
833 
834 #define NUM_BUFFERS 100
835 static gboolean done;
836 static guint expect_offset;
837 
838 static GstFlowReturn
chain_____func(GstPad * pad,GstObject * parent,GstBuffer * buf)839 chain_____func (GstPad * pad, GstObject * parent, GstBuffer * buf)
840 {
841   GST_LOG ("  buffer # %3u", (guint) GST_BUFFER_OFFSET (buf));
842 
843   fail_unless_equals_int (GST_BUFFER_OFFSET (buf), expect_offset);
844   ++expect_offset;
845 
846   if (GST_BUFFER_OFFSET (buf) > NUM_BUFFERS) {
847     g_mutex_lock (&check_mutex);
848     done = TRUE;
849     g_cond_signal (&check_cond);
850     g_mutex_unlock (&check_mutex);
851   }
852   gst_buffer_unref (buf);
853 
854   return GST_FLOW_OK;
855 }
856 
857 static GstFlowReturn
chainlist_func(GstPad * pad,GstObject * parent,GstBufferList * list)858 chainlist_func (GstPad * pad, GstObject * parent, GstBufferList * list)
859 {
860   guint i, len;
861 
862   len = gst_buffer_list_length (list);
863 
864   GST_DEBUG ("buffer list with %u buffers", len);
865   for (i = 0; i < len; ++i) {
866     GstBuffer *buf = gst_buffer_list_get (list, i);
867     GST_LOG ("  buffer # %3u", (guint) GST_BUFFER_OFFSET (buf));
868 
869     fail_unless_equals_int (GST_BUFFER_OFFSET (buf), expect_offset);
870     ++expect_offset;
871   }
872 
873   gst_buffer_list_unref (list);
874   return GST_FLOW_OK;
875 }
876 
GST_START_TEST(basesrc_create_bufferlist)877 GST_START_TEST (basesrc_create_bufferlist)
878 {
879   GstElement *src;
880 
881   src = g_object_new (test_src_get_type (), NULL);
882 
883   mysinkpad = gst_check_setup_sink_pad (src, &sinktemplate);
884   gst_pad_set_chain_function (mysinkpad, chain_____func);
885   gst_pad_set_chain_list_function (mysinkpad, chainlist_func);
886   gst_pad_set_active (mysinkpad, TRUE);
887 
888   done = FALSE;
889   expect_offset = 0;
890 
891   gst_element_set_state (src, GST_STATE_PLAYING);
892 
893   g_mutex_lock (&check_mutex);
894   while (!done)
895     g_cond_wait (&check_cond, &check_mutex);
896   g_mutex_unlock (&check_mutex);
897 
898   gst_element_set_state (src, GST_STATE_NULL);
899 
900   gst_check_teardown_sink_pad (src);
901 
902   gst_object_unref (src);
903 }
904 
905 GST_END_TEST;
906 
907 typedef struct
908 {
909   GstBaseSrc parent;
910   GstSegment *segment;
911   gboolean n_output_buffers;
912   gsize num_times_negotiate_called;
913   gboolean do_renegotiate;
914 } TimeSrc;
915 
916 typedef GstBaseSrcClass TimeSrcClass;
917 
918 static GType time_src_get_type (void);
919 
920 G_DEFINE_TYPE (TimeSrc, time_src, GST_TYPE_BASE_SRC);
921 
922 static void
time_src_init(TimeSrc * src)923 time_src_init (TimeSrc * src)
924 {
925   gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
926   gst_base_src_set_automatic_eos (GST_BASE_SRC (src), FALSE);
927   src->n_output_buffers = 0;
928   src->num_times_negotiate_called = 0;
929   src->do_renegotiate = FALSE;
930 }
931 
932 /* This test src outputs a compressed format, with a single GOP
933  * starting at PTS 0.
934  *
935  * This means that in reverse playback, we may want to output
936  * buffers outside the segment bounds, and decide when to EOS
937  * from the create function.
938  */
939 static GstFlowReturn
time_src_create(GstBaseSrc * bsrc,guint64 offset,guint size,GstBuffer ** p_buf)940 time_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
941     GstBuffer ** p_buf)
942 {
943   TimeSrc *src = (TimeSrc *) bsrc;
944 
945   if (src->segment->position >= src->segment->stop)
946     return GST_FLOW_EOS;
947 
948   if (src->do_renegotiate) {
949     gst_base_src_negotiate (bsrc);
950     src->do_renegotiate = FALSE;
951   }
952 
953   *p_buf = gst_buffer_new ();
954   GST_BUFFER_PTS (*p_buf) = src->segment->position;
955   GST_BUFFER_DURATION (*p_buf) = GST_SECOND;
956   src->segment->position += GST_SECOND;
957 
958   src->n_output_buffers++;
959 
960   return GST_FLOW_OK;
961 }
962 
963 static gboolean
time_src_do_seek(GstBaseSrc * bsrc,GstSegment * segment)964 time_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
965 {
966   TimeSrc *src = (TimeSrc *) bsrc;
967   fail_unless (segment->format == GST_FORMAT_TIME);
968 
969   if (src->segment)
970     gst_segment_free (src->segment);
971 
972   src->segment = gst_segment_copy (segment);
973 
974   ((TimeSrc *) bsrc)->segment->position = 0;
975 
976   return TRUE;
977 }
978 
979 static gboolean
time_src_is_seekable(GstBaseSrc * bsrc)980 time_src_is_seekable (GstBaseSrc * bsrc)
981 {
982   return TRUE;
983 }
984 
985 static gboolean
time_src_negotiate(GstBaseSrc * bsrc)986 time_src_negotiate (GstBaseSrc * bsrc)
987 {
988   TimeSrc *src = (TimeSrc *) bsrc;
989   src->num_times_negotiate_called++;
990   return GST_BASE_SRC_CLASS (time_src_parent_class)->negotiate (bsrc);
991 }
992 
993 static void
time_src_class_init(TimeSrcClass * klass)994 time_src_class_init (TimeSrcClass * klass)
995 {
996   GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
997 
998   gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
999       &src_template);
1000 
1001   gstbasesrc_class->create = time_src_create;
1002   gstbasesrc_class->do_seek = time_src_do_seek;
1003   gstbasesrc_class->is_seekable = time_src_is_seekable;
1004   gstbasesrc_class->negotiate = time_src_negotiate;
1005 }
1006 
GST_START_TEST(basesrc_time_automatic_eos)1007 GST_START_TEST (basesrc_time_automatic_eos)
1008 {
1009   GstElement *src, *sink;
1010   GstElement *pipe;
1011   GstBus *bus;
1012 
1013   src = g_object_new (time_src_get_type (), NULL);
1014   sink = gst_element_factory_make ("fakesink", NULL);
1015 
1016   pipe = gst_pipeline_new (NULL);
1017 
1018   gst_bin_add (GST_BIN (pipe), src);
1019   gst_bin_add (GST_BIN (pipe), sink);
1020 
1021   gst_element_link (src, sink);
1022 
1023   gst_element_set_state (pipe, GST_STATE_PAUSED);
1024   gst_element_get_state (pipe, NULL, NULL, GST_CLOCK_TIME_NONE);
1025 
1026   gst_element_seek (pipe, -1.0, GST_FORMAT_TIME,
1027       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET,
1028       GST_SECOND, GST_SEEK_TYPE_SET, 2 * GST_SECOND);
1029 
1030   gst_element_set_state (pipe, GST_STATE_PLAYING);
1031 
1032   bus = gst_pipeline_get_bus (GST_PIPELINE (pipe));
1033 
1034   gst_message_unref (gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
1035           GST_MESSAGE_EOS));
1036 
1037   gst_element_set_state (pipe, GST_STATE_NULL);
1038 
1039   /* - One preroll buffer
1040    * - One (1-second) buffer outside the segment, our "keyframe"
1041    * - One buffer inside the segment
1042    */
1043   fail_unless_equals_int (((TimeSrc *) src)->n_output_buffers, 3);
1044 
1045   if (((TimeSrc *) src)->segment)
1046     gst_segment_free (((TimeSrc *) src)->segment);
1047 
1048   gst_object_unref (bus);
1049   gst_object_unref (pipe);
1050 }
1051 
1052 GST_END_TEST;
1053 
GST_START_TEST(basesrc_negotiate)1054 GST_START_TEST (basesrc_negotiate)
1055 {
1056   GstElement *src, *sink;
1057   GstElement *pipe;
1058   GstSegment seg;
1059 
1060   src = g_object_new (time_src_get_type (), NULL);
1061   sink = gst_element_factory_make ("fakesink", NULL);
1062 
1063   pipe = gst_pipeline_new (NULL);
1064 
1065   gst_bin_add (GST_BIN (pipe), src);
1066   gst_bin_add (GST_BIN (pipe), sink);
1067 
1068   gst_element_link (src, sink);
1069 
1070   /* Use some default segment to get the stream going. */
1071   gst_segment_init (&seg, GST_FORMAT_TIME);
1072   ((TimeSrc *) src)->segment = gst_segment_copy (&seg);
1073 
1074   /* Check that gst_base_src_negotiate () actually ends up calling
1075    * the negotiate () vmethod by first running the test pipeline
1076    * normally, and then running it with a gst_base_src_negotiate ()
1077    * call, and checking how many times negotiate () was called in
1078    * both cases. */
1079 
1080   /* Run pipeline, keep do_renegotiate at FALSE, so
1081    * gst_base_src_negotiate () won't be called. negotiate () still
1082    * will be called once, as part of the regular caps negotiation
1083    * sequence. */
1084   fail_unless (((TimeSrc *) src)->num_times_negotiate_called == 0);
1085   gst_element_set_state (pipe, GST_STATE_PLAYING);
1086   gst_element_get_state (pipe, NULL, NULL, GST_CLOCK_TIME_NONE);
1087   fail_unless (((TimeSrc *) src)->num_times_negotiate_called == 1);
1088   gst_element_set_state (pipe, GST_STATE_NULL);
1089 
1090   ((TimeSrc *) src)->num_times_negotiate_called = 0;
1091 
1092   /* Run pipeline, set do_renegotiate to TRUE. This will cause
1093    * negotiate () to be called twice: Once during caps negotiation,
1094    * and once by the gst_base_src_negotiate () call in the
1095    * time_src_create () function. */
1096   ((TimeSrc *) src)->do_renegotiate = TRUE;
1097   fail_unless (((TimeSrc *) src)->num_times_negotiate_called == 0);
1098   gst_element_set_state (pipe, GST_STATE_PLAYING);
1099   gst_element_get_state (pipe, NULL, NULL, GST_CLOCK_TIME_NONE);
1100   fail_unless (((TimeSrc *) src)->num_times_negotiate_called == 2);
1101   gst_element_set_state (pipe, GST_STATE_NULL);
1102 
1103   if (((TimeSrc *) src)->segment)
1104     gst_segment_free (((TimeSrc *) src)->segment);
1105 
1106   gst_object_unref (pipe);
1107 }
1108 
1109 GST_END_TEST;
1110 
1111 static Suite *
gst_basesrc_suite(void)1112 gst_basesrc_suite (void)
1113 {
1114   Suite *s = suite_create ("GstBaseSrc");
1115   TCase *tc = tcase_create ("general");
1116 
1117   suite_add_tcase (s, tc);
1118   tcase_add_test (tc, basesrc_eos_events_pull);
1119   tcase_add_test (tc, basesrc_eos_events_push);
1120   tcase_add_test (tc, basesrc_eos_events_push_live_op);
1121   tcase_add_test (tc, basesrc_eos_events_pull_live_op);
1122   tcase_add_test (tc, basesrc_eos_events_push_live_eos);
1123   tcase_add_test (tc, basesrc_eos_events_pull_live_eos);
1124   tcase_add_test (tc, basesrc_seek_events_rate_update);
1125   tcase_add_test (tc, basesrc_seek_on_last_buffer);
1126   tcase_add_test (tc, basesrc_create_bufferlist);
1127   tcase_add_test (tc, basesrc_time_automatic_eos);
1128   tcase_add_test (tc, basesrc_negotiate);
1129 
1130   return s;
1131 }
1132 
1133 GST_CHECK_MAIN (gst_basesrc);
1134