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., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 */
20
21 #include "test-utils.h"
22 #include <ges/ges.h>
23 #include <gst/check/gstcheck.h>
24 #include <gst/controller/gstdirectcontrolbinding.h>
25 #include <gst/controller/gstinterpolationcontrolsource.h>
26
27 GMainLoop *mainloop;
28
29 static void
project_loaded_cb(GESProject * project,GESTimeline * timeline,GMainLoop * mainloop)30 project_loaded_cb (GESProject * project, GESTimeline * timeline,
31 GMainLoop * mainloop)
32 {
33 g_main_loop_quit (mainloop);
34 }
35
GST_START_TEST(test_project_simple)36 GST_START_TEST (test_project_simple)
37 {
38 gchar *id;
39 GESProject *project;
40 GESTimeline *timeline;
41
42 ges_init ();
43
44 mainloop = g_main_loop_new (NULL, FALSE);
45 project = GES_PROJECT (ges_asset_request (GES_TYPE_TIMELINE, NULL, NULL));
46 fail_unless (GES_IS_PROJECT (project));
47 assert_equals_string (ges_asset_get_id (GES_ASSET (project)), "project-0");
48 g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop);
49
50 timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
51 g_main_loop_run (mainloop);
52
53 fail_unless (GES_IS_TIMELINE (timeline));
54 id = ges_extractable_get_id (GES_EXTRACTABLE (timeline));
55 assert_equals_string (id, "project-0");
56 ASSERT_OBJECT_REFCOUNT (timeline, "We own the only ref", 1);
57
58 g_free (id);
59 gst_object_unref (project);
60 gst_object_unref (timeline);
61 g_main_loop_unref (mainloop);
62 g_signal_handlers_disconnect_by_func (project, (GCallback) project_loaded_cb,
63 mainloop);
64
65 ges_deinit ();
66 }
67
68 GST_END_TEST;
69
70 static void
asset_removed_add_cb(GESProject * project,GESAsset * asset,gboolean * called)71 asset_removed_add_cb (GESProject * project, GESAsset * asset, gboolean * called)
72 {
73 *called = TRUE;
74 }
75
76 static void
asset_created_cb(GObject * source,GAsyncResult * res,GESAsset ** asset)77 asset_created_cb (GObject * source, GAsyncResult * res, GESAsset ** asset)
78 {
79 GError *error = NULL;
80 *asset = ges_asset_request_finish (res, &error);
81
82 fail_unless (error == NULL);
83 g_main_loop_quit (mainloop);
84 }
85
GST_START_TEST(test_project_add_assets)86 GST_START_TEST (test_project_add_assets)
87 {
88 GESProject *project;
89 GESAsset *asset;
90 gboolean added_cb_called = FALSE;
91 gboolean removed_cb_called = FALSE;
92
93 ges_init ();
94
95 mainloop = g_main_loop_new (NULL, FALSE);
96 project = GES_PROJECT (ges_asset_request (GES_TYPE_TIMELINE, NULL, NULL));
97 fail_unless (GES_IS_PROJECT (project));
98
99 g_signal_connect (project, "asset-added",
100 (GCallback) asset_removed_add_cb, &added_cb_called);
101 g_signal_connect (project, "asset-removed",
102 (GCallback) asset_removed_add_cb, &removed_cb_called);
103
104 ges_asset_request_async (GES_TYPE_TEST_CLIP, NULL, NULL,
105 (GAsyncReadyCallback) asset_created_cb, &asset);
106 g_main_loop_run (mainloop);
107 g_main_loop_unref (mainloop);
108
109 fail_unless (GES_IS_ASSET (asset));
110
111 fail_unless (ges_project_add_asset (project, asset));
112 fail_unless (added_cb_called);
113 ASSERT_OBJECT_REFCOUNT (project, "The project", 2);
114 ASSERT_OBJECT_REFCOUNT (asset, "The asset (1 for project and one for "
115 "us + 1 cache)", 3);
116
117 fail_unless (ges_project_remove_asset (project, asset));
118 fail_unless (removed_cb_called);
119
120 g_signal_handlers_disconnect_by_func (project,
121 (GCallback) asset_removed_add_cb, &added_cb_called);
122 g_signal_handlers_disconnect_by_func (project,
123 (GCallback) asset_removed_add_cb, &removed_cb_called);
124
125 gst_object_unref (asset);
126 gst_object_unref (project);
127 ASSERT_OBJECT_REFCOUNT (asset, "The asset (1 ref in cache)", 1);
128 ASSERT_OBJECT_REFCOUNT (project, "The project (1 ref in cache)", 1);
129
130 ges_deinit ();
131 }
132
133 GST_END_TEST;
134
135 static void
error_loading_asset_cb(GESProject * project,GError * error,gchar * id,GType extractable_type,GMainLoop * mainloop)136 error_loading_asset_cb (GESProject * project, GError * error, gchar * id,
137 GType extractable_type, GMainLoop * mainloop)
138 {
139 fail_unless (g_error_matches (error, GST_PARSE_ERROR,
140 GST_PARSE_ERROR_NO_SUCH_ELEMENT));
141 g_main_loop_quit (mainloop);
142 }
143
GST_START_TEST(test_project_unexistant_effect)144 GST_START_TEST (test_project_unexistant_effect)
145 {
146 GESProject *project;
147 gboolean added_cb_called = FALSE;
148 gboolean removed_cb_called = FALSE;
149
150 ges_init ();
151
152 project = GES_PROJECT (ges_asset_request (GES_TYPE_TIMELINE, NULL, NULL));
153 fail_unless (GES_IS_PROJECT (project));
154
155 mainloop = g_main_loop_new (NULL, FALSE);
156 g_signal_connect (project, "asset-added",
157 (GCallback) asset_removed_add_cb, &added_cb_called);
158 g_signal_connect (project, "asset-removed",
159 (GCallback) asset_removed_add_cb, &removed_cb_called);
160 g_signal_connect (project, "error-loading-asset",
161 (GCallback) error_loading_asset_cb, mainloop);
162
163 fail_unless (ges_project_create_asset (project, "nowaythiselementexists",
164 GES_TYPE_EFFECT));
165 g_main_loop_run (mainloop);
166
167 /* And.... try again! */
168 fail_if (ges_project_create_asset (project, "nowaythiselementexists",
169 GES_TYPE_EFFECT));
170
171 fail_if (added_cb_called);
172 fail_if (removed_cb_called);
173
174 ASSERT_OBJECT_REFCOUNT (project, "The project", 2);
175 gst_object_unref (project);
176 g_main_loop_unref (mainloop);
177
178 ASSERT_OBJECT_REFCOUNT (project, "The project (1 ref in cache)", 1);
179
180 ges_deinit ();
181 }
182
183 GST_END_TEST;
184
185 static void
asset_added_cb(GESProject * project,GESAsset * asset)186 asset_added_cb (GESProject * project, GESAsset * asset)
187 {
188 gchar *uri = ges_test_file_uri ("audio_video.ogg");
189 GstDiscovererInfo *info;
190
191 if (ges_asset_get_extractable_type (asset) == GES_TYPE_EFFECT) {
192 assert_equals_string (ges_asset_get_id (asset), "video agingtv");
193 } else {
194 info = ges_uri_clip_asset_get_info (GES_URI_CLIP_ASSET (asset));
195 fail_unless (GST_IS_DISCOVERER_INFO (info));
196 assert_equals_string (ges_asset_get_id (asset), uri);
197 }
198
199 g_free (uri);
200 }
201
202 static gchar *
_set_new_uri(GESProject * project,GError * error,GESAsset * wrong_asset)203 _set_new_uri (GESProject * project, GError * error, GESAsset * wrong_asset)
204 {
205 fail_unless (!g_strcmp0 (ges_asset_get_id (wrong_asset),
206 "file:///test/not/exisiting"));
207
208 return ges_test_file_uri ("audio_video.ogg");
209 }
210
211 static void
_test_project(GESProject * project,GESTimeline * timeline)212 _test_project (GESProject * project, GESTimeline * timeline)
213 {
214 guint a_meta;
215 gchar *media_uri;
216 GESTrack *track;
217 const GList *profiles;
218 GstEncodingContainerProfile *profile;
219 GList *tracks, *tmp, *tmptrackelement, *clips;
220
221 fail_unless (GES_IS_TIMELINE (timeline));
222 assert_equals_int (g_list_length (timeline->layers), 2);
223
224 assert_equals_string (ges_meta_container_get_string (GES_META_CONTAINER
225 (project), "name"), "Example project");
226 clips = ges_layer_get_clips (GES_LAYER (timeline->layers->data));
227 fail_unless (ges_meta_container_get_uint (GES_META_CONTAINER
228 (timeline->layers->data), "a", &a_meta));
229 assert_equals_int (a_meta, 3);
230 assert_equals_int (g_list_length (clips), 1);
231 media_uri = ges_test_file_uri ("audio_video.ogg");
232 assert_equals_string (ges_asset_get_id (ges_extractable_get_asset
233 (GES_EXTRACTABLE (clips->data))), media_uri);
234 g_free (media_uri);
235 g_list_free_full (clips, gst_object_unref);
236
237 /* Check tracks and the objects they contain */
238 tracks = ges_timeline_get_tracks (timeline);
239 assert_equals_int (g_list_length (tracks), 2);
240 for (tmp = tracks; tmp; tmp = tmp->next) {
241 GList *trackelements;
242 track = GES_TRACK (tmp->data);
243
244 trackelements = ges_track_get_elements (track);
245 GST_DEBUG_OBJECT (track, "Testing track");
246 switch (track->type) {
247 case GES_TRACK_TYPE_VIDEO:
248 assert_equals_int (g_list_length (trackelements), 2);
249 for (tmptrackelement = trackelements; tmptrackelement;
250 tmptrackelement = tmptrackelement->next) {
251 GESTrackElement *trackelement =
252 GES_TRACK_ELEMENT (tmptrackelement->data);
253
254 if (GES_IS_BASE_EFFECT (trackelement)) {
255 guint nb_scratch_lines;
256
257 ges_timeline_element_get_child_properties (tmptrackelement->data,
258 "scratch-lines", &nb_scratch_lines, NULL);
259 assert_equals_int (nb_scratch_lines, 12);
260
261 nle_object_check (ges_track_element_get_nleobject (trackelement),
262 0, 1000000000, 0, 1000000000, MIN_NLE_PRIO + TRANSITIONS_HEIGHT,
263 TRUE);
264 } else {
265 nle_object_check (ges_track_element_get_nleobject (trackelement),
266 0, 1000000000, 0, 1000000000,
267 MIN_NLE_PRIO + TRANSITIONS_HEIGHT + 1, TRUE);
268 }
269 }
270 break;
271 case GES_TRACK_TYPE_AUDIO:
272 assert_equals_int (g_list_length (trackelements), 2);
273 break;
274 default:
275 g_assert (1);
276 }
277
278 g_list_free_full (trackelements, gst_object_unref);
279
280 }
281 g_list_free_full (tracks, gst_object_unref);
282
283 /* Now test the encoding profile */
284 profiles = ges_project_list_encoding_profiles (project);
285 assert_equals_int (g_list_length ((GList *) profiles), 1);
286 profile = profiles->data;
287 fail_unless (GST_IS_ENCODING_CONTAINER_PROFILE (profile));
288 profiles = gst_encoding_container_profile_get_profiles (profile);
289 assert_equals_int (g_list_length ((GList *) profiles), 2);
290 }
291
292 static void
_add_properties(GESTimeline * timeline)293 _add_properties (GESTimeline * timeline)
294 {
295 GList *tracks;
296 GList *tmp;
297
298 tracks = ges_timeline_get_tracks (timeline);
299 for (tmp = tracks; tmp; tmp = tmp->next) {
300 GESTrack *track;
301 GList *track_elements;
302 GList *tmp_tck;
303
304 track = GES_TRACK (tmp->data);
305 switch (track->type) {
306 case GES_TRACK_TYPE_VIDEO:
307 track_elements = ges_track_get_elements (track);
308
309 for (tmp_tck = track_elements; tmp_tck; tmp_tck = tmp_tck->next) {
310 GESTrackElement *element = GES_TRACK_ELEMENT (tmp_tck->data);
311
312 /* Adding keyframes */
313 if (GES_IS_EFFECT (element)) {
314 GstControlSource *source;
315 GstControlBinding *tmp_binding, *binding;
316
317 source = gst_interpolation_control_source_new ();
318
319 /* Check binding creation and replacement */
320 binding =
321 ges_track_element_get_control_binding (element,
322 "scratch-lines");
323 fail_unless (binding == NULL);
324 ges_track_element_set_control_source (element,
325 source, "scratch-lines", "direct");
326 tmp_binding =
327 ges_track_element_get_control_binding (element,
328 "scratch-lines");
329 fail_unless (tmp_binding != NULL);
330 ges_track_element_set_control_source (element,
331 source, "scratch-lines", "direct");
332 binding =
333 ges_track_element_get_control_binding (element,
334 "scratch-lines");
335 fail_unless (binding != tmp_binding);
336
337
338 g_object_set (source, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
339 gst_timed_value_control_source_set (GST_TIMED_VALUE_CONTROL_SOURCE
340 (source), 0 * GST_SECOND, 0.);
341 gst_timed_value_control_source_set (GST_TIMED_VALUE_CONTROL_SOURCE
342 (source), 5 * GST_SECOND, 0.);
343 gst_timed_value_control_source_set (GST_TIMED_VALUE_CONTROL_SOURCE
344 (source), 10 * GST_SECOND, 1.);
345 } else if (GES_IS_VIDEO_SOURCE (element)) {
346 /* Adding children properties */
347 gint64 posx = 42;
348 ges_timeline_element_set_child_properties (GES_TIMELINE_ELEMENT
349 (element), "posx", posx, NULL);
350 ges_timeline_element_get_child_properties (GES_TIMELINE_ELEMENT
351 (element), "posx", &posx, NULL);
352 fail_unless_equals_int64 (posx, 42);
353 }
354
355 }
356 g_list_free_full (track_elements, g_object_unref);
357 break;
358 default:
359 break;
360 }
361 }
362
363 g_list_free_full (tracks, g_object_unref);
364 }
365
366 static void
_check_properties(GESTimeline * timeline)367 _check_properties (GESTimeline * timeline)
368 {
369 GList *tracks;
370 GList *tmp;
371
372 tracks = ges_timeline_get_tracks (timeline);
373 for (tmp = tracks; tmp; tmp = tmp->next) {
374 GESTrack *track;
375 GList *track_elements;
376 GList *tmp_tck;
377
378 track = GES_TRACK (tmp->data);
379 switch (track->type) {
380 case GES_TRACK_TYPE_VIDEO:
381 track_elements = ges_track_get_elements (track);
382
383 for (tmp_tck = track_elements; tmp_tck; tmp_tck = tmp_tck->next) {
384 GESTrackElement *element = GES_TRACK_ELEMENT (tmp_tck->data);
385 /* Checking keyframes */
386 if (GES_IS_EFFECT (element)) {
387 GstControlBinding *binding;
388 GstControlSource *source;
389 GList *timed_values;
390 GstTimedValue *value;
391
392 binding =
393 ges_track_element_get_control_binding (element,
394 "scratch-lines");
395 fail_unless (binding != NULL);
396 g_object_get (binding, "control-source", &source, NULL);
397 fail_unless (source != NULL);
398
399 /* Now check keyframe position */
400 timed_values =
401 gst_timed_value_control_source_get_all
402 (GST_TIMED_VALUE_CONTROL_SOURCE (source));
403 value = timed_values->data;
404 fail_unless (value->value == 0.);
405 fail_unless (value->timestamp == 0 * GST_SECOND);
406 timed_values = timed_values->next;
407 value = timed_values->data;
408 fail_unless (value->value == 0.);
409 fail_unless (value->timestamp == 5 * GST_SECOND);
410 timed_values = timed_values->next;
411 value = timed_values->data;
412 fail_unless (value->value == 1.);
413 fail_unless (value->timestamp == 10 * GST_SECOND);
414 }
415 /* Checking children properties */
416 else if (GES_IS_VIDEO_SOURCE (element)) {
417 /* Init 'posx' with a wrong value */
418 gint64 posx = 27;
419 ges_timeline_element_get_child_properties (GES_TIMELINE_ELEMENT
420 (element), "posx", &posx, NULL);
421 fail_unless_equals_int64 (posx, 42);
422 }
423 }
424 g_list_free_full (track_elements, g_object_unref);
425 break;
426 default:
427 break;
428 }
429 }
430
431 g_list_free_full (tracks, g_object_unref);
432 }
433
GST_START_TEST(test_project_add_properties)434 GST_START_TEST (test_project_add_properties)
435 {
436 GESProject *project;
437 GESTimeline *timeline;
438 gchar *uri;
439
440 ges_init ();
441
442 uri = ges_test_file_uri ("test-properties.xges");
443 project = ges_project_new (uri);
444 g_free (uri);
445 mainloop = g_main_loop_new (NULL, FALSE);
446
447 /* Connect the signals */
448 g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop);
449 g_signal_connect (project, "missing-uri", (GCallback) _set_new_uri, NULL);
450
451 /* Now extract a timeline from it */
452 GST_LOG ("Loading project");
453 timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
454
455 g_main_loop_run (mainloop);
456
457 GST_LOG ("Test first loading");
458
459
460 _add_properties (timeline);
461
462 uri = ges_test_get_tmp_uri ("test-properties-save.xges");
463 fail_unless (ges_project_save (project, timeline, uri, NULL, TRUE, NULL));
464 gst_object_unref (timeline);
465 gst_object_unref (project);
466
467 project = ges_project_new (uri);
468 g_free (uri);
469
470 ASSERT_OBJECT_REFCOUNT (project, "Our + cache", 2);
471
472 g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop);
473
474 GST_LOG ("Loading saved project");
475 timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
476 fail_unless (GES_IS_TIMELINE (timeline));
477
478 g_main_loop_run (mainloop);
479
480 _check_properties (timeline);
481
482 gst_object_unref (timeline);
483 gst_object_unref (project);
484
485 g_main_loop_unref (mainloop);
486 g_signal_handlers_disconnect_by_func (project, (GCallback) project_loaded_cb,
487 mainloop);
488 g_signal_handlers_disconnect_by_func (project, (GCallback) asset_added_cb,
489 NULL);
490
491 ges_deinit ();
492 }
493
494 GST_END_TEST;
495
GST_START_TEST(test_project_load_xges)496 GST_START_TEST (test_project_load_xges)
497 {
498 gboolean saved;
499 GESProject *loaded_project, *saved_project;
500 GESTimeline *timeline;
501 GESAsset *formatter_asset;
502 gchar *uri;
503 GList *tmp;
504
505 ges_init ();
506
507 uri = ges_test_file_uri ("test-project.xges");
508 loaded_project = ges_project_new (uri);
509 mainloop = g_main_loop_new (NULL, FALSE);
510 fail_unless (GES_IS_PROJECT (loaded_project));
511
512 /* Connect the signals */
513 g_signal_connect (loaded_project, "asset-added", (GCallback) asset_added_cb,
514 NULL);
515 g_signal_connect (loaded_project, "loaded", (GCallback) project_loaded_cb,
516 mainloop);
517
518 /* Make sure we update the project's dummy URL to some actual URL */
519 g_signal_connect (loaded_project, "missing-uri", (GCallback) _set_new_uri,
520 NULL);
521
522 /* Now extract a timeline from it */
523 GST_LOG ("Loading project");
524 timeline =
525 GES_TIMELINE (ges_asset_extract (GES_ASSET (loaded_project), NULL));
526 fail_unless (GES_IS_TIMELINE (timeline));
527 tmp = ges_project_get_loading_assets (loaded_project);
528 assert_equals_int (g_list_length (tmp), 1);
529 g_list_free_full (tmp, g_object_unref);
530
531 g_main_loop_run (mainloop);
532 GST_LOG ("Test first loading");
533 _test_project (loaded_project, timeline);
534 g_free (uri);
535
536 uri = ges_test_get_tmp_uri ("test-project_TMP.xges");
537 formatter_asset = ges_asset_request (GES_TYPE_FORMATTER, "ges", NULL);
538 saved =
539 ges_project_save (loaded_project, timeline, uri, formatter_asset, TRUE,
540 NULL);
541 fail_unless (saved);
542 gst_object_unref (timeline);
543
544 saved_project = ges_project_new (uri);
545 ASSERT_OBJECT_REFCOUNT (saved_project, "Our + cache", 2);
546 g_signal_connect (saved_project, "asset-added", (GCallback) asset_added_cb,
547 NULL);
548 g_signal_connect (saved_project, "loaded", (GCallback) project_loaded_cb,
549 mainloop);
550
551 GST_LOG ("Loading saved project");
552 timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (saved_project), NULL));
553 fail_unless (GES_IS_TIMELINE (timeline));
554 g_main_loop_run (mainloop);
555 _test_project (saved_project, timeline);
556
557 fail_unless (ges_meta_container_get_string (GES_META_CONTAINER
558 (loaded_project), GES_META_FORMAT_VERSION));
559 fail_unless_equals_string (ges_meta_container_get_string (GES_META_CONTAINER
560 (loaded_project), GES_META_FORMAT_VERSION),
561 ges_meta_container_get_string (GES_META_CONTAINER (loaded_project),
562 GES_META_FORMAT_VERSION));
563 gst_object_unref (timeline);
564 gst_object_unref (saved_project);
565 gst_object_unref (loaded_project);
566 g_free (uri);
567
568 ASSERT_OBJECT_REFCOUNT (saved_project, "Still 1 ref for asset cache", 1);
569
570 g_main_loop_unref (mainloop);
571 g_signal_handlers_disconnect_by_func (saved_project,
572 (GCallback) project_loaded_cb, mainloop);
573 g_signal_handlers_disconnect_by_func (saved_project,
574 (GCallback) asset_added_cb, NULL);
575
576 ges_deinit ();
577 }
578
579 GST_END_TEST;
580
GST_START_TEST(test_project_auto_transition)581 GST_START_TEST (test_project_auto_transition)
582 {
583 GList *layers, *tmp;
584 GESProject *project;
585 GESTimeline *timeline;
586 GESLayer *layer = NULL;
587 GESAsset *formatter_asset;
588 gboolean saved;
589 gchar *tmpuri, *uri;
590
591 ges_init ();
592
593 uri = ges_test_file_uri ("test-auto-transition.xges");
594 project = ges_project_new (uri);
595 mainloop = g_main_loop_new (NULL, FALSE);
596 fail_unless (GES_IS_PROJECT (project));
597
598 /* Connect the signals */
599 g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop);
600 g_signal_connect (project, "missing-uri", (GCallback) _set_new_uri, NULL);
601
602 /* Now extract a timeline from it */
603 GST_LOG ("Loading project");
604 timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
605
606 g_main_loop_run (mainloop);
607
608 /* Check timeline and layers auto-transition, must be FALSE */
609 fail_if (ges_timeline_get_auto_transition (timeline));
610 layers = ges_timeline_get_layers (timeline);
611 for (tmp = layers; tmp; tmp = tmp->next) {
612 layer = tmp->data;
613 fail_if (ges_layer_get_auto_transition (layer));
614 }
615
616 g_list_free_full (layers, gst_object_unref);
617 g_free (uri);
618
619 /* Set timeline and layers auto-transition to TRUE */
620 ges_timeline_set_auto_transition (timeline, TRUE);
621
622 tmpuri = ges_test_get_tmp_uri ("test-auto-transition-save.xges");
623 formatter_asset = ges_asset_request (GES_TYPE_FORMATTER, "ges", NULL);
624 saved =
625 ges_project_save (project, timeline, tmpuri, formatter_asset, TRUE, NULL);
626 fail_unless (saved);
627
628 gst_object_unref (timeline);
629 gst_object_unref (project);
630
631 project = ges_project_new (tmpuri);
632
633 ASSERT_OBJECT_REFCOUNT (project, "Our + cache", 2);
634
635 g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop);
636
637 GST_LOG ("Loading saved project");
638 timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
639 fail_unless (GES_IS_TIMELINE (timeline));
640
641 g_main_loop_run (mainloop);
642
643 /* Check timeline and layers auto-transition, must be TRUE */
644 fail_unless (ges_timeline_get_auto_transition (timeline));
645 layers = ges_timeline_get_layers (timeline);
646 for (tmp = layers; tmp; tmp = tmp->next) {
647 layer = tmp->data;
648 fail_unless (ges_layer_get_auto_transition (layer));
649 }
650
651 g_list_free_full (layers, gst_object_unref);
652 gst_object_unref (timeline);
653 gst_object_unref (project);
654 g_free (tmpuri);
655
656 g_main_loop_unref (mainloop);
657 g_signal_handlers_disconnect_by_func (project, (GCallback) project_loaded_cb,
658 mainloop);
659 g_signal_handlers_disconnect_by_func (project, (GCallback) asset_added_cb,
660 NULL);
661
662 ges_deinit ();
663 }
664
665 GST_END_TEST;
666
667 /* FIXME This test does not pass for some bad reason */
668 #if 0
669 static void
670 project_loaded_now_play_cb (GESProject * project, GESTimeline * timeline)
671 {
672 GstBus *bus;
673 GstMessage *message;
674 gboolean carry_on = TRUE;
675
676 GESPipeline *pipeline = ges_pipeline_new ();
677
678 fail_unless (ges_pipeline_set_timeline (pipeline, timeline));
679
680 bus = gst_element_get_bus (GST_ELEMENT (pipeline));
681 fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
682 GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE);
683
684 GST_DEBUG ("Let's poll the bus");
685
686 while (carry_on) {
687 message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 10);
688 if (message) {
689 GST_ERROR ("GOT MESSAGE: %" GST_PTR_FORMAT, message);
690 switch (GST_MESSAGE_TYPE (message)) {
691 case GST_MESSAGE_EOS:
692 /* we should check if we really finished here */
693 GST_WARNING ("Got an EOS, we did not even start!");
694 carry_on = FALSE;
695 fail_if (TRUE);
696 break;
697 case GST_MESSAGE_SEGMENT_START:
698 case GST_MESSAGE_SEGMENT_DONE:
699 /* We shouldn't see any segement messages, since we didn't do a segment seek */
700 GST_WARNING ("Saw a Segment start/stop");
701 fail_if (TRUE);
702 break;
703 case GST_MESSAGE_ERROR:
704 fail_error_message (message);
705 break;
706 case GST_MESSAGE_ASYNC_DONE:
707 GST_DEBUG ("prerolling done");
708 carry_on = FALSE;
709 break;
710 default:
711 break;
712 }
713 gst_mini_object_unref (GST_MINI_OBJECT (message));
714 }
715 }
716
717 fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
718 GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
719 gst_object_unref (pipeline);
720 g_main_loop_quit (mainloop);
721 }
722
723
724 GST_START_TEST (test_load_xges_and_play)
725 {
726 GESProject *project;
727 GESTimeline *timeline;
728 gchar *uri = ges_test_file_uri ("test-project_TMP.xges");
729
730 project = ges_project_new (uri);
731 fail_unless (GES_IS_PROJECT (project));
732
733 mainloop = g_main_loop_new (NULL, FALSE);
734 /* Connect the signals */
735 g_signal_connect (project, "loaded", (GCallback) project_loaded_now_play_cb,
736 NULL);
737
738 /* Now extract a timeline from it */
739 timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
740 fail_unless (GES_IS_TIMELINE (timeline));
741
742 g_main_loop_run (mainloop);
743
744 g_free (uri);
745 gst_object_unref (project);
746 gst_object_unref (timeline);
747 g_main_loop_unref (mainloop);
748 }
749
750 GST_END_TEST;
751 #endif
752
753 static Suite *
ges_suite(void)754 ges_suite (void)
755 {
756 Suite *s = suite_create ("ges-project");
757 TCase *tc_chain = tcase_create ("project");
758
759 suite_add_tcase (s, tc_chain);
760
761 tcase_add_test (tc_chain, test_project_simple);
762 tcase_add_test (tc_chain, test_project_add_assets);
763 tcase_add_test (tc_chain, test_project_load_xges);
764 tcase_add_test (tc_chain, test_project_add_properties);
765 tcase_add_test (tc_chain, test_project_auto_transition);
766 /*tcase_add_test (tc_chain, test_load_xges_and_play); */
767 tcase_add_test (tc_chain, test_project_unexistant_effect);
768
769 return s;
770 }
771
772 GST_CHECK_MAIN (ges);
773