ges: tests: Use correct variable types when setting properties
[platform/upstream/gstreamer.git] / subprojects / gst-editing-services / tests / check / nle / nlecomposition.c
1 /* Gnonlin
2  * Copyright (C) <2009> Alessandro Decina <alessandro.decina@collabora.co.uk>
3  *
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.
8  *
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.
13  *
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., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 #include "common.h"
20
21 typedef struct
22 {
23   GstElement *composition;
24   GstElement *source3;
25 } TestClosure;
26
27 static int seek_events;
28
29 static GstPadProbeReturn
30 on_source1_pad_event_cb (GstPad * pad, GstPadProbeInfo * info,
31     gpointer user_data)
32 {
33   if (GST_EVENT_TYPE (info->data) == GST_EVENT_SEEK)
34     ++seek_events;
35
36   return GST_PAD_PROBE_OK;
37 }
38
39 GST_START_TEST (test_change_object_start_stop_in_current_stack)
40 {
41   GstPad *srcpad;
42   GstElement *pipeline;
43   GstElement *comp, *source1, *def, *sink;
44   GstBus *bus;
45   GstMessage *message;
46   gboolean carry_on, ret = FALSE;
47
48   ges_init ();
49
50   pipeline = gst_pipeline_new ("test_pipeline");
51   comp =
52       gst_element_factory_make_or_warn ("nlecomposition", "test_composition");
53
54   gst_element_set_state (comp, GST_STATE_READY);
55
56   sink = gst_element_factory_make_or_warn ("fakevideosink", "sink");
57   gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL);
58
59   gst_element_link (comp, sink);
60
61   /*
62      source1
63      Start : 0s
64      Duration : 2s
65      Priority : 2
66    */
67
68   source1 = videotest_nle_src ("source1", 0, 2 * GST_SECOND, 2, 2);
69   srcpad = gst_element_get_static_pad (source1, "src");
70   gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
71       (GstPadProbeCallback) on_source1_pad_event_cb, NULL, NULL);
72   gst_object_unref (srcpad);
73
74   /*
75      def (default source)
76      Priority = G_MAXUINT32
77    */
78   def =
79       videotest_nle_src ("default", 0 * GST_SECOND, 0 * GST_SECOND, 2,
80       G_MAXUINT32);
81   g_object_set (def, "expandable", TRUE, NULL);
82
83   ASSERT_OBJECT_REFCOUNT (source1, "source1", 1);
84   ASSERT_OBJECT_REFCOUNT (def, "default", 1);
85
86   /* Add source 1 */
87
88   nle_composition_add (GST_BIN (comp), source1);
89   nle_composition_add (GST_BIN (comp), def);
90   commit_and_wait (comp, &ret);
91   check_start_stop_duration (source1, 0, 2 * GST_SECOND, 2 * GST_SECOND);
92   check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND);
93
94   bus = gst_element_get_bus (GST_ELEMENT (pipeline));
95
96   GST_DEBUG ("Setting pipeline to PAUSED");
97   ASSERT_OBJECT_REFCOUNT (source1, "source1", 1);
98
99   fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
100           GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE);
101
102   GST_DEBUG ("Let's poll the bus");
103
104   carry_on = TRUE;
105   while (carry_on) {
106     message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 10);
107     if (message) {
108       switch (GST_MESSAGE_TYPE (message)) {
109         case GST_MESSAGE_ASYNC_DONE:
110         {
111           carry_on = FALSE;
112           GST_DEBUG ("Pipeline reached PAUSED, stopping polling");
113           break;
114         }
115         case GST_MESSAGE_EOS:
116         {
117           GST_WARNING ("Saw EOS");
118
119           fail_if (TRUE);
120         }
121         case GST_MESSAGE_ERROR:
122           fail_error_message (message);
123         default:
124           break;
125       }
126       gst_mini_object_unref (GST_MINI_OBJECT (message));
127     }
128   }
129
130
131   /* pipeline is paused at this point */
132
133   /* move source1 out of the active segment */
134   g_object_set (source1, "start", (guint64) 4 * GST_SECOND, NULL);
135   commit_and_wait (comp, &ret);
136
137   /* remove source1 from the composition, which will become empty and remove the
138    * ghostpad */
139
140
141   /* keep an extra ref to source1 as we remove it from the bin */
142   gst_object_ref (source1);
143   fail_unless (nle_composition_remove (GST_BIN (comp), source1));
144   g_object_set (source1, "start", (guint64) 0 * GST_SECOND, NULL);
145   /* add the source again and check that the ghostpad is added again */
146   nle_composition_add (GST_BIN (comp), source1);
147   gst_object_unref (source1);
148   commit_and_wait (comp, &ret);
149
150
151   g_object_set (source1, "duration", (guint64) 1 * GST_SECOND, NULL);
152   commit_and_wait (comp, &ret);
153
154   GST_DEBUG ("Setting pipeline to NULL");
155
156   fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
157           GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE);
158   gst_element_set_state (source1, GST_STATE_NULL);
159
160   GST_DEBUG ("Resetted pipeline to NULL");
161
162   ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "main pipeline", 1, 2);
163   gst_check_objects_destroyed_on_unref (pipeline, comp, def, NULL);
164   ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "main bus", 1, 2);
165   gst_object_unref (bus);
166
167   ges_deinit ();
168 }
169
170 GST_END_TEST;
171
172 GST_START_TEST (test_remove_invalid_object)
173 {
174   GstBin *composition;
175   GstElement *source1, *source2;
176
177   ges_init ();
178
179   composition = GST_BIN (gst_element_factory_make ("nlecomposition",
180           "composition"));
181   gst_element_set_state (GST_ELEMENT (composition), GST_STATE_READY);
182
183   source1 = gst_element_factory_make ("nlesource", "source1");
184   source2 = gst_element_factory_make ("nlesource", "source2");
185
186   nle_composition_add (composition, source1);
187   nle_composition_remove (composition, source2);
188   fail_unless (nle_composition_remove (composition, source1));
189
190   gst_element_set_state (GST_ELEMENT (composition), GST_STATE_NULL);
191   gst_object_unref (composition);
192   gst_object_unref (source2);
193
194   ges_deinit ();
195 }
196
197 GST_END_TEST;
198
199 GST_START_TEST (test_remove_last_object)
200 {
201   GstBin *composition;
202   GstElement *source1, *audiotestsrc, *source2, *audiotestsrc2, *fakesink,
203       *pipeline;
204   GstBus *bus;
205   GstMessage *message;
206   gboolean ret;
207   gint64 position = 0;
208   GstClockTime duration;
209
210   ges_init ();
211
212   pipeline = GST_ELEMENT (gst_pipeline_new (NULL));
213   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
214
215   composition = GST_BIN (gst_element_factory_make ("nlecomposition",
216           "composition"));
217
218   gst_element_set_state (GST_ELEMENT (composition), GST_STATE_READY);
219
220   fakesink = gst_element_factory_make ("fakeaudiosink", NULL);
221   gst_bin_add_many (GST_BIN (pipeline), GST_ELEMENT (composition), fakesink,
222       NULL);
223   gst_element_link (GST_ELEMENT (composition), fakesink);
224
225   source1 = gst_element_factory_make ("nlesource", "source1");
226   audiotestsrc = gst_element_factory_make ("audiotestsrc", "audiotestsrc1");
227   gst_bin_add (GST_BIN (source1), audiotestsrc);
228   g_object_set (source1, "start", (guint64) 0 * GST_SECOND,
229       "duration", (gint64) 10 * GST_SECOND, "inpoint", (guint64) 0, "priority",
230       1, NULL);
231
232   nle_composition_add (composition, source1);
233
234   source2 = gst_element_factory_make ("nlesource", "source1");
235   audiotestsrc2 = gst_element_factory_make ("audiotestsrc", "audiotestsrc1");
236   gst_bin_add (GST_BIN (source2), audiotestsrc2);
237   g_object_set (source2, "start", (guint64) 10 * GST_SECOND,
238       "duration", (gint64) 10 * GST_SECOND, "inpoint", (guint64) 0, "priority",
239       1, NULL);
240
241   nle_composition_add (composition, source2);
242
243   fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED)
244       == GST_STATE_CHANGE_FAILURE);
245   message = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
246       GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR);
247   gst_mini_object_unref (GST_MINI_OBJECT (message));
248
249   commit_and_wait (GST_ELEMENT (composition), &ret);
250
251   message = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
252       GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR);
253   gst_mini_object_unref (GST_MINI_OBJECT (message));
254
255   gst_element_seek_simple (pipeline,
256       GST_FORMAT_TIME,
257       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, 15 * GST_SECOND);
258
259   message = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
260       GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR);
261   gst_mini_object_unref (GST_MINI_OBJECT (message));
262
263   ret =
264       gst_element_query_position (GST_ELEMENT (pipeline), GST_FORMAT_TIME,
265       &position);
266   fail_unless_equals_uint64 (position, 15 * GST_SECOND);
267
268   gst_element_seek_simple (pipeline,
269       GST_FORMAT_TIME,
270       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, 18 * GST_SECOND);
271
272   message = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
273       GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR);
274   gst_mini_object_unref (GST_MINI_OBJECT (message));
275
276   ret =
277       gst_element_query_position (GST_ELEMENT (pipeline), GST_FORMAT_TIME,
278       &position);
279   fail_unless_equals_uint64 (position, 18 * GST_SECOND);
280
281   nle_composition_remove (composition, source2);
282
283   commit_and_wait (GST_ELEMENT (composition), &ret);
284   g_object_get (composition, "duration", &duration, NULL);
285   fail_unless_equals_uint64 (duration, 10 * GST_SECOND);
286
287   ret =
288       gst_element_query_position (GST_ELEMENT (pipeline), GST_FORMAT_TIME,
289       &position);
290   fail_unless_equals_uint64 (position, 10 * GST_SECOND - 1);
291
292   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
293   gst_object_unref (pipeline);
294   gst_object_unref (bus);
295
296   ges_deinit ();
297 }
298
299 GST_END_TEST;
300
301 GST_START_TEST (test_dispose_on_commit)
302 {
303   GstElement *composition;
304   GstElement *nlesource;
305   GstElement *audiotestsrc;
306   GstElement *pipeline, *fakesink;
307   gboolean ret;
308
309   ges_init ();
310
311   composition = gst_element_factory_make ("nlecomposition", "composition");
312   pipeline = GST_ELEMENT (gst_pipeline_new (NULL));
313   fakesink = gst_element_factory_make ("fakevideosink", NULL);
314
315   nlesource = gst_element_factory_make ("nlesource", "nlesource1");
316   audiotestsrc = gst_element_factory_make ("audiotestsrc", "audiotestsrc1");
317   gst_bin_add (GST_BIN (nlesource), audiotestsrc);
318   g_object_set (nlesource, "start", (guint64) 0 * GST_SECOND,
319       "duration", (gint64) 10 * GST_SECOND, "inpoint", (guint64) 0, "priority",
320       1, NULL);
321   fail_unless (nle_composition_add (GST_BIN (composition), nlesource));
322
323   gst_bin_add_many (GST_BIN (pipeline), composition, fakesink, NULL);
324   fail_unless (gst_element_link (composition, fakesink) == TRUE);
325
326
327   ASSERT_OBJECT_REFCOUNT (composition, "composition", 1);
328   g_signal_emit_by_name (composition, "commit", TRUE, &ret);
329
330   gst_object_unref (pipeline);
331
332   ges_deinit ();
333 }
334
335 GST_END_TEST;
336
337 GST_START_TEST (test_simple_audiomixer)
338 {
339   GstBus *bus;
340   GstMessage *message;
341   GstElement *pipeline;
342   GstElement *nle_audiomixer;
343   GstElement *composition;
344   GstElement *audiomixer, *fakesink;
345   GstElement *nlesource1, *nlesource2;
346   GstElement *audiotestsrc1, *audiotestsrc2;
347
348   gboolean carry_on = TRUE, ret;
349   GstClockTime total_time = 10 * GST_SECOND;
350
351   ges_init ();
352
353   pipeline = GST_ELEMENT (gst_pipeline_new (NULL));
354   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
355
356   composition = gst_element_factory_make ("nlecomposition", "composition");
357   gst_element_set_state (composition, GST_STATE_READY);
358   fakesink = gst_element_factory_make ("fakeaudiosink", NULL);
359
360   /* nle_audiomixer */
361   nle_audiomixer = gst_element_factory_make ("nleoperation", "nle_audiomixer");
362   audiomixer = gst_element_factory_make ("audiomixer", "audiomixer");
363   fail_unless (audiomixer != NULL);
364   gst_bin_add (GST_BIN (nle_audiomixer), audiomixer);
365   g_object_set (nle_audiomixer, "start", (guint64) 0 * GST_SECOND,
366       "duration", total_time, "inpoint", (guint64) 0 * GST_SECOND,
367       "priority", 0, NULL);
368   nle_composition_add (GST_BIN (composition), nle_audiomixer);
369
370   /* source 1 */
371   nlesource1 = gst_element_factory_make ("nlesource", "nlesource1");
372   audiotestsrc1 = gst_element_factory_make ("audiotestsrc", "audiotestsrc1");
373   gst_bin_add (GST_BIN (nlesource1), audiotestsrc1);
374   g_object_set (nlesource1, "start", (guint64) 0 * GST_SECOND,
375       "duration", (gint64) total_time / 2, "inpoint", (guint64) 0, "priority",
376       1, NULL);
377   fail_unless (nle_composition_add (GST_BIN (composition), nlesource1));
378
379   /* nlesource2 */
380   nlesource2 = gst_element_factory_make ("nlesource", "nlesource2");
381   audiotestsrc2 = gst_element_factory_make ("audiotestsrc", "audiotestsrc2");
382   gst_bin_add (GST_BIN (nlesource2), GST_ELEMENT (audiotestsrc2));
383   g_object_set (nlesource2, "start", (guint64) 0 * GST_SECOND,
384       "duration", total_time, "inpoint", (guint64) 0 * GST_SECOND, "priority",
385       2, NULL);
386
387   GST_DEBUG ("Adding composition to pipeline");
388   gst_bin_add_many (GST_BIN (pipeline), composition, fakesink, NULL);
389
390   fail_unless (nle_composition_add (GST_BIN (composition), nlesource2));
391   fail_unless (gst_element_link (composition, fakesink) == TRUE);
392
393   GST_DEBUG ("Setting pipeline to PLAYING");
394
395   commit_and_wait (composition, &ret);
396   fail_if (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING)
397       == GST_STATE_CHANGE_FAILURE);
398
399   message = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
400       GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR);
401
402   if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR)
403     fail_error_message (message);
404   gst_mini_object_unref (GST_MINI_OBJECT (message));
405
406   GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline),
407       GST_DEBUG_GRAPH_SHOW_ALL, "nle-simple-audiomixer-test-play");
408
409   /* Now play the 10 second composition */
410   while (carry_on) {
411     message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 10);
412     GST_LOG ("poll: %" GST_PTR_FORMAT, message);
413     if (message) {
414       switch (GST_MESSAGE_TYPE (message)) {
415         case GST_MESSAGE_EOS:
416           /* we should check if we really finished here */
417           GST_WARNING ("Got an EOS");
418           carry_on = FALSE;
419           break;
420         case GST_MESSAGE_SEGMENT_START:
421         case GST_MESSAGE_SEGMENT_DONE:
422           /* We shouldn't see any segement messages, since we didn't do a segment seek */
423           GST_WARNING ("Saw a Segment start/stop");
424           fail_if (TRUE);
425           carry_on = FALSE;
426           break;
427         case GST_MESSAGE_ERROR:
428           fail_error_message (message);
429         default:
430           break;
431       }
432       gst_mini_object_unref (GST_MINI_OBJECT (message));
433     }
434   }
435
436   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
437   gst_object_unref (bus);
438   gst_object_unref (pipeline);
439
440   ges_deinit ();
441 }
442
443 GST_END_TEST;
444
445 static GstElement *
446 create_nested_source (gint nesting_depth)
447 {
448   gint i;
449   GstElement *source, *nested_comp, *bin;
450
451   source = videotest_nle_src ("source", 0, 2 * GST_SECOND, 2, 2);
452   for (i = 0; i < nesting_depth; i++) {
453     gchar *name = g_strdup_printf ("nested_comp%d", i);
454     gchar *desc = g_strdup_printf ("nlecomposition name=%s ! queue", name);
455     bin = gst_parse_bin_from_description (desc, TRUE, NULL);
456     nested_comp = gst_bin_get_by_name (GST_BIN (bin), name);
457     g_free (name);
458     g_free (desc);
459
460     nle_composition_add (GST_BIN (nested_comp), source);
461     gst_object_unref (nested_comp);
462
463     name = g_strdup_printf ("nested_src%d", i);
464     source = gst_element_factory_make_or_warn ("nlesource", name);
465     g_free (name);
466     g_object_set (source, "start", (guint64) 0, "duration",
467         (gint64) 2 * GST_SECOND, NULL);
468     gst_bin_add (GST_BIN (source), bin);
469   }
470
471
472   return source;
473 }
474
475 GST_START_TEST (test_seek_on_nested)
476 {
477   GstBus *bus;
478   GstPad *srcpad;
479   GstElement *pipeline, *comp, *nested_source, *sink;
480   GstMessage *message;
481   gboolean carry_on, ret = FALSE;
482   GstClockTime position;
483
484   ges_init ();
485
486   pipeline = gst_pipeline_new ("test_pipeline");
487   comp = gst_element_factory_make_or_warn ("nlecomposition", NULL);
488
489   gst_element_set_state (comp, GST_STATE_READY);
490   sink = gst_element_factory_make_or_warn ("fakevideosink", "sink");
491   gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL);
492
493   gst_element_link (comp, sink);
494
495   nested_source = create_nested_source (1);
496   srcpad = gst_element_get_static_pad (nested_source, "src");
497   gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
498       (GstPadProbeCallback) on_source1_pad_event_cb, NULL, NULL);
499   gst_object_unref (srcpad);
500
501   /* Add nested source */
502   nle_composition_add (GST_BIN (comp), nested_source);
503   commit_and_wait (comp, &ret);
504   check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND);
505
506   bus = gst_element_get_bus (GST_ELEMENT (pipeline));
507
508   fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
509           GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE);
510
511   GST_DEBUG ("Let's poll the bus");
512
513   carry_on = TRUE;
514   while (carry_on) {
515     message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 10);
516     if (message) {
517       switch (GST_MESSAGE_TYPE (message)) {
518         case GST_MESSAGE_ASYNC_DONE:
519         {
520           carry_on = FALSE;
521           GST_DEBUG ("Pipeline reached PAUSED, stopping polling");
522           break;
523         }
524         case GST_MESSAGE_EOS:
525         {
526           GST_WARNING ("Saw EOS");
527
528           fail_if (TRUE);
529         }
530         case GST_MESSAGE_ERROR:
531           GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (pipeline),
532               GST_DEBUG_GRAPH_SHOW_ALL, "error");
533           fail_error_message (message);
534         default:
535           break;
536       }
537       gst_mini_object_unref (GST_MINI_OBJECT (message));
538     }
539   }
540
541   gst_element_seek_simple (pipeline,
542       GST_FORMAT_TIME,
543       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, 1 * GST_SECOND);
544
545   message = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
546       GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR);
547   gst_mini_object_unref (GST_MINI_OBJECT (message));
548
549   ret =
550       gst_element_query_position (GST_ELEMENT (pipeline), GST_FORMAT_TIME,
551       (gint64 *) & position);
552   fail_unless_equals_uint64 (position, 1 * GST_SECOND);
553
554   GST_DEBUG ("Setting pipeline to NULL");
555
556   fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
557           GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE);
558
559   GST_DEBUG ("Resetted pipeline to NULL");
560
561   ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "main pipeline", 1, 2);
562   ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "main bus", 1, 2);
563   gst_object_unref (bus);
564   gst_check_objects_destroyed_on_unref (pipeline, comp, nested_source, NULL);
565
566   ges_deinit ();
567 }
568
569 GST_END_TEST;
570
571 GST_START_TEST (test_error_in_nested_timeline)
572 {
573   GstBus *bus;
574   GstPad *srcpad;
575   GstElement *pipeline, *comp, *nested_source, *sink;
576   GstMessage *message;
577   gboolean carry_on, ret = FALSE;
578
579   ges_init ();
580
581   pipeline = gst_pipeline_new ("test_pipeline");
582   comp = gst_element_factory_make_or_warn ("nlecomposition", NULL);
583
584   gst_element_set_state (comp, GST_STATE_READY);
585   sink = gst_element_factory_make_or_warn ("fakevideosink", "sink");
586   gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL);
587
588   gst_element_link (comp, sink);
589
590   nested_source = create_nested_source (1);
591   srcpad = gst_element_get_static_pad (nested_source, "src");
592   gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
593       (GstPadProbeCallback) on_source1_pad_event_cb, NULL, NULL);
594   gst_object_unref (srcpad);
595
596   /* Add nested source */
597   nle_composition_add (GST_BIN (comp), nested_source);
598   commit_and_wait (comp, &ret);
599   check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND);
600
601   bus = gst_element_get_bus (GST_ELEMENT (pipeline));
602
603   fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
604           GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE);
605
606   GST_DEBUG ("Let's poll the bus");
607
608   carry_on = TRUE;
609   while (carry_on) {
610     message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 10);
611     if (message) {
612       switch (GST_MESSAGE_TYPE (message)) {
613         case GST_MESSAGE_ASYNC_DONE:
614         {
615           carry_on = FALSE;
616           GST_DEBUG ("Pipeline reached PAUSED, stopping polling");
617           break;
618         }
619         case GST_MESSAGE_EOS:
620         {
621           GST_WARNING ("Saw EOS");
622
623           fail_if (TRUE);
624         }
625         case GST_MESSAGE_ERROR:
626           GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (pipeline),
627               GST_DEBUG_GRAPH_SHOW_ALL, "error");
628           fail_error_message (message);
629         default:
630           break;
631       }
632       gst_mini_object_unref (GST_MINI_OBJECT (message));
633     }
634   }
635
636   GST_ELEMENT_ERROR (nested_source, STREAM, FAILED,
637       ("Faking an error message"), ("Nothing"));
638
639   message =
640       gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR);
641   gst_mini_object_unref (GST_MINI_OBJECT (message));
642
643   fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
644           GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE);
645
646   GST_DEBUG ("Resetted pipeline to NULL");
647
648   ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "main bus", 1, 2);
649   gst_object_unref (bus);
650
651   ges_deinit ();
652 }
653
654 GST_END_TEST;
655
656 GST_START_TEST (test_nest_deep)
657 {
658   GstBus *bus;
659   GstPad *srcpad;
660   GstElement *pipeline, *comp, *nested_source, *sink;
661   GstMessage *message;
662   gboolean carry_on, ret = FALSE;
663   GstClockTime position;
664
665   ges_init ();
666
667   pipeline = gst_pipeline_new ("test_pipeline");
668   comp = gst_element_factory_make_or_warn ("nlecomposition", NULL);
669
670   gst_element_set_state (comp, GST_STATE_READY);
671   sink = gst_element_factory_make_or_warn ("fakevideosink", "sink");
672   gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL);
673
674   gst_element_link (comp, sink);
675
676   nested_source = create_nested_source (2);
677   srcpad = gst_element_get_static_pad (nested_source, "src");
678   gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
679       (GstPadProbeCallback) on_source1_pad_event_cb, NULL, NULL);
680   gst_object_unref (srcpad);
681
682   /* Add nested source */
683   nle_composition_add (GST_BIN (comp), nested_source);
684   commit_and_wait (comp, &ret);
685   check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND);
686
687   bus = gst_element_get_bus (GST_ELEMENT (pipeline));
688
689   fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
690           GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE);
691
692   GST_DEBUG ("Let's poll the bus");
693
694   carry_on = TRUE;
695   while (carry_on) {
696     message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 10);
697     GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (pipeline),
698         GST_DEBUG_GRAPH_SHOW_ALL, "nothing");
699     if (message) {
700       switch (GST_MESSAGE_TYPE (message)) {
701         case GST_MESSAGE_ASYNC_DONE:
702         {
703           carry_on = FALSE;
704           GST_DEBUG ("Pipeline reached PAUSED, stopping polling");
705           break;
706         }
707         case GST_MESSAGE_EOS:
708         {
709           GST_WARNING ("Saw EOS");
710
711           fail_if (TRUE);
712         }
713         case GST_MESSAGE_ERROR:
714           GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (pipeline),
715               GST_DEBUG_GRAPH_SHOW_ALL, "error");
716           fail_error_message (message);
717         default:
718           break;
719       }
720       gst_mini_object_unref (GST_MINI_OBJECT (message));
721     }
722   }
723
724   gst_element_seek_simple (pipeline,
725       GST_FORMAT_TIME,
726       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, 1 * GST_SECOND);
727
728   message = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
729       GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR);
730   gst_mini_object_unref (GST_MINI_OBJECT (message));
731
732   ret =
733       gst_element_query_position (GST_ELEMENT (pipeline), GST_FORMAT_TIME,
734       (gint64 *) & position);
735   fail_unless_equals_uint64 (position, 1 * GST_SECOND);
736
737   GST_DEBUG ("Setting pipeline to NULL");
738
739   fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
740           GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE);
741
742   GST_DEBUG ("Resetted pipeline to NULL");
743
744   ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "main pipeline", 1, 2);
745   gst_check_objects_destroyed_on_unref (pipeline, comp, nested_source, NULL);
746   ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "main bus", 1, 2);
747   gst_object_unref (bus);
748
749   ges_deinit ();
750 }
751
752 GST_END_TEST;
753
754
755
756 static Suite *
757 gnonlin_suite (void)
758 {
759   Suite *s = suite_create ("nlecomposition");
760   TCase *tc_chain = tcase_create ("nlecomposition");
761
762   suite_add_tcase (s, tc_chain);
763
764   tcase_add_test (tc_chain, test_change_object_start_stop_in_current_stack);
765   tcase_add_test (tc_chain, test_remove_invalid_object);
766   tcase_add_test (tc_chain, test_remove_last_object);
767   tcase_add_test (tc_chain, test_seek_on_nested);
768   tcase_add_test (tc_chain, test_error_in_nested_timeline);
769   tcase_add_test (tc_chain, test_nest_deep);
770
771   tcase_add_test (tc_chain, test_dispose_on_commit);
772
773   if (gst_registry_check_feature_version (gst_registry_get (), "audiomixer", 1,
774           0, 0)) {
775     tcase_add_test (tc_chain, test_simple_audiomixer);
776   } else {
777     GST_WARNING ("audiomixer element not available, skipping 1 test");
778   }
779
780   return s;
781 }
782
783 GST_CHECK_MAIN (gnonlin)