144db177eb54b0107f3941c012574d1947e74afb
[platform/upstream/gst-editing-services.git] / tests / check / ges / timelineedition.c
1 /* GStreamer Editing Services
2  *
3  * Copyright (C) <2012> Thibault Saunier <thibault.saunier@collabora.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 #include "test-utils.h"
22 #include <ges/ges.h>
23 #include <gst/check/gstcheck.h>
24
25 #define DEEP_CHECK(element, start, inpoint, duration)                          \
26 {                                                                              \
27   GList *track_elements, *tmp;                                                 \
28                                                                                \
29   assert_equals_uint64 (_START (element), start);                              \
30   assert_equals_uint64 (_INPOINT (element), inpoint);                          \
31   assert_equals_uint64 (_DURATION (element), duration);                        \
32                                                                                \
33   track_elements = GES_CONTAINER_CHILDREN (element);                           \
34   for (tmp = track_elements; tmp; tmp = tmp->next) {                           \
35     assert_equals_uint64 (_START (tmp->data), start);                          \
36     assert_equals_uint64 (_INPOINT (tmp->data), inpoint);                      \
37     assert_equals_uint64 (_DURATION (tmp->data), duration);                    \
38   }                                                                            \
39 }
40
41 GST_START_TEST (test_basic_timeline_edition)
42 {
43   GESAsset *asset;
44   GESTrack *track;
45   GESTimeline *timeline;
46   GESLayer *layer;
47   GESTrackElement *trackelement, *trackelement1, *trackelement2;
48   GESContainer *clip, *clip1, *clip2;
49
50   ges_init ();
51
52   track = GES_TRACK (ges_audio_track_new ());
53   fail_unless (track != NULL);
54
55   timeline = ges_timeline_new ();
56   fail_unless (timeline != NULL);
57   fail_unless (ges_timeline_add_track (timeline, track));
58
59   layer = ges_layer_new ();
60   fail_unless (layer != NULL);
61   fail_unless (ges_timeline_add_layer (timeline, layer));
62
63   asset = ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL);
64   fail_unless (GES_IS_ASSET (asset));
65
66   /**
67    * Our timeline
68    *
69    * inpoints 0-------   0--------      0-----------
70    *          |  clip  |  |  clip1  |     |     clip2  |
71    * time     0------- 10 --------20    50---------60
72    */
73   clip = GES_CONTAINER (ges_layer_add_asset (layer, asset, 0, 0, 10,
74           GES_TRACK_TYPE_UNKNOWN));
75   trackelement = GES_CONTAINER_CHILDREN (clip)->data;
76   fail_unless (GES_IS_TRACK_ELEMENT (trackelement));
77
78   clip1 = GES_CONTAINER (ges_layer_add_asset (layer, asset, 10, 0, 10,
79           GES_TRACK_TYPE_UNKNOWN));
80   trackelement1 = GES_CONTAINER_CHILDREN (clip1)->data;
81   fail_unless (GES_IS_TRACK_ELEMENT (trackelement1));
82
83   clip2 = GES_CONTAINER (ges_layer_add_asset (layer, asset, 50, 0, 60,
84           GES_TRACK_TYPE_UNKNOWN));
85   trackelement2 = GES_CONTAINER_CHILDREN (clip2)->data;
86   fail_unless (GES_IS_TRACK_ELEMENT (trackelement2));
87
88   CHECK_OBJECT_PROPS (trackelement, 0, 0, 10);
89   CHECK_OBJECT_PROPS (trackelement1, 10, 0, 10);
90   CHECK_OBJECT_PROPS (trackelement2, 50, 0, 60);
91
92   /**
93    * Simple rippling clip to: 10
94    *
95    * New timeline:
96    * ------------
97    *
98    * inpoints 0-------   0--------      0-----------
99    *          |  clip  |  |  clip1  |     |   clip2    |
100    * time    10------- 20 --------30    60---------120
101    */
102   fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_RIPPLE,
103           GES_EDGE_NONE, 10) == TRUE);
104   CHECK_OBJECT_PROPS (trackelement, 10, 0, 10);
105   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
106   CHECK_OBJECT_PROPS (trackelement2, 60, 0, 60);
107
108
109   /* FIXME find a way to check that we are using the same MovingContext
110    * inside the GESTrack */
111   fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_RIPPLE,
112           GES_EDGE_NONE, 40) == TRUE);
113   CHECK_OBJECT_PROPS (trackelement, 10, 0, 10);
114   CHECK_OBJECT_PROPS (trackelement1, 40, 0, 10);
115   CHECK_OBJECT_PROPS (trackelement2, 80, 0, 60);
116
117   /**
118    * Rippling clip1 back to: 20 (getting to the exact same timeline as before
119    */
120   fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_RIPPLE,
121           GES_EDGE_NONE, 20) == TRUE);
122   CHECK_OBJECT_PROPS (trackelement, 10, 0, 10);
123   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
124   CHECK_OBJECT_PROPS (trackelement2, 60, 0, 60);
125
126   /**
127    * Simple move clip to: 27 and clip2 to 35
128    *
129    * New timeline:
130    * ------------
131    *                    0------------
132    * inpoints   0-------|---  clip 0--|----------
133    *            |  clip1 27 -|-----|-37   clip2   |
134    * time      20-----------30   35-------------120
135    */
136   fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_NORMAL,
137           GES_EDGE_NONE, 27) == TRUE);
138   fail_unless (ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_NORMAL,
139           GES_EDGE_NONE, 35) == TRUE);
140   CHECK_OBJECT_PROPS (trackelement, 27, 0, 10);
141   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
142   CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60);
143
144   /**
145    * Trim start clip to: 32 and clip2 to 35
146    *
147    * New timeline:
148    * ------------
149    *                           5--------
150    * inpoints   0-----------   | clip 0--|----------
151    *            |  clip1     |  32----|-37   clip2   |
152    * time      20-----------30      35-------------120
153    */
154   fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_TRIM,
155           GES_EDGE_START, 32) == TRUE);
156   CHECK_OBJECT_PROPS (trackelement, 32, 5, 5);
157   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
158   CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60);
159
160   /* Ripple end clip to 42
161    * New timeline:
162    * ------------
163    *                           5--------
164    * inpoints   0-----------   | clip 0--|----------
165    *            |  clip1     |  32----|-42   clip2   |
166    * time      20-----------30      35-------------120
167    */
168   fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_RIPPLE,
169           GES_EDGE_END, 42) == TRUE);
170   CHECK_OBJECT_PROPS (trackelement, 32, 5, 10);
171   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
172   CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60);
173
174   /**
175    * New timeline:
176    * ------------
177    * inpoints 0-------     5-------- 0-----------
178    *          |  clip1 |    |  clip1  ||  clip2    |
179    * time    20-------30  32--------52 ---------112
180    */
181   fail_unless (ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_NORMAL,
182           GES_EDGE_NONE, 42) == TRUE);
183   fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_RIPPLE,
184           GES_EDGE_END, 52) == TRUE);
185   CHECK_OBJECT_PROPS (trackelement, 32, 5, 20);
186   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
187   CHECK_OBJECT_PROPS (trackelement2, 52, 0, 60);
188
189   /**
190    * New timeline:
191    * ------------
192    * inpoints 0-------     5-------- 0------------
193    *          |  clip1 |    |  clip   ||    clip2    |
194    * time    20-------40  42--------62 ---------122
195    */
196   fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_RIPPLE,
197           GES_EDGE_END, 40) == TRUE);
198   CHECK_OBJECT_PROPS (trackelement, 42, 5, 20);
199   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20);
200   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
201
202   /**
203    * New timeline:
204    * ------------
205    * inpoints 0-------  3-------- 0------------
206    *          |  clip1 ||  clip   ||    clip2    |
207    * time    20-------40 --------62 ---------122
208    */
209   fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_TRIM,
210           GES_EDGE_START, 40) == TRUE);
211   CHECK_OBJECT_PROPS (trackelement, 40, 3, 22);
212   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20);
213   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
214   /**
215    * New timeline:
216    * ------------
217    * inpoints 0------- 0-------- 0-----------
218    *          |  clip1 ||   clip  ||  clip2     |
219    * time    20------ 25 ------ 62 ---------122
220    */
221   fail_if (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_ROLL,
222           GES_EDGE_START, 25));
223   CHECK_OBJECT_PROPS (trackelement, 40, 3, 22);
224   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20);
225   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
226
227   /* Make sure that not doing anything when not able to roll */
228   fail_if (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL,
229           GES_EDGE_END, 65) == TRUE, 0);
230   CHECK_OBJECT_PROPS (trackelement, 40, 3, 22);
231   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20);
232   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
233
234   gst_object_unref (timeline);
235
236   ges_deinit ();
237 }
238
239 GST_END_TEST;
240
241 GST_START_TEST (test_snapping)
242 {
243   GESTrack *track;
244   GESTimeline *timeline;
245   GESTrackElement *trackelement, *trackelement1, *trackelement2;
246   GESContainer *clip, *clip1, *clip2;
247   GESLayer *layer;
248   GList *trackelements;
249
250   ges_init ();
251
252   track = GES_TRACK (ges_video_track_new ());
253   fail_unless (track != NULL);
254
255   timeline = ges_timeline_new ();
256   fail_unless (timeline != NULL);
257
258   fail_unless (ges_timeline_add_track (timeline, track));
259
260   clip = GES_CONTAINER (ges_test_clip_new ());
261   clip1 = GES_CONTAINER (ges_test_clip_new ());
262   clip2 = GES_CONTAINER (ges_test_clip_new ());
263
264   fail_unless (clip && clip1 && clip2);
265
266   /**
267    * Our timeline
268    * ------------
269    * inpoints 0------- 0-------- 0-----------
270    *          |  clip1 ||   clip  ||  clip2     |
271    * time    20------ 25 ------ 62 ---------122
272    */
273   g_object_set (clip, "start", (guint64) 25, "duration", (guint64) 37,
274       "in-point", (guint64) 0, NULL);
275   g_object_set (clip1, "start", (guint64) 20, "duration", (guint64) 15,
276       "in-point", (guint64) 0, NULL);
277   g_object_set (clip2, "start", (guint64) 62, "duration", (guint64) 60,
278       "in-point", (guint64) 0, NULL);
279
280   fail_unless ((layer = ges_timeline_append_layer (timeline)) != NULL);
281   assert_equals_int (ges_layer_get_priority (layer), 0);
282
283
284   fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip)));
285   fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip)) != NULL);
286   fail_unless ((trackelement =
287           GES_TRACK_ELEMENT (trackelements->data)) != NULL);
288   fail_unless (ges_track_element_get_track (trackelement) == track);
289   assert_equals_uint64 (_DURATION (trackelement), 37);
290
291   ASSERT_OBJECT_REFCOUNT (trackelement, "track + timeline + clip", 4);
292   ASSERT_OBJECT_REFCOUNT (clip, "layer + timeline", 2);
293
294   fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip1)));
295   fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip1)) != NULL);
296   fail_unless ((trackelement1 =
297           GES_TRACK_ELEMENT (trackelements->data)) != NULL);
298   fail_unless (ges_track_element_get_track (trackelement1) == track);
299   assert_equals_uint64 (_DURATION (trackelement1), 15);
300
301   /* Same ref logic */
302   ASSERT_OBJECT_REFCOUNT (trackelement1, "First trackelement", 4);
303   ASSERT_OBJECT_REFCOUNT (clip1, "First clip", 2);
304
305   fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip2)));
306   fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip2)) != NULL);
307   fail_unless ((trackelement2 =
308           GES_TRACK_ELEMENT (trackelements->data)) != NULL);
309   fail_unless (ges_track_element_get_track (trackelement2) == track);
310   assert_equals_uint64 (_DURATION (trackelement2), 60);
311
312   /* Same ref logic */
313   ASSERT_OBJECT_REFCOUNT (trackelement2, "First trackelement", 4);
314   ASSERT_OBJECT_REFCOUNT (clip2, "First clip", 2);
315
316   /* Snaping to edge, so no move */
317   g_object_set (timeline, "snapping-distance", (guint64) 3, NULL);
318   fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM,
319           GES_EDGE_END, 27) == TRUE);
320   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
321   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5);
322   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
323
324   /* Snaping to edge, so no move */
325   fail_if (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM,
326           GES_EDGE_END, 27));
327   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
328   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5);
329   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
330
331   /**
332    * New timeline:
333    * ------------
334    *                    0----------- 0-------------
335    * inpoints   0-------|--   clip   ||   clip2      |
336    *            |  clip1 25-|------- 62 -----------122
337    * time      20----------30
338    */
339   g_object_set (timeline, "snapping-distance", (guint64) 0, NULL);
340   ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (clip1), 10);
341   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
342   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
343   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
344
345   /**
346    * New timeline(the "layers" are just to help reading diagram, nothing else):
347    * ------------
348    *                    0----------
349    *                    |   clip    |
350    *                    25---------62
351    * inpoints   0----------------------- 10--------
352    *            |       clip1            ||  clip2   |
353    * time      20---------------------- 72 --------122
354    */
355   /* Rolling involves only neighbour that are currently snapping */
356   fail_unless (ges_timeline_element_roll_end (GES_TIMELINE_ELEMENT (clip1),
357           62));
358   fail_unless (ges_timeline_element_roll_end (GES_TIMELINE_ELEMENT (clip1),
359           72) == TRUE);
360   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
361   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 52);
362   CHECK_OBJECT_PROPS (trackelement2, 72, 10, 50);
363
364   /**
365    *                    0----------
366    *                    |   clip    |
367    *                    25---------62
368    * inpoints           5--------------- 10--------
369    *                    |     clip1      ||  clip2   |
370    * time               25------------- 72 --------122
371    */
372   g_object_set (timeline, "snapping-distance", (guint64) 4, NULL);
373   fail_unless (ges_timeline_element_trim (GES_TIMELINE_ELEMENT (clip1),
374           28) == TRUE);
375   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
376   CHECK_OBJECT_PROPS (trackelement1, 25, 5, 47);
377   CHECK_OBJECT_PROPS (trackelement2, 72, 10, 50);
378
379   /**
380    *                    0----------
381    *                    |   clip    |
382    *                    25---------62
383    * inpoints           5---------- 0---------
384    *                    |  clip1    ||  clip2   |
385    * time               25-------- 62 --------122
386    */
387   fail_unless (ges_timeline_element_roll_start (GES_TIMELINE_ELEMENT (clip2),
388           59) == TRUE);
389   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
390   CHECK_OBJECT_PROPS (trackelement1, 25, 5, 37);
391   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
392
393   /**
394    *                  0----------
395    *                  |   clip  |
396    *                  25--------62
397    * inpoints           5-----------------------+
398    *                    |  clip1    ||  clip2   |
399    * time               30------------]--------122
400    *                                 67
401    */
402   ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 30);
403   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
404   CHECK_OBJECT_PROPS (trackelement1, 30, 5, 37);
405   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
406
407    /**
408    * inpoints           0----------5--------------
409    *                    |   clip    ||  clip1    |
410    * time               25----------62----------99
411    *                                            0-----------
412    *                                            |  clip2   |
413    *                                            98--------168
414    * Check that clip1 snaps with the end of clip */
415   fail_unless (ges_timeline_element_ripple (GES_TIMELINE_ELEMENT (clip1),
416           58) == TRUE);
417   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
418   CHECK_OBJECT_PROPS (trackelement1, 62, 5, 37);
419   CHECK_OBJECT_PROPS (trackelement2, 94, 0, 60);
420
421   /**
422    * inpoints     0----------- 5------------   0-----------
423    *              |   clip    ||  clip1    |   |  clip2    |
424    * time         25----------62----------99  110--------170
425    */
426   ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE,
427       110);
428   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
429   CHECK_OBJECT_PROPS (trackelement1, 62, 5, 37);
430   CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
431
432   /**
433    * inpoints     0----------5    5 --------- 0----------
434    *              |   clip    |    |  clip1    ||  clip2    |
435    * time         25---------62   73---------110--------170
436    */
437   fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_NORMAL,
438           GES_EDGE_NONE, 72) == TRUE);
439   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
440   CHECK_OBJECT_PROPS (trackelement1, 73, 5, 37);
441   CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
442
443   /**
444    * inpoints     0----------5----------     0----------
445    *              |   clip    ||  clip1    |   |  clip2    |
446    * time         25---------62-------- 99  110--------170
447    */
448   fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_NORMAL,
449           GES_EDGE_NONE, 58) == TRUE);
450   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
451   CHECK_OBJECT_PROPS (trackelement1, 62, 5, 37);
452   CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
453
454
455   /**
456    * inpoints     0----------5---------- 0----------
457    *              |   clip    ||  clip1   ||  clip2    |
458    * time         25---------62--------110--------170
459    */
460   g_object_set (clip1, "duration", (guint64) 46, NULL);
461   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
462   CHECK_OBJECT_PROPS (trackelement1, 62, 5, 48);
463   CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
464
465   /**
466    * inpoints     5----------- 0--------- 0----------
467    *              |   clip1    ||  clip2   ||  clip     |
468    * time         62---------110--------170--------207
469    */
470   ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 168);
471   CHECK_OBJECT_PROPS (trackelement, 170, 0, 37);
472   CHECK_OBJECT_PROPS (trackelement1, 62, 5, 48);
473   CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60);
474
475   /* Check we didn't lose/screwed any references */
476   ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 4);
477   ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 4);
478   ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 4);
479   ASSERT_OBJECT_REFCOUNT (clip, "First clip", 2);
480   ASSERT_OBJECT_REFCOUNT (clip1, "Second clip", 2);
481   ASSERT_OBJECT_REFCOUNT (clip2, "Third clip", 2);
482
483   check_destroyed (G_OBJECT (timeline), G_OBJECT (trackelement),
484       trackelement1, trackelement2, clip, clip1, clip2, layer, NULL);
485
486   ges_deinit ();
487 }
488
489 GST_END_TEST;
490
491 static void
492 asset_added_cb (GESProject * project, GESAsset * asset, void *mainloop)
493 {
494   GstDiscovererInfo *info;
495
496   info = ges_uri_clip_asset_get_info (GES_URI_CLIP_ASSET (asset));
497   fail_unless (GST_IS_DISCOVERER_INFO (info));
498
499   g_main_loop_quit ((GMainLoop *) mainloop);
500 }
501
502 GST_START_TEST (test_simple_triming)
503 {
504   GList *assets;
505   GMainLoop *mainloop;
506   GESClipAsset *asset;
507   GESProject *project;
508   GESTimeline *timeline;
509   GESLayer *layer;
510   GESTimelineElement *element;
511   gchar *uri;
512
513   ges_init ();
514
515   uri = ges_test_file_uri ("audio_video.ogg");
516
517   project = ges_project_new (NULL);
518
519   mainloop = g_main_loop_new (NULL, FALSE);
520
521   g_signal_connect (project, "asset-added", (GCallback) asset_added_cb,
522       mainloop);
523   ges_project_create_asset (project, uri, GES_TYPE_URI_CLIP);
524   g_free (uri);
525
526   g_main_loop_run (mainloop);
527
528   /* the asset is now loaded */
529   timeline = ges_timeline_new_audio_video ();
530   assets = ges_project_list_assets (project, GES_TYPE_CLIP);
531
532   assert_equals_int (g_list_length (assets), 1);
533   asset = assets->data;
534
535   layer = ges_layer_new ();
536   ges_timeline_add_layer (timeline, layer);
537
538   ges_layer_add_asset (layer, GES_ASSET (asset), 0, 0, 10,
539       ges_clip_asset_get_supported_formats (asset));
540
541   element = ges_layer_get_clips (layer)->data;
542
543   DEEP_CHECK (element, 0, 0, 10);
544   ges_container_edit (GES_CONTAINER (element), NULL, -1, GES_EDIT_MODE_TRIM,
545       GES_EDGE_START, 5);
546   DEEP_CHECK (element, 5, 5, 5);
547
548   g_main_loop_unref (mainloop);
549   gst_object_unref (timeline);
550   gst_object_unref (project);
551
552   ges_deinit ();
553 }
554
555 GST_END_TEST;
556
557 GST_START_TEST (test_timeline_edition_mode)
558 {
559   GESTrack *track;
560   GESTimeline *timeline;
561   GESTrackElement *trackelement, *trackelement1, *trackelement2;
562   GESContainer *clip, *clip1, *clip2;
563   GESLayer *layer, *layer1, *layer2;
564   GList *trackelements, *layers, *tmp;
565
566   ges_init ();
567
568   track = GES_TRACK (ges_video_track_new ());
569   fail_unless (track != NULL);
570
571   timeline = ges_timeline_new ();
572   fail_unless (timeline != NULL);
573
574   fail_unless (ges_timeline_add_track (timeline, track));
575
576   clip = GES_CONTAINER (ges_test_clip_new ());
577   clip1 = GES_CONTAINER (ges_test_clip_new ());
578   clip2 = GES_CONTAINER (ges_test_clip_new ());
579
580   fail_unless (clip && clip1 && clip2);
581
582   /**
583    * Our timeline
584    *
585    *          0-------
586    * layer:   |  clip  |
587    *          0-------10
588    *
589    *                   0--------     0-----------
590    * layer1:           |  clip1  |    |     clip2  |
591    *                  10--------20   50---------60
592    */
593   g_object_set (clip, "start", (guint64) 0, "duration", (guint64) 10,
594       "in-point", (guint64) 0, NULL);
595   g_object_set (clip1, "start", (guint64) 10, "duration", (guint64) 10,
596       "in-point", (guint64) 0, NULL);
597   g_object_set (clip2, "start", (guint64) 50, "duration", (guint64) 60,
598       "in-point", (guint64) 0, NULL);
599
600   fail_unless ((layer = ges_timeline_append_layer (timeline)) != NULL);
601   assert_equals_int (ges_layer_get_priority (layer), 0);
602
603
604   fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip)));
605   fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip)) != NULL);
606   fail_unless ((trackelement =
607           GES_TRACK_ELEMENT (trackelements->data)) != NULL);
608   fail_unless (ges_track_element_get_track (trackelement) == track);
609   assert_equals_uint64 (_DURATION (trackelement), 10);
610
611   /* Add a new layer and add clipects to it */
612   fail_unless ((layer1 = ges_timeline_append_layer (timeline)) != NULL);
613   fail_unless (layer != layer1);
614   assert_equals_int (ges_layer_get_priority (layer1), 1);
615
616   fail_unless (ges_layer_add_clip (layer1, GES_CLIP (clip1)));
617   fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip1)) != NULL);
618   fail_unless ((trackelement1 =
619           GES_TRACK_ELEMENT (trackelements->data)) != NULL);
620   fail_unless (ges_track_element_get_track (trackelement1) == track);
621   assert_equals_uint64 (_DURATION (trackelement1), 10);
622
623   fail_unless (ges_layer_add_clip (layer1, GES_CLIP (clip2)));
624   fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip2)) != NULL);
625   fail_unless ((trackelement2 =
626           GES_TRACK_ELEMENT (trackelements->data)) != NULL);
627   fail_unless (ges_track_element_get_track (trackelement2) == track);
628   assert_equals_uint64 (_DURATION (trackelement2), 60);
629
630   /**
631    * Simple rippling clip to: 10
632    *
633    * New timeline:
634    * ------------
635    *
636    * inpoints 0-------
637    *          |  clip  |
638    * time    10-------20
639    *
640    *                   0--------      0-----------
641    *                   |  clip1  |     |   clip2    |
642    *                  20--------30    60--------120
643    */
644   fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_RIPPLE,
645           GES_EDGE_NONE, 10) == TRUE);
646   CHECK_OBJECT_PROPS (trackelement, 10, 0, 10);
647   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
648   CHECK_OBJECT_PROPS (trackelement2, 60, 0, 60);
649
650
651   /* FIXME find a way to check that we are using the same MovingContext
652    * inside the GESTimeline */
653   fail_unless (ges_container_edit (clip1, NULL, 3, GES_EDIT_MODE_RIPPLE,
654           GES_EDGE_NONE, 40) == TRUE);
655   CHECK_OBJECT_PROPS (trackelement, 10, 0, 10);
656   CHECK_OBJECT_PROPS (trackelement1, 40, 0, 10);
657   CHECK_OBJECT_PROPS (trackelement2, 80, 0, 60);
658   layer2 = ges_clip_get_layer (GES_CLIP (clip1));
659   assert_equals_int (ges_layer_get_priority (layer2), 3);
660   /* clip2 should have moved layer too */
661   fail_unless (ges_clip_get_layer (GES_CLIP (clip2)) == layer2);
662   /* We got 2 reference to the same clipect, unref them */
663   gst_object_unref (layer2);
664   gst_object_unref (layer2);
665
666   /**
667    * Rippling clip1 back to: 20 (getting to the exact same timeline as before
668    */
669   fail_unless (ges_container_edit (clip1, NULL, 1, GES_EDIT_MODE_RIPPLE,
670           GES_EDGE_NONE, 20) == TRUE);
671   CHECK_OBJECT_PROPS (trackelement, 10, 0, 10);
672   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
673   CHECK_OBJECT_PROPS (trackelement2, 60, 0, 60);
674   layer2 = ges_clip_get_layer (GES_CLIP (clip1));
675   assert_equals_int (ges_layer_get_priority (layer2), 1);
676   /* clip2 should have moved layer too */
677   fail_unless (ges_clip_get_layer (GES_CLIP (clip2)) == layer2);
678   /* We got 2 reference to the same clipect, unref them */
679   gst_object_unref (layer2);
680   gst_object_unref (layer2);
681
682   /**
683    * Simple move clip to 27 and clip2 to 35
684    *
685    * New timeline:
686    * ------------
687    *
688    * inpoints 0-------
689    *          |  clip  |
690    * time    27-------37
691    *
692    *                   0--------   0-----------
693    *                   |  clip1  |  |   clip2    |
694    *                  20--------30 35---------95
695    */
696   fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_NORMAL,
697           GES_EDGE_NONE, 27) == TRUE);
698   fail_unless (ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_NORMAL,
699           GES_EDGE_NONE, 35) == TRUE);
700   CHECK_OBJECT_PROPS (trackelement, 27, 0, 10);
701   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
702   CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60);
703
704   /**
705    * Simple trimming start clip to: 32
706    *
707    * New timeline:
708    * ------------
709    *
710    *                      5-------
711    * layer 0:             |  clip  |
712    *                     32-------37
713    *
714    *               0--------      0-----------
715    * layer 1       |  clip1  |     |   clip2    |
716    *              20--------30    35---------95
717    */
718   fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_TRIM,
719           GES_EDGE_START, 32) == TRUE);
720   CHECK_OBJECT_PROPS (trackelement, 32, 5, 5);
721   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
722   CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60);
723
724   /* Ripple end clip to 35 and move to layer 2
725    * New timeline:
726    * ------------
727    *
728    *            0--------          0-----------
729    * layer 1:   |  clip1  |         |   clip2    |
730    *            20--------30       35---------95
731    *
732    *                        5------
733    * layer 2:               |  clip |
734    *                       32------35
735    */
736   fail_unless (ges_container_edit (clip, NULL, 2, GES_EDIT_MODE_RIPPLE,
737           GES_EDGE_END, 35) == TRUE);
738   CHECK_OBJECT_PROPS (trackelement, 32, 5, 3);
739   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
740   CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60);
741   assert_equals_int (GES_TIMELINE_ELEMENT_LAYER_PRIORITY (clip), 2);
742
743   /* Roll end clip to 50
744    * New timeline:
745    * ------------
746    *
747    *            0--------          0-----------
748    * layer 1:   |  clip1  |         |   clip2    |
749    *            20--------30       50---------95
750    *
751    *                        5------
752    * layer 2:               |  clip |
753    *                       32------50
754    */
755   fail_unless (ges_container_edit (clip, NULL, 2, GES_EDIT_MODE_ROLL,
756           GES_EDGE_END, 50) == TRUE);
757   CHECK_OBJECT_PROPS (trackelement, 32, 5, 18);
758   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
759   CHECK_OBJECT_PROPS (trackelement2, 50, 15, 45);
760   layer = ges_clip_get_layer (GES_CLIP (clip));
761   assert_equals_int (ges_layer_get_priority (layer), 2);
762   gst_object_unref (layer);
763
764   /* Roll end clip back to 35
765    * New timeline:
766    * ------------
767    *
768    *            0--------          0-----------
769    * layer 1:   |  clip1  |         |   clip2    |
770    *            20--------30       35---------95
771    *
772    *                        5------
773    * layer 2:               |  clip |
774    *                       32------35
775    */
776   fail_unless (ges_container_edit (clip, NULL, 2, GES_EDIT_MODE_ROLL,
777           GES_EDGE_END, 35) == TRUE);
778   CHECK_OBJECT_PROPS (trackelement, 32, 5, 3);
779   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
780   CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60);
781   layer = ges_clip_get_layer (GES_CLIP (clip));
782   assert_equals_int (ges_layer_get_priority (layer), 2);
783   gst_object_unref (layer);
784
785   /* Ripple clip end to 52
786    * New timeline:
787    * ------------
788    *
789    *            0--------          0----------
790    * layer 1:   |  clip1  |         |   clip2   |
791    *            20-------30       52---------112
792    *
793    *                        5------
794    * layer 2:               |  clip |
795    *                       32------52
796    *
797    */
798   /* Can not move to the first layer as clip2 should move to a layer with priority < 0 */
799   fail_unless (ges_container_edit (clip, NULL, 0, GES_EDIT_MODE_RIPPLE,
800           GES_EDGE_END, 52) == TRUE);
801   CHECK_OBJECT_PROPS (trackelement, 32, 5, 20);
802   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
803   CHECK_OBJECT_PROPS (trackelement2, 52, 0, 60);
804   assert_equals_int (GES_TIMELINE_ELEMENT_LAYER_PRIORITY (clip), 2);
805
806
807   /* Little check that we have 4 layers in the timeline */
808   layers = ges_timeline_get_layers (timeline);
809   assert_equals_int (g_list_length (layers), 4);
810
811   /* Some refcount checkings */
812   /*  We have a reference to each layer in layers */
813   for (tmp = layers; tmp; tmp = tmp->next)
814     ASSERT_OBJECT_REFCOUNT (layer, "Layer", 2);
815   g_list_free_full (layers, gst_object_unref);
816
817   /* We have 3 references:
818    *  track  + timeline  + clip
819    */
820   ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 4);
821   ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 4);
822   ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 4);
823   ASSERT_OBJECT_REFCOUNT (clip, "First clip", 2);
824   ASSERT_OBJECT_REFCOUNT (clip1, "Second clip", 2);
825   ASSERT_OBJECT_REFCOUNT (clip2, "Third clip", 2);
826
827   /* Ripple clip end to 52
828    * New timeline:
829    * ------------
830    *
831    *            0--------          0-----------
832    * layer 0:   |  clip1  |         |   clip2    |
833    *            20-------40       62----------112
834    *
835    *                        5------
836    * layer 1:               |  clip |
837    *                       42------60
838    *
839    */
840   fail_unless (ges_container_edit (clip1, NULL, 0, GES_EDIT_MODE_RIPPLE,
841           GES_EDGE_END, 40) == TRUE);
842   CHECK_OBJECT_PROPS (trackelement, 42, 5, 20);
843   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20);
844   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
845
846   /* Check that movement between layer has been done properly */
847   layer1 = ges_clip_get_layer (GES_CLIP (clip));
848   layer = ges_clip_get_layer (GES_CLIP (clip1));
849   assert_equals_int (ges_layer_get_priority (layer1), 1);
850   assert_equals_int (ges_layer_get_priority (layer), 0);
851   fail_unless (ges_clip_get_layer (GES_CLIP (clip2)) == layer);
852   gst_object_unref (layer1);
853   /* We have 2 references to @layer that we do not need anymore */ ;
854   gst_object_unref (layer);
855   gst_object_unref (layer);
856
857   /* Trim clip start to 40
858    * New timeline:
859    * ------------
860    *
861    *            0--------          0-----------
862    * layer 0:   |  clip1  |         |   clip2    |
863    *            20-------40       62---------112
864    *
865    *                      0------
866    * layer 1:             |  clip |
867    *                     40------62
868    *
869    */
870   fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_TRIM,
871           GES_EDGE_START, 40) == TRUE);
872   CHECK_OBJECT_PROPS (trackelement, 40, 3, 22);
873   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20);
874   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
875
876   /* Roll clip end to 25
877    * New timeline:
878    * ------------
879    *
880    *            0--------          0-----------
881    * layer 0:   |  clip1  |         |   clip2    |
882    *            20-------25       62---------112
883    *
884    *                      0------
885    * layer 1:             |  clip |
886    *                     25------62
887    *
888    */
889   ges_timeline_element_set_inpoint (GES_TIMELINE_ELEMENT (clip), 15);
890   fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL,
891           GES_EDGE_END, 25) == TRUE);
892   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
893   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5);
894   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
895
896   /* Make sure that not doing anything when not able to roll */
897   fail_if (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_ROLL,
898           GES_EDGE_START, 65));
899   fail_if (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL,
900           GES_EDGE_END, 65));
901   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
902   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5);
903   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
904
905   /* Snaping to edge, so no move */
906   g_object_set (timeline, "snapping-distance", (guint64) 3, NULL);
907   fail_if (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM,
908           GES_EDGE_END, 27));
909   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
910   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5);
911   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
912
913   /* Snaping to edge, so no move */
914   fail_if (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM,
915           GES_EDGE_END, 27));
916
917   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
918   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5);
919   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
920
921   /**
922    * New timeline:
923    * ------------
924    *                    0----------- 0-------------
925    * inpoints   0-------|--   clip  ||   clip2      |
926    *            |  clip1 25-|------- 62 -----------122
927    * time      20----------30
928    */
929   g_object_set (timeline, "snapping-distance", (guint64) 0, NULL);
930   fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM,
931           GES_EDGE_END, 30) == TRUE);
932   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
933   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10);
934   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
935
936   /**
937    * New timeline
938    * ------------
939    *                    0----------
940    *                    |   clip   |
941    *                    25---------62
942    * inpoints   0----------------------- 10--------
943    *            |       clip1           ||  clip2  |
944    * time      20---------------------- 72 --------122
945    */
946   /* Rolling involves only neighbours that are currently snapping */
947   fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL,
948           GES_EDGE_END, 62) == TRUE);
949   fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL,
950           GES_EDGE_END, 72) == TRUE);
951   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
952   CHECK_OBJECT_PROPS (trackelement1, 20, 0, 52);
953   CHECK_OBJECT_PROPS (trackelement2, 72, 10, 50);
954
955   /* Test Snapping */
956   /**
957    *                    0----------
958    *                    |   clip   |
959    *                    25---------62
960    * inpoints           5--------------- 10--------
961    *                    |     clip1     ||  clip2  |
962    * time               25------------- 72 --------122
963    */
964   g_object_set (timeline, "snapping-distance", (guint64) 4, NULL);
965   fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM,
966           GES_EDGE_START, 28) == TRUE);
967   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
968   CHECK_OBJECT_PROPS (trackelement1, 25, 5, 47);
969   CHECK_OBJECT_PROPS (trackelement2, 72, 10, 50);
970
971   /**
972    *                    0----------
973    *                    |   clip   |
974    *                    25---------62
975    * inpoints           5---------- 0---------
976    *                    |  clip1   ||  clip2  |
977    * time               25-------- 62 --------122
978    */
979   fail_unless (ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_ROLL,
980           GES_EDGE_START, 59) == TRUE);
981   CHECK_OBJECT_PROPS (trackelement, 25, 0, 37);
982   CHECK_OBJECT_PROPS (trackelement1, 25, 5, 37);
983   CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60);
984
985   ges_deinit ();
986 }
987
988 GST_END_TEST;
989
990 GST_START_TEST (test_groups)
991 {
992   GESAsset *asset;
993   GESTimeline *timeline;
994   GESGroup *group;
995   GESLayer *layer, *layer1, *layer2, *layer3;
996   GESClip *c, *c1, *c2, *c3, *c4, *c5;
997
998   GList *clips = NULL;
999
1000   ges_init ();
1001
1002   timeline = ges_timeline_new_audio_video ();
1003
1004   /* Our timeline
1005    *
1006    *    --0------------10-Group-----20---------------30-----------------------70
1007    *      | +-----------+                             |+-----------50         |
1008    * L    | |    C      |                             ||     C3    |          |
1009    *      | +-----------+                             |+-----------+          |
1010    *    --|-------------------------------------------|-----40----------------|
1011    *      |            +------------+ +-------------+ |      +--------60      |
1012    * L1   |            |     C1     | |     C2      | |      |     C4 |       |
1013    *      |            +------------+ +-------------+ |      +--------+       |
1014    *    --|-------------------------------------------|-----------------------|
1015    *      |                                           |             +--------+|
1016    * L2   |                                           |             |  c5    ||
1017    *      |                                           |             +--------+|
1018    *    --+-------------------------------------------+-----------------------+
1019    *
1020    * L3
1021    *
1022    *    -----------------------------------------------------------------------
1023    */
1024
1025   layer = ges_timeline_append_layer (timeline);
1026   layer1 = ges_timeline_append_layer (timeline);
1027   layer2 = ges_timeline_append_layer (timeline);
1028   layer3 = ges_timeline_append_layer (timeline);
1029   assert_equals_int (ges_layer_get_priority (layer3), 3);
1030   asset = ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL);
1031
1032   c = ges_layer_add_asset (layer, asset, 0, 0, 10, GES_TRACK_TYPE_UNKNOWN);
1033   c1 = ges_layer_add_asset (layer1, asset, 10, 0, 10, GES_TRACK_TYPE_UNKNOWN);
1034   c2 = ges_layer_add_asset (layer1, asset, 20, 0, 10, GES_TRACK_TYPE_UNKNOWN);
1035   clips = g_list_prepend (clips, c);
1036   clips = g_list_prepend (clips, c1);
1037   clips = g_list_prepend (clips, c2);
1038   group = GES_GROUP (ges_container_group (clips));
1039   fail_unless (GES_TIMELINE_ELEMENT_TIMELINE (group) == timeline);
1040   g_list_free (clips);
1041
1042   fail_unless (GES_IS_GROUP (group));
1043   DEEP_CHECK (c, 0, 0, 10);
1044   DEEP_CHECK (c1, 10, 0, 10);
1045   DEEP_CHECK (c2, 20, 0, 10);
1046   CHECK_OBJECT_PROPS (group, 0, 0, 30);
1047
1048   c3 = ges_layer_add_asset (layer, asset, 30, 0, 20, GES_TRACK_TYPE_UNKNOWN);
1049   c4 = ges_layer_add_asset (layer1, asset, 40, 0, 20, GES_TRACK_TYPE_UNKNOWN);
1050   c5 = ges_layer_add_asset (layer2, asset, 50, 0, 20, GES_TRACK_TYPE_UNKNOWN);
1051
1052   DEEP_CHECK (c3, 30, 0, 20);
1053   DEEP_CHECK (c4, 40, 0, 20);
1054   DEEP_CHECK (c5, 50, 0, 20);
1055   check_layer (c, 0);
1056   check_layer (c1, 1);
1057   check_layer (c2, 1);
1058   check_layer (c3, 0);
1059   check_layer (c4, 1);
1060   check_layer (c5, 2);
1061
1062   fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, -1,
1063           GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 10) == TRUE);
1064
1065   DEEP_CHECK (c, 10, 0, 10);
1066   DEEP_CHECK (c1, 10, 0, 10);
1067   DEEP_CHECK (c2, 30, 0, 10);
1068   DEEP_CHECK (c3, 40, 0, 20);
1069   DEEP_CHECK (c4, 50, 0, 20);
1070   DEEP_CHECK (c5, 60, 0, 20);
1071   check_layer (c, 0);
1072   check_layer (c1, 1);
1073   check_layer (c2, 1);
1074   check_layer (c3, 0);
1075   check_layer (c4, 1);
1076   check_layer (c5, 2);
1077
1078   fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 1,
1079           GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 10) == TRUE);
1080   DEEP_CHECK (c, 10, 0, 10);
1081   DEEP_CHECK (c1, 10, 0, 10);
1082   DEEP_CHECK (c2, 30, 0, 10);
1083   DEEP_CHECK (c3, 40, 0, 20);
1084   DEEP_CHECK (c4, 50, 0, 20);
1085   DEEP_CHECK (c5, 60, 0, 20);
1086   check_layer (c, 1);
1087   check_layer (c1, 2);
1088   check_layer (c2, 2);
1089   check_layer (c3, 1);
1090   check_layer (c4, 2);
1091   check_layer (c5, 3);
1092
1093   fail_unless (ges_container_edit (GES_CONTAINER (c1), NULL, 2,
1094           GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 40) == TRUE);
1095   DEEP_CHECK (c, 10, 0, 10);
1096   DEEP_CHECK (c1, 10, 0, 30);
1097   DEEP_CHECK (c2, 50, 0, 10);
1098   DEEP_CHECK (c3, 60, 0, 20);
1099   DEEP_CHECK (c4, 70, 0, 20);
1100   DEEP_CHECK (c5, 80, 0, 20);
1101   check_layer (c, 1);
1102   check_layer (c1, 2);
1103   check_layer (c2, 2);
1104   check_layer (c3, 1);
1105   check_layer (c4, 2);
1106   check_layer (c5, 3);
1107
1108   fail_unless (ges_container_edit (GES_CONTAINER (c1), NULL, 2,
1109           GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 30) == TRUE);
1110   DEEP_CHECK (c, 10, 0, 10);
1111   DEEP_CHECK (c1, 10, 0, 20);
1112   DEEP_CHECK (c2, 40, 0, 10);
1113   DEEP_CHECK (c3, 50, 0, 20);
1114   DEEP_CHECK (c4, 60, 0, 20);
1115   DEEP_CHECK (c5, 70, 0, 20);
1116   check_layer (c, 1);
1117   check_layer (c1, 2);
1118   check_layer (c2, 2);
1119   check_layer (c3, 1);
1120   check_layer (c4, 2);
1121   check_layer (c5, 3);
1122
1123   fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 0,
1124           GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 0) == TRUE);
1125   DEEP_CHECK (c, 0, 0, 10);
1126   DEEP_CHECK (c1, 10, 0, 20);
1127   DEEP_CHECK (c2, 30, 0, 10);
1128   DEEP_CHECK (c3, 40, 0, 20);
1129   DEEP_CHECK (c4, 50, 0, 20);
1130   DEEP_CHECK (c5, 60, 0, 20);
1131   check_layer (c, 0);
1132   check_layer (c1, 1);
1133   check_layer (c2, 1);
1134   check_layer (c3, 0);
1135   check_layer (c4, 1);
1136   check_layer (c5, 2);
1137
1138   fail_if (ges_container_edit (GES_CONTAINER (c2), NULL, -1,
1139           GES_EDIT_MODE_ROLL, GES_EDGE_END, 40) == TRUE);
1140   DEEP_CHECK (c, 0, 0, 10);
1141   DEEP_CHECK (c1, 10, 0, 20);
1142   DEEP_CHECK (c2, 30, 0, 10);
1143   DEEP_CHECK (c3, 40, 0, 20);
1144   DEEP_CHECK (c4, 50, 0, 20);
1145   DEEP_CHECK (c5, 60, 0, 20);
1146   check_layer (c, 0);
1147   check_layer (c1, 1);
1148   check_layer (c2, 1);
1149   check_layer (c3, 0);
1150   check_layer (c4, 1);
1151   check_layer (c5, 2);
1152
1153   fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 0,
1154           GES_EDIT_MODE_TRIM, GES_EDGE_START, 5) == TRUE);
1155   CHECK_OBJECT_PROPS (c, 5, 5, 5);
1156   DEEP_CHECK (c1, 10, 0, 20);
1157   DEEP_CHECK (c2, 30, 0, 10);
1158   DEEP_CHECK (c3, 40, 0, 20);
1159   DEEP_CHECK (c4, 50, 0, 20);
1160   DEEP_CHECK (c5, 60, 0, 20);
1161   CHECK_OBJECT_PROPS (group, 5, 0, 35);
1162   check_layer (c, 0);
1163   check_layer (c1, 1);
1164   check_layer (c2, 1);
1165   check_layer (c3, 0);
1166   check_layer (c4, 1);
1167   check_layer (c5, 2);
1168
1169   gst_object_unref (timeline);
1170   gst_object_unref (asset);
1171
1172   ges_deinit ();
1173 }
1174
1175 GST_END_TEST;
1176
1177 GST_START_TEST (test_snapping_groups)
1178 {
1179   GESAsset *asset;
1180   GESTimeline *timeline;
1181   GESGroup *group;
1182   GESLayer *layer, *layer1, *layer2, *layer3;
1183   GESClip *c, *c1, *c2, *c3, *c4, *c5;
1184
1185   GList *clips = NULL;
1186
1187   ges_init ();
1188
1189   timeline = ges_timeline_new_audio_video ();
1190   g_object_set (timeline, "snapping-distance", (guint64) 3, NULL);
1191
1192   /* Our timeline
1193    *
1194    *    --0------------10-Group-----20---------25-----30----------------------70
1195    *      | +-----------+                      |       +-----------50         |
1196    * L    | |    C      |                      |       |     C3    |          |
1197    *      | +-----------+                      |       +-----------+          |
1198    *    --|------------------------------------|------------40----------------|
1199    *      |            +------------+ +--------+             +--------60      |
1200    * L1   |            |     C1     | |     C2 |             |     C4 |       |
1201    *      |            +------------+ +--------+             +--------+       |
1202    *    --|------------------------------------+------------------------------|
1203    *      |                                                         +--------+|
1204    * L2   |                                                         |  c5    ||
1205    *      |                                                         +--------+|
1206    *    --+-------------------------------------------------------------------+
1207    *
1208    * L3
1209    *
1210    *    -----------------------------------------------------------------------
1211    */
1212
1213   layer = ges_timeline_append_layer (timeline);
1214   layer1 = ges_timeline_append_layer (timeline);
1215   layer2 = ges_timeline_append_layer (timeline);
1216   layer3 = ges_timeline_append_layer (timeline);
1217   assert_equals_int (ges_layer_get_priority (layer3), 3);
1218   asset = ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL);
1219
1220   c = ges_layer_add_asset (layer, asset, 0, 0, 10, GES_TRACK_TYPE_UNKNOWN);
1221   c1 = ges_layer_add_asset (layer1, asset, 10, 0, 10, GES_TRACK_TYPE_UNKNOWN);
1222   c2 = ges_layer_add_asset (layer1, asset, 20, 0, 5, GES_TRACK_TYPE_UNKNOWN);
1223   clips = g_list_prepend (clips, c);
1224   clips = g_list_prepend (clips, c1);
1225   clips = g_list_prepend (clips, c2);
1226   group = GES_GROUP (ges_container_group (clips));
1227   fail_unless (GES_TIMELINE_ELEMENT_TIMELINE (group) == timeline);
1228   g_list_free (clips);
1229
1230   fail_unless (GES_IS_GROUP (group));
1231   CHECK_OBJECT_PROPS (c, 0, 0, 10);
1232   CHECK_OBJECT_PROPS (c1, 10, 0, 10);
1233   CHECK_OBJECT_PROPS (c2, 20, 0, 5);
1234   CHECK_OBJECT_PROPS (group, 0, 0, 25);
1235
1236   c3 = ges_layer_add_asset (layer, asset, 30, 0, 20, GES_TRACK_TYPE_UNKNOWN);
1237   c4 = ges_layer_add_asset (layer1, asset, 40, 0, 20, GES_TRACK_TYPE_UNKNOWN);
1238   c5 = ges_layer_add_asset (layer2, asset, 50, 0, 20, GES_TRACK_TYPE_UNKNOWN);
1239
1240   CHECK_OBJECT_PROPS (c3, 30, 0, 20);
1241   CHECK_OBJECT_PROPS (c4, 40, 0, 20);
1242   CHECK_OBJECT_PROPS (c5, 50, 0, 20);
1243   check_layer (c, 0);
1244   check_layer (c1, 1);
1245   check_layer (c2, 1);
1246   check_layer (c3, 0);
1247   check_layer (c4, 1);
1248   check_layer (c5, 2);
1249
1250   /* c2 should snap with C3 and make the group moving to 5 */
1251   fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, -1,
1252           GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 3) == TRUE);
1253
1254   DEEP_CHECK (c, 5, 0, 10);
1255   DEEP_CHECK (c1, 15, 0, 10);
1256   DEEP_CHECK (c2, 25, 0, 5);
1257   DEEP_CHECK (c2, 25, 0, 5);
1258   DEEP_CHECK (c4, 40, 0, 20);
1259   DEEP_CHECK (c5, 50, 0, 20);
1260   CHECK_OBJECT_PROPS (group, 5, 0, 25);
1261   check_layer (c, 0);
1262   check_layer (c1, 1);
1263   check_layer (c2, 1);
1264   check_layer (c3, 0);
1265   check_layer (c4, 1);
1266   check_layer (c5, 2);
1267
1268
1269   gst_object_unref (timeline);
1270   gst_object_unref (asset);
1271
1272   ges_deinit ();
1273 }
1274
1275 GST_END_TEST;
1276
1277 static void
1278 _set_track_element_width_height (GESTrackElement * trksrc, gint wvalue,
1279     gint hvalue)
1280 {
1281   GValue width = { 0 };
1282   GValue height = { 0 };
1283
1284   g_value_init (&width, G_TYPE_INT);
1285   g_value_init (&height, G_TYPE_INT);
1286   g_value_set_int (&width, wvalue);
1287   g_value_set_int (&height, hvalue);
1288   if (wvalue >= 0)
1289     ges_timeline_element_set_child_property (GES_TIMELINE_ELEMENT (trksrc),
1290         "width", &width);
1291   if (hvalue >= 0)
1292     ges_timeline_element_set_child_property (GES_TIMELINE_ELEMENT (trksrc),
1293         "height", &height);
1294 }
1295
1296 static gboolean
1297 check_frame_positioner_size (GESClip * clip, gint width, gint height)
1298 {
1299   GESTrackElement *trksrc;
1300   GValue val_width = { 0 };
1301   GValue val_height = { 0 };
1302   gint real_width, real_height;
1303
1304   trksrc = GES_CONTAINER_CHILDREN (clip)->data;
1305   if (!GES_IS_VIDEO_SOURCE (trksrc))
1306     return FALSE;
1307
1308   g_value_init (&val_width, G_TYPE_INT);
1309   g_value_init (&val_height, G_TYPE_INT);
1310
1311   ges_timeline_element_get_child_property (GES_TIMELINE_ELEMENT (trksrc),
1312       "width", &val_width);
1313   ges_timeline_element_get_child_property (GES_TIMELINE_ELEMENT (trksrc),
1314       "height", &val_height);
1315
1316   real_width = g_value_get_int (&val_width);
1317   real_height = g_value_get_int (&val_height);
1318
1319   assert_equals_int (real_width, width);
1320   assert_equals_int (real_height, height);
1321
1322   return (width == real_width && height == real_height);
1323 }
1324
1325 GST_START_TEST (test_scaling)
1326 {
1327   GESTimeline *timeline;
1328   GESLayer *layer;
1329   GESAsset *asset1, *asset2;
1330   GESClip *clip;
1331   GESTrack *trackv;
1332   GstCaps *caps;
1333
1334   ges_init ();
1335
1336   trackv = GES_TRACK (ges_video_track_new ());
1337   caps =
1338       gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, 1200, "height",
1339       G_TYPE_INT, 1000, NULL);
1340
1341   timeline = ges_timeline_new ();
1342   ges_timeline_add_track (timeline, trackv);
1343   layer = ges_layer_new ();
1344   fail_unless (ges_timeline_add_layer (timeline, layer));
1345
1346   g_object_set (layer, "auto-transition", TRUE, NULL);
1347
1348   asset1 = GES_ASSET (ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL));
1349   asset2 = GES_ASSET (ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL));
1350
1351   fail_unless (asset1 != NULL && asset2 != NULL);
1352
1353   GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (timeline),
1354       GST_DEBUG_GRAPH_SHOW_ALL, "ges-integration-timeline");
1355
1356   ges_track_set_restriction_caps (trackv, caps);
1357   gst_caps_unref (caps);
1358
1359   GST_DEBUG ("adding clip, should be 1200 x 1000");
1360   clip =
1361       ges_layer_add_asset (layer, GES_ASSET (asset1), 0 * GST_SECOND,
1362       0 * GST_SECOND, 4 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN);
1363   gst_object_unref (asset1);
1364   g_object_set (clip, "vpattern", (gint) GES_VIDEO_TEST_PATTERN_SMPTE75, NULL);
1365
1366   /**
1367    * Our track: 1200 x 1000
1368    *
1369    * 0--------------0
1370    * | width : 1200 |
1371    * | height: 1000 |
1372    * 0--------------2
1373    */
1374
1375   /* clip takes the size set on the track as a default */
1376   fail_unless (check_frame_positioner_size (clip, 1200, 1000));
1377
1378   if (GES_IS_VIDEO_SOURCE (GES_CONTAINER_CHILDREN (clip)->data))
1379     _set_track_element_width_height (GES_CONTAINER_CHILDREN (clip)->data, 1024,
1380         768);
1381
1382   GST_DEBUG ("Setting clip size, should be 1024 x 768");
1383
1384   /**
1385    * Our timeline : 1200 x 1000
1386    *
1387    * 0--------------0
1388    * | width : 1024 |
1389    * | height: 768  |
1390    * 0--------------2
1391    */
1392
1393   /* Clip has to comply to direct orders */
1394   fail_unless (check_frame_positioner_size (clip, 1024, 768));
1395
1396   GST_DEBUG ("Changing caps, should still be 1024 x 768");
1397
1398   caps =
1399       gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, 1400, "height",
1400       G_TYPE_INT, 1200, NULL);
1401   ges_track_set_restriction_caps (trackv, caps);
1402   gst_caps_unref (caps);
1403
1404   /**
1405    * Our timeline : 1400 x 1200
1406    *
1407    * 0--------------0
1408    * | width : 1024 |
1409    * | height: 768  |
1410    * 0--------------2
1411    */
1412
1413   /* Clip still has to be the same size */
1414   fail_unless (check_frame_positioner_size (clip, 1024, 768));
1415
1416   GST_DEBUG ("Setting width to 0, should be 1400 x 768");
1417
1418   /* -1 means don't set it, only valid here */
1419   if (GES_IS_VIDEO_SOURCE (GES_CONTAINER_CHILDREN (clip)->data))
1420     _set_track_element_width_height (GES_CONTAINER_CHILDREN (clip)->data, 0,
1421         -1);
1422
1423   /**
1424    * Our timeline : 1400 x 1200
1425    *
1426    * 0--------------0
1427    * | width : 1400 |
1428    * | height: 768  |
1429    * 0--------------2
1430    */
1431
1432   /* Clip width was set to 0 so it has to use track width */
1433   /* Clip height is still directly set by the user */
1434   fail_unless (check_frame_positioner_size (clip, 1400, 768));
1435
1436   GST_DEBUG ("Setting height to 0, should be 1400 x 1200");
1437
1438   if (GES_IS_VIDEO_SOURCE (GES_CONTAINER_CHILDREN (clip)->data))
1439     _set_track_element_width_height (GES_CONTAINER_CHILDREN (clip)->data, -1,
1440         0);
1441
1442   /**
1443    * Our timeline : 1400 x 1200
1444    *
1445    * 0--------------0
1446    * | width : 1400 |
1447    * | height: 1200 |
1448    * 0--------------2
1449    */
1450
1451   /* Clip width still has to use track width */
1452   /* Clip height was set to 0 so it has to use track height */
1453   fail_unless (check_frame_positioner_size (clip, 1400, 1200));
1454
1455   GST_DEBUG ("Removing restriction on track height, should be 1400 x 240");
1456
1457   caps =
1458       gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, 1400, "height",
1459       G_TYPE_INT, 0, NULL);
1460   ges_track_set_restriction_caps (trackv, caps);
1461   gst_caps_unref (caps);
1462
1463   /**
1464    * Our timeline : 1400 x no restriction
1465    *
1466    * 0--------------0
1467    * | width : 1400 |
1468    * | height: 240  |
1469    * 0--------------2
1470    */
1471
1472   /* Clip width still has to use track width */
1473   /* Clip height was set to 0 so it has to use natural clip height */
1474   fail_unless (check_frame_positioner_size (clip, 1400, 0));
1475
1476   GST_DEBUG ("Removing restriction on track width, should be 320 x 240");
1477
1478   caps = gst_caps_new_empty_simple ("video/x-raw");
1479   ges_track_set_restriction_caps (trackv, caps);
1480   gst_caps_unref (caps);
1481
1482   /**
1483    * Our timeline : no restriction x no restriction
1484    *
1485    * 0--------------0
1486    * | width : 320  |
1487    * | height: 240  |
1488    * 0--------------2
1489    */
1490
1491   /* Clip width was set to 0 so it has to use natural clip width */
1492   /* Clip height was set to 0 so it has to use natural clip height */
1493   fail_unless (check_frame_positioner_size (clip, 0, 0));
1494
1495
1496   /**
1497    * Our timeline : 320 * 240
1498    *
1499    * 0--------------0
1500    * | width : 320  |
1501    * | height: 240  |
1502    * 0--------------2
1503    */
1504
1505   /* We set the restriction caps video size to the same as the video source
1506    * size. */
1507   caps = gst_caps_from_string ("video/x-raw,height=240,width=320");
1508   ges_track_set_restriction_caps (trackv, caps);
1509   gst_caps_unref (caps);
1510   _set_track_element_width_height (GES_CONTAINER_CHILDREN (clip)->data, 320,
1511       240);
1512
1513   /* The video source has the same size as the track restriction caps but we
1514    * are changing the aspect ratio, the video should thus not be rescaled. */
1515   caps = gst_caps_from_string ("video/x-raw,height=1080,width=1920");
1516   ges_track_set_restriction_caps (trackv, caps);
1517   fail_unless (check_frame_positioner_size (clip, 320, 240));
1518
1519   gst_object_unref (timeline);
1520
1521   ges_deinit ();
1522 }
1523
1524 GST_END_TEST;
1525
1526 static Suite *
1527 ges_suite (void)
1528 {
1529   Suite *s = suite_create ("ges-timeline-edition");
1530   TCase *tc_chain = tcase_create ("timeline-edition");
1531
1532   suite_add_tcase (s, tc_chain);
1533
1534   tcase_add_test (tc_chain, test_basic_timeline_edition);
1535   tcase_add_test (tc_chain, test_snapping);
1536   tcase_add_test (tc_chain, test_timeline_edition_mode);
1537   tcase_add_test (tc_chain, test_simple_triming);
1538   tcase_add_test (tc_chain, test_groups);
1539   tcase_add_test (tc_chain, test_snapping_groups);
1540   tcase_add_test (tc_chain, test_scaling);
1541
1542   return s;
1543 }
1544
1545 GST_CHECK_MAIN (ges);