1 /* GStreamer Editing Services
2  * Copyright (C) 2016 Sjors Gielen <mixml-ges@sjorsgielen.nl>
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 
20 #include "common.h"
21 #include "plugins/nle/nleobject.h"
22 
GST_START_TEST(test_tempochange)23 GST_START_TEST (test_tempochange)
24 {
25   GstElement *pipeline;
26   GstElement *comp, *source1, *def, *sink, *oper;
27   GList *segments = NULL;
28   GstBus *bus;
29   GstMessage *message;
30   gboolean carry_on, ret = FALSE;
31   CollectStructure *collect;
32   GstPad *sinkpad;
33 
34   pipeline = gst_pipeline_new ("test_pipeline");
35   comp =
36       gst_element_factory_make_or_warn ("nlecomposition", "test_composition");
37 
38   gst_element_set_state (comp, GST_STATE_READY);
39 
40   sink = gst_element_factory_make_or_warn ("fakesink", "sink");
41   gst_bin_add_many (GST_BIN (pipeline), comp, sink, NULL);
42 
43   gst_element_link (comp, sink);
44 
45   /*
46      source1
47      Start : 0s
48      Duration : 2s
49      Priority : 2
50    */
51 
52   source1 = audiotest_bin_src ("source1", 0, 2 * GST_SECOND, 2, 2);
53 
54   /*
55      def (default source)
56      Priority = G_MAXUINT32
57    */
58   def =
59       audiotest_bin_src ("default", 0 * GST_SECOND, 0 * GST_SECOND, G_MAXUINT32,
60       1);
61   g_object_set (def, "expandable", TRUE, NULL);
62 
63   /* Operation */
64   oper = new_operation ("oper", "identity", 0, 2 * GST_SECOND, 1);
65   fail_if (oper == NULL);
66   ((NleObject *) oper)->media_duration_factor = 2.0;
67 
68   ASSERT_OBJECT_REFCOUNT (source1, "source1", 1);
69   ASSERT_OBJECT_REFCOUNT (def, "default", 1);
70   ASSERT_OBJECT_REFCOUNT (oper, "oper", 1);
71 
72   /* Add source 1 */
73 
74   nle_composition_add (GST_BIN (comp), source1);
75   nle_composition_add (GST_BIN (comp), def);
76   nle_composition_add (GST_BIN (comp), oper);
77   commit_and_wait (comp, &ret);
78   check_start_stop_duration (source1, 0, 2 * GST_SECOND, 2 * GST_SECOND);
79   check_start_stop_duration (comp, 0, 2 * GST_SECOND, 2 * GST_SECOND);
80   check_start_stop_duration (oper, 0, 2 * GST_SECOND, 2 * GST_SECOND);
81 
82   /* Define expected segments */
83   segments = g_list_append (segments,
84       segment_new (1.0, GST_FORMAT_TIME, 0 * GST_SECOND, 4.0 * GST_SECOND, 0));
85   collect = g_new0 (CollectStructure, 1);
86   collect->comp = comp;
87   collect->sink = sink;
88 
89   collect->expected_segments = segments;
90   collect->keep_expected_segments = FALSE;
91 
92   sinkpad = gst_element_get_static_pad (sink, "sink");
93   gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
94       (GstPadProbeCallback) sinkpad_probe, collect, NULL);
95   gst_object_unref (sinkpad);
96 
97   bus = gst_element_get_bus (GST_ELEMENT (pipeline));
98 
99   GST_DEBUG ("Setting pipeline to PAUSED");
100   ASSERT_OBJECT_REFCOUNT (source1, "source1", 1);
101 
102   fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
103           GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE);
104 
105   GST_DEBUG ("Let's poll the bus");
106 
107   carry_on = TRUE;
108   while (carry_on) {
109     message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 10);
110     if (message) {
111       switch (GST_MESSAGE_TYPE (message)) {
112         case GST_MESSAGE_ASYNC_DONE:
113         {
114           carry_on = FALSE;
115           GST_DEBUG ("Pipeline reached PAUSED, stopping polling");
116           break;
117         }
118         case GST_MESSAGE_EOS:
119         {
120           GST_WARNING ("Saw EOS");
121 
122           fail_if (TRUE);
123         }
124         case GST_MESSAGE_ERROR:
125           fail_error_message (message);
126         default:
127           break;
128       }
129       gst_mini_object_unref (GST_MINI_OBJECT (message));
130     }
131   }
132 
133   fail_unless_equals_float (((NleObject *) source1)->media_duration_factor,
134       1.0f);
135   fail_unless_equals_float (((NleObject *)
136           source1)->recursive_media_duration_factor, 2.0f);
137   fail_unless_equals_float (((NleObject *) oper)->media_duration_factor, 2.0f);
138   fail_unless_equals_float (((NleObject *)
139           oper)->recursive_media_duration_factor, 2.0f);
140 
141   GST_DEBUG ("Setting pipeline to READY");
142 
143   fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
144           GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
145 
146   fail_if (collect->expected_segments != NULL);
147 
148   fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
149           GST_STATE_NULL) == GST_STATE_CHANGE_FAILURE);
150 
151   ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "main pipeline", 1, 2);
152   gst_object_unref (pipeline);
153   ASSERT_OBJECT_REFCOUNT_BETWEEN (bus, "main bus", 1, 2);
154   gst_object_unref (bus);
155 
156   collect_free (collect);
157 }
158 
159 GST_END_TEST;
160 
161 static Suite *
gnonlin_suite(void)162 gnonlin_suite (void)
163 {
164   Suite *s = suite_create ("nle");
165   TCase *tc_chain = tcase_create ("tempochange");
166 
167   if (atexit (ges_deinit) != 0) {
168     GST_ERROR ("failed to set ges_deinit as exit function");
169   }
170 
171   ges_init ();
172   suite_add_tcase (s, tc_chain);
173 
174   tcase_add_test (tc_chain, test_tempochange);
175 
176   return s;
177 }
178 
179 GST_CHECK_MAIN (gnonlin)
180