1 /* GStreamer Editing Services
2  * Copyright (C) 2010 Brandon Lewis <brandon.lewis@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 
20 #include "test-utils.h"
21 #include <ges/ges.h>
22 #include <gst/check/gstcheck.h>
23 
24 #define DEFAULT_VOLUME 1.0
25 
GST_START_TEST(test_test_source_basic)26 GST_START_TEST (test_test_source_basic)
27 {
28   GESTestClip *source;
29 
30   ges_init ();
31 
32   source = ges_test_clip_new ();
33   fail_unless (source != NULL);
34 
35   gst_object_unref (source);
36 
37   ges_deinit ();
38 }
39 
40 GST_END_TEST;
41 
GST_START_TEST(test_test_source_properties)42 GST_START_TEST (test_test_source_properties)
43 {
44   GESClip *clip;
45   GESTrack *track;
46   GESTimeline *timeline;
47   GESLayer *layer;
48   GESTrackElement *trackelement;
49 
50   ges_init ();
51 
52   track = ges_track_new (GES_TRACK_TYPE_AUDIO, gst_caps_ref (GST_CAPS_ANY));
53   fail_unless (track != NULL);
54 
55   layer = ges_layer_new ();
56   fail_unless (layer != NULL);
57 
58   timeline = ges_timeline_new ();
59   fail_unless (timeline != NULL);
60   fail_unless (ges_timeline_add_layer (timeline, layer));
61   fail_unless (ges_timeline_add_track (timeline, track));
62 
63   clip = (GESClip *) ges_test_clip_new ();
64   fail_unless (clip != NULL);
65 
66   /* Set some properties */
67   GST_DEBUG ("Setting start duration and inpoint to %" GST_PTR_FORMAT, clip);
68   g_object_set (clip, "start", (guint64) 42, "duration", (guint64) 51,
69       "in-point", (guint64) 12, NULL);
70   assert_equals_uint64 (_START (clip), 42);
71   assert_equals_uint64 (_DURATION (clip), 51);
72   assert_equals_uint64 (_INPOINT (clip), 12);
73 
74   ges_layer_add_clip (layer, GES_CLIP (clip));
75   assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1);
76   trackelement = GES_CONTAINER_CHILDREN (clip)->data;
77   fail_unless (trackelement != NULL);
78   fail_unless (GES_TIMELINE_ELEMENT_PARENT (trackelement) ==
79       GES_TIMELINE_ELEMENT (clip));
80   fail_unless (ges_track_element_get_track (trackelement) == track);
81 
82   /* Check that trackelement has the same properties */
83   assert_equals_uint64 (_START (trackelement), 42);
84   assert_equals_uint64 (_DURATION (trackelement), 51);
85   assert_equals_uint64 (_INPOINT (trackelement), 12);
86 
87   fail_unless (ges_timeline_commit (timeline));
88   /* And let's also check that it propagated correctly to GNonLin */
89   nle_object_check (ges_track_element_get_nleobject (trackelement), 42, 51, 12,
90       51, MIN_NLE_PRIO + TRANSITIONS_HEIGHT, TRUE);
91 
92   /* Change more properties, see if they propagate */
93   g_object_set (clip, "start", (guint64) 420, "duration", (guint64) 510,
94       "in-point", (guint64) 120, NULL);
95   assert_equals_uint64 (_START (clip), 420);
96   assert_equals_uint64 (_DURATION (clip), 510);
97   assert_equals_uint64 (_INPOINT (clip), 120);
98   assert_equals_uint64 (_START (trackelement), 420);
99   assert_equals_uint64 (_DURATION (trackelement), 510);
100   assert_equals_uint64 (_INPOINT (trackelement), 120);
101 
102   fail_unless (ges_timeline_commit (timeline));
103   /* And let's also check that it propagated correctly to GNonLin */
104   nle_object_check (ges_track_element_get_nleobject (trackelement), 420, 510,
105       120, 510, MIN_NLE_PRIO + TRANSITIONS_HEIGHT, TRUE);
106 
107   /* Test mute support */
108   g_object_set (clip, "mute", TRUE, NULL);
109   fail_unless (ges_timeline_commit (timeline));
110   nle_object_check (ges_track_element_get_nleobject (trackelement), 420, 510,
111       120, 510, MIN_NLE_PRIO + TRANSITIONS_HEIGHT, FALSE);
112   g_object_set (clip, "mute", FALSE, NULL);
113   fail_unless (ges_timeline_commit (timeline));
114   nle_object_check (ges_track_element_get_nleobject (trackelement), 420, 510,
115       120, 510, MIN_NLE_PRIO + TRANSITIONS_HEIGHT, TRUE);
116 
117   ges_container_remove (GES_CONTAINER (clip),
118       GES_TIMELINE_ELEMENT (trackelement));
119   gst_object_unref (clip);
120 
121   ges_deinit ();
122 }
123 
124 GST_END_TEST;
125 
GST_START_TEST(test_test_source_in_layer)126 GST_START_TEST (test_test_source_in_layer)
127 {
128   GESTimeline *timeline;
129   GESLayer *layer;
130   GESTrack *a, *v;
131   GESTrackElement *track_element;
132   GESTestClip *source;
133   GESVideoTestPattern ptrn;
134   gdouble freq, volume;
135 
136   ges_init ();
137 
138   timeline = ges_timeline_new ();
139   layer = ges_layer_new ();
140   a = GES_TRACK (ges_audio_track_new ());
141   v = GES_TRACK (ges_video_track_new ());
142 
143   ges_timeline_add_track (timeline, a);
144   ges_timeline_add_track (timeline, v);
145   ges_timeline_add_layer (timeline, layer);
146 
147   source = ges_test_clip_new_for_nick ((gchar *) "red");
148   g_object_get (source, "vpattern", &ptrn, NULL);
149   assert_equals_int (ptrn, GES_VIDEO_TEST_PATTERN_RED);
150 
151   g_object_set (source, "duration", (guint64) GST_SECOND, NULL);
152 
153   ges_layer_add_clip (layer, (GESClip *) source);
154 
155   /* specifically test the vpattern property */
156   g_object_set (source, "vpattern", (gint) GES_VIDEO_TEST_PATTERN_WHITE, NULL);
157   g_object_get (source, "vpattern", &ptrn, NULL);
158   assert_equals_int (ptrn, GES_VIDEO_TEST_PATTERN_WHITE);
159 
160   track_element =
161       ges_clip_find_track_element (GES_CLIP (source), v,
162       GES_TYPE_VIDEO_TEST_SOURCE);
163 
164   g_assert (GES_IS_VIDEO_TEST_SOURCE (track_element));
165 
166   ptrn = (ges_video_test_source_get_pattern ((GESVideoTestSource *)
167           track_element));
168   assert_equals_int (ptrn, GES_VIDEO_TEST_PATTERN_WHITE);
169   gst_object_unref (track_element);
170 
171   /* test audio properties as well */
172 
173   track_element = ges_clip_find_track_element (GES_CLIP (source),
174       a, GES_TYPE_AUDIO_TEST_SOURCE);
175   g_assert (GES_IS_AUDIO_TEST_SOURCE (track_element));
176   assert_equals_float (ges_test_clip_get_frequency (source), 440);
177   assert_equals_float (ges_test_clip_get_volume (source), DEFAULT_VOLUME);
178 
179   g_object_get (source, "freq", &freq, "volume", &volume, NULL);
180   assert_equals_float (freq, 440);
181   assert_equals_float (volume, DEFAULT_VOLUME);
182 
183 
184   freq = ges_audio_test_source_get_freq (GES_AUDIO_TEST_SOURCE (track_element));
185   volume =
186       ges_audio_test_source_get_volume (GES_AUDIO_TEST_SOURCE (track_element));
187   g_assert (freq == 440);
188   g_assert (volume == DEFAULT_VOLUME);
189 
190   g_object_set (source, "freq", (gdouble) 2000, "volume", (gdouble) 0.5, NULL);
191   g_object_get (source, "freq", &freq, "volume", &volume, NULL);
192   assert_equals_float (freq, 2000);
193   assert_equals_float (volume, 0.5);
194 
195   freq = ges_audio_test_source_get_freq (GES_AUDIO_TEST_SOURCE (track_element));
196   volume =
197       ges_audio_test_source_get_volume (GES_AUDIO_TEST_SOURCE (track_element));
198   g_assert (freq == 2000);
199   g_assert (volume == 0.5);
200 
201   gst_object_unref (track_element);
202 
203   ges_layer_remove_clip (layer, (GESClip *) source);
204 
205   GST_DEBUG ("removing the layer");
206 
207   gst_object_unref (timeline);
208 
209   ges_deinit ();
210 }
211 
212 GST_END_TEST;
213 
214 #if 0
215 static gint
216 find_composition_func (const GValue * velement)
217 {
218   GstElement *element = g_value_get_object (velement);
219   GstElementFactory *fac = gst_element_get_factory (element);
220   const gchar *name = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (fac));
221 
222   if (g_strcmp0 (name, "nlecomposition") == 0)
223     return 0;
224 
225   return 1;
226 }
227 
228 static GstElement *
229 find_composition (GESTrack * track)
230 {
231   GstIterator *it = gst_bin_iterate_recurse (GST_BIN (track));
232   GValue val = { 0, };
233   GstElement *ret = NULL;
234 
235   if (gst_iterator_find_custom (it, (GCompareFunc) find_composition_func, &val,
236           NULL))
237     ret = g_value_get_object (&val);
238 
239   g_value_unset (&val);
240   gst_iterator_free (it);
241 
242   return ret;
243 }
244 
245 #define gap_object_check(nleobj, start, duration, priority)  \
246 {                                                            \
247   guint64 pstart, pdur, pprio;                               \
248   g_object_get (nleobj, "start", &pstart, "duration", &pdur, \
249     "priority", &pprio, NULL);                               \
250   assert_equals_uint64 (pstart, start);                      \
251   assert_equals_uint64 (pdur, duration);                     \
252   assert_equals_int (pprio, priority);                       \
253 }
254 
255 GST_START_TEST (test_gap_filling_basic)
256 {
257   GList *tmp;
258   GESTrack *track;
259   GESTimeline *timeline;
260   GstElement *composition;
261   GESLayer *layer;
262   GESClip *clip, *clip1, *clip2;
263 
264   GstElement *nlesrc, *nlesrc1, *gap = NULL;
265   GESTrackElement *trackelement, *trackelement1, *trackelement2;
266 
267   track = GES_TRACK (ges_audio_track_new ());
268   fail_unless (track != NULL);
269 
270   composition = find_composition (track);
271   fail_unless (composition != NULL);
272 
273   layer = ges_layer_new ();
274   fail_unless (layer != NULL);
275 
276   timeline = ges_timeline_new ();
277   fail_unless (timeline != NULL);
278   fail_unless (ges_timeline_add_layer (timeline, layer));
279   fail_unless (ges_timeline_add_track (timeline, track));
280 
281   clip = GES_CLIP (ges_test_clip_new ());
282   fail_unless (clip != NULL);
283 
284   /* Set some properties */
285   g_object_set (clip, "start", (guint64) 0, "duration", (guint64) 5, NULL);
286   assert_equals_uint64 (_START (clip), 0);
287   assert_equals_uint64 (_DURATION (clip), 5);
288 
289   ges_layer_add_clip (layer, GES_CLIP (clip));
290   assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1);
291   trackelement = GES_CONTAINER_CHILDREN (clip)->data;
292   fail_unless (trackelement != NULL);
293   fail_unless (ges_track_element_get_track (trackelement) == track);
294 
295   nlesrc = ges_track_element_get_nleobject (trackelement);
296   fail_unless (nlesrc != NULL);
297 
298   /* Check that trackelement has the same properties */
299   assert_equals_uint64 (_START (trackelement), 0);
300   assert_equals_uint64 (_DURATION (trackelement), 5);
301 
302   /* Check no gap were wrongly added
303    * 2: 1 for the trackelement and 1 for the mixer */
304   assert_equals_int (g_list_length (GST_BIN_CHILDREN (composition)), 2);
305 
306   clip1 = GES_CLIP (ges_test_clip_new ());
307   fail_unless (clip1 != NULL);
308 
309   g_object_set (clip1, "start", (guint64) 15, "duration", (guint64) 5, NULL);
310   assert_equals_uint64 (_START (clip1), 15);
311   assert_equals_uint64 (_DURATION (clip1), 5);
312 
313   ges_layer_add_clip (layer, GES_CLIP (clip1));
314   ges_timeline_commit (timeline);
315   assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip1)), 1);
316   trackelement1 = GES_CONTAINER_CHILDREN (clip1)->data;
317   fail_unless (trackelement1 != NULL);
318   fail_unless (ges_track_element_get_track (trackelement1) == track);
319   nlesrc1 = ges_track_element_get_nleobject (trackelement1);
320   fail_unless (nlesrc1 != NULL);
321 
322   /* Check that trackelement1 has the same properties */
323   assert_equals_uint64 (_START (trackelement1), 15);
324   assert_equals_uint64 (_DURATION (trackelement1), 5);
325 
326   /* Check the gap as properly been added */
327   assert_equals_int (g_list_length (GST_BIN_CHILDREN (composition)), 4);
328 
329   for (tmp = GST_BIN_CHILDREN (composition); tmp; tmp = tmp->next) {
330     guint prio;
331     GstElement *tmp_nleobj = GST_ELEMENT (tmp->data);
332 
333     g_object_get (tmp_nleobj, "priority", &prio, NULL);
334     if (tmp_nleobj != nlesrc && tmp_nleobj != nlesrc1 && prio == 1) {
335       gap = tmp_nleobj;
336     }
337   }
338   fail_unless (gap != NULL);
339   gap_object_check (gap, 5, 10, 1);
340 
341   clip2 = GES_CLIP (ges_test_clip_new ());
342   fail_unless (clip2 != NULL);
343   g_object_set (clip2, "start", (guint64) 35, "duration", (guint64) 5, NULL);
344   ges_layer_add_clip (layer, GES_CLIP (clip2));
345   fail_unless (ges_timeline_commit (timeline));
346   assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip2)), 1);
347   trackelement2 = GES_CONTAINER_CHILDREN (clip2)->data;
348   fail_unless (trackelement2 != NULL);
349   fail_unless (ges_track_element_get_track (trackelement2) == track);
350   assert_equals_uint64 (_START (trackelement2), 35);
351   assert_equals_uint64 (_DURATION (trackelement2), 5);
352   assert_equals_int (g_list_length (GST_BIN_CHILDREN (composition)), 6);
353 
354   gst_object_unref (timeline);
355 }
356 
357 GST_END_TEST;
358 
359 GST_START_TEST (test_gap_filling_empty_track)
360 {
361   GESAsset *asset;
362   GESTrack *track;
363   GESTimeline *timeline;
364   GstElement *gap;
365   GstElement *composition;
366   GESLayer *layer;
367   GESClip *clip;
368 
369   track = GES_TRACK (ges_audio_track_new ());
370 
371   layer = ges_layer_new ();
372   timeline = ges_timeline_new ();
373   fail_unless (timeline != NULL);
374   fail_unless (ges_timeline_add_layer (timeline, layer));
375   fail_unless (ges_timeline_add_track (timeline, track));
376   fail_unless (ges_timeline_add_track (timeline,
377           GES_TRACK (ges_video_track_new ())));
378 
379   /* Set some properties */
380   asset = ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL);
381   clip = ges_layer_add_asset (layer, asset, 0, 0, 10, GES_TRACK_TYPE_VIDEO);
382   ges_timeline_commit (timeline);
383   assert_equals_int (g_list_length (GES_CONTAINER_CHILDREN (clip)), 1);
384 
385   /* We should not have created any TrackElement in the audio track */
386   fail_unless (ges_track_get_elements (track) == NULL);
387 
388   /* Check that a gap was properly added */
389   composition = find_composition (track);
390   /* We also have an adder in that composition */
391   assert_equals_int (g_list_length (GST_BIN_CHILDREN (composition)), 2);
392 
393   gap = GST_BIN_CHILDREN (composition)->data;
394   fail_unless (gap != NULL);
395   gap_object_check (gap, 0, 10, 1);
396   fail_unless (ges_timeline_commit (timeline));
397 
398   gst_object_unref (timeline);
399 }
400 
401 GST_END_TEST;
402 #endif
403 
404 static Suite *
ges_suite(void)405 ges_suite (void)
406 {
407   Suite *s = suite_create ("ges-backgroundsource");
408   TCase *tc_chain = tcase_create ("backgroundsource");
409 
410   suite_add_tcase (s, tc_chain);
411 
412   tcase_add_test (tc_chain, test_test_source_basic);
413   tcase_add_test (tc_chain, test_test_source_properties);
414   tcase_add_test (tc_chain, test_test_source_in_layer);
415 
416 #if 0
417   tcase_add_test (tc_chain, test_gap_filling_basic);
418   tcase_add_test (tc_chain, test_gap_filling_empty_track);
419 #endif
420 
421   return s;
422 }
423 
424 GST_CHECK_MAIN (ges);
425