gstreamer/tests/check/ges/project.c
Thibault Saunier 241e809a81 ges: Enhance xges format versioning
Summary:
Handle the fact that some new features can be added and that means
generated files will not be fully understandable by older versions of
the formatter.

Make sure that we set the format version to 0.2 when we serialize the
GstEncodingProfile.enabled property.

Add some tests around that.

+ Fix a minor bug in the test-utils
+ Add a meta on the projects to tell in what format version a project
  has been serialized/parsed back

API:
  GES_META_FORMAT_VERSION

Depends on D178

Reviewers: Mathieu_Du

Differential Revision: http://phabricator.freedesktop.org/D184
2015-05-18 21:27:48 +02:00

749 lines
24 KiB
C

/* GStreamer Editing Services
*
* Copyright (C) <2012> Thibault Saunier <thibault.saunier@collabora.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "test-utils.h"
#include <ges/ges.h>
#include <gst/check/gstcheck.h>
#include <gst/controller/gstdirectcontrolbinding.h>
#include <gst/controller/gstinterpolationcontrolsource.h>
GMainLoop *mainloop;
static void
project_loaded_cb (GESProject * project, GESTimeline * timeline,
GMainLoop * mainloop)
{
g_main_loop_quit (mainloop);
}
GST_START_TEST (test_project_simple)
{
gchar *id;
GESProject *project;
GESTimeline *timeline;
ges_init ();
mainloop = g_main_loop_new (NULL, FALSE);
project = GES_PROJECT (ges_asset_request (GES_TYPE_TIMELINE, NULL, NULL));
fail_unless (GES_IS_PROJECT (project));
assert_equals_string (ges_asset_get_id (GES_ASSET (project)), "project-0");
g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop);
timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
g_main_loop_run (mainloop);
fail_unless (GES_IS_TIMELINE (timeline));
id = ges_extractable_get_id (GES_EXTRACTABLE (timeline));
assert_equals_string (id, "project-0");
ASSERT_OBJECT_REFCOUNT (timeline, "We own the only ref", 1);
g_free (id);
gst_object_unref (project);
gst_object_unref (timeline);
g_main_loop_unref (mainloop);
g_signal_handlers_disconnect_by_func (project, (GCallback) project_loaded_cb,
mainloop);
}
GST_END_TEST;
static void
asset_removed_add_cb (GESProject * project, GESAsset * asset, gboolean * called)
{
*called = TRUE;
}
static void
asset_created_cb (GObject * source, GAsyncResult * res, GESAsset ** asset)
{
GError *error = NULL;
*asset = ges_asset_request_finish (res, &error);
fail_unless (error == NULL);
g_main_loop_quit (mainloop);
}
GST_START_TEST (test_project_add_assets)
{
GESProject *project;
GESAsset *asset;
gboolean added_cb_called = FALSE;
gboolean removed_cb_called = FALSE;
ges_init ();
mainloop = g_main_loop_new (NULL, FALSE);
project = GES_PROJECT (ges_asset_request (GES_TYPE_TIMELINE, NULL, NULL));
fail_unless (GES_IS_PROJECT (project));
g_signal_connect (project, "asset-added",
(GCallback) asset_removed_add_cb, &added_cb_called);
g_signal_connect (project, "asset-removed",
(GCallback) asset_removed_add_cb, &removed_cb_called);
ges_asset_request_async (GES_TYPE_TEST_CLIP, NULL, NULL,
(GAsyncReadyCallback) asset_created_cb, &asset);
g_main_loop_run (mainloop);
g_main_loop_unref (mainloop);
fail_unless (GES_IS_ASSET (asset));
fail_unless (ges_project_add_asset (project, asset));
fail_unless (added_cb_called);
ASSERT_OBJECT_REFCOUNT (project, "The project", 2);
ASSERT_OBJECT_REFCOUNT (asset, "The asset (1 for project and one for "
"us + 1 cache)", 3);
fail_unless (ges_project_remove_asset (project, asset));
fail_unless (removed_cb_called);
g_signal_handlers_disconnect_by_func (project,
(GCallback) asset_removed_add_cb, &added_cb_called);
g_signal_handlers_disconnect_by_func (project,
(GCallback) asset_removed_add_cb, &removed_cb_called);
gst_object_unref (asset);
gst_object_unref (project);
ASSERT_OBJECT_REFCOUNT (asset, "The asset (1 ref in cache)", 1);
ASSERT_OBJECT_REFCOUNT (project, "The project (1 ref in cache)", 1);
}
GST_END_TEST;
static void
error_loading_asset_cb (GESProject * project, GError * error, gchar * id,
GType extractable_type, GMainLoop * mainloop)
{
fail_unless (g_error_matches (error, GST_PARSE_ERROR,
GST_PARSE_ERROR_NO_SUCH_ELEMENT));
g_main_loop_quit (mainloop);
}
GST_START_TEST (test_project_unexistant_effect)
{
GESProject *project;
gboolean added_cb_called = FALSE;
gboolean removed_cb_called = FALSE;
ges_init ();
project = GES_PROJECT (ges_asset_request (GES_TYPE_TIMELINE, NULL, NULL));
fail_unless (GES_IS_PROJECT (project));
mainloop = g_main_loop_new (NULL, FALSE);
g_signal_connect (project, "asset-added",
(GCallback) asset_removed_add_cb, &added_cb_called);
g_signal_connect (project, "asset-removed",
(GCallback) asset_removed_add_cb, &removed_cb_called);
g_signal_connect (project, "error-loading-asset",
(GCallback) error_loading_asset_cb, mainloop);
fail_unless (ges_project_create_asset (project, "nowaythiselementexists",
GES_TYPE_EFFECT));
g_main_loop_run (mainloop);
/* And.... try again! */
fail_if (ges_project_create_asset (project, "nowaythiselementexists",
GES_TYPE_EFFECT));
fail_if (added_cb_called);
fail_if (removed_cb_called);
ASSERT_OBJECT_REFCOUNT (project, "The project", 2);
gst_object_unref (project);
g_main_loop_unref (mainloop);
ASSERT_OBJECT_REFCOUNT (project, "The project (1 ref in cache)", 1);
}
GST_END_TEST;
static void
asset_added_cb (GESProject * project, GESAsset * asset)
{
gchar *uri = ges_test_file_uri ("audio_video.ogg");
GstDiscovererInfo *info;
if (ges_asset_get_extractable_type (asset) == GES_TYPE_EFFECT) {
assert_equals_string (ges_asset_get_id (asset), "agingtv");
} else {
info = ges_uri_clip_asset_get_info (GES_URI_CLIP_ASSET (asset));
fail_unless (GST_IS_DISCOVERER_INFO (info));
assert_equals_string (ges_asset_get_id (asset), uri);
}
g_free (uri);
}
static gchar *
_set_new_uri (GESProject * project, GError * error, GESAsset * wrong_asset)
{
fail_unless (!g_strcmp0 (ges_asset_get_id (wrong_asset),
"file:///test/not/exisiting"));
return ges_test_file_uri ("audio_video.ogg");
}
static void
_test_project (GESProject * project, GESTimeline * timeline)
{
guint a_meta;
gchar *media_uri;
GESTrack *track;
const GList *profiles;
GstEncodingContainerProfile *profile;
GList *tracks, *tmp, *tmptrackelement, *clips;
fail_unless (GES_IS_TIMELINE (timeline));
assert_equals_int (g_list_length (timeline->layers), 2);
assert_equals_string (ges_meta_container_get_string (GES_META_CONTAINER
(project), "name"), "Example project");
clips = ges_layer_get_clips (GES_LAYER (timeline->layers->data));
fail_unless (ges_meta_container_get_uint (GES_META_CONTAINER
(timeline->layers->data), "a", &a_meta));
assert_equals_int (a_meta, 3);
assert_equals_int (g_list_length (clips), 1);
media_uri = ges_test_file_uri ("audio_video.ogg");
assert_equals_string (ges_asset_get_id (ges_extractable_get_asset
(GES_EXTRACTABLE (clips->data))), media_uri);
g_free (media_uri);
g_list_free_full (clips, gst_object_unref);
/* Check tracks and the objects they contain */
tracks = ges_timeline_get_tracks (timeline);
assert_equals_int (g_list_length (tracks), 2);
for (tmp = tracks; tmp; tmp = tmp->next) {
GList *trackelements;
track = GES_TRACK (tmp->data);
trackelements = ges_track_get_elements (track);
GST_DEBUG_OBJECT (track, "Testing track");
switch (track->type) {
case GES_TRACK_TYPE_VIDEO:
assert_equals_int (g_list_length (trackelements), 2);
for (tmptrackelement = trackelements; tmptrackelement;
tmptrackelement = tmptrackelement->next) {
GESTrackElement *trackelement =
GES_TRACK_ELEMENT (tmptrackelement->data);
if (GES_IS_BASE_EFFECT (trackelement)) {
guint nb_scratch_lines;
ges_timeline_element_get_child_properties (tmptrackelement->data,
"scratch-lines", &nb_scratch_lines, NULL);
assert_equals_int (nb_scratch_lines, 12);
nle_object_check (ges_track_element_get_nleobject (trackelement),
0, 1000000000, 0, 1000000000, MIN_NLE_PRIO, TRUE);
} else {
nle_object_check (ges_track_element_get_nleobject (trackelement),
0, 1000000000, 0, 1000000000, MIN_NLE_PRIO + 1, TRUE);
}
}
break;
case GES_TRACK_TYPE_AUDIO:
assert_equals_int (g_list_length (trackelements), 2);
break;
default:
g_assert (1);
}
g_list_free_full (trackelements, gst_object_unref);
}
g_list_free_full (tracks, gst_object_unref);
/* Now test the encoding profile */
profiles = ges_project_list_encoding_profiles (project);
assert_equals_int (g_list_length ((GList *) profiles), 1);
profile = profiles->data;
fail_unless (GST_IS_ENCODING_CONTAINER_PROFILE (profile));
profiles = gst_encoding_container_profile_get_profiles (profile);
assert_equals_int (g_list_length ((GList *) profiles), 2);
}
static void
_add_properties (GESTimeline * timeline)
{
GList *tracks;
GList *tmp;
tracks = ges_timeline_get_tracks (timeline);
for (tmp = tracks; tmp; tmp = tmp->next) {
GESTrack *track;
GList *track_elements;
GList *tmp_tck;
track = GES_TRACK (tmp->data);
switch (track->type) {
case GES_TRACK_TYPE_VIDEO:
track_elements = ges_track_get_elements (track);
for (tmp_tck = track_elements; tmp_tck; tmp_tck = tmp_tck->next) {
GESTrackElement *element = GES_TRACK_ELEMENT (tmp_tck->data);
/* Adding keyframes */
if (GES_IS_EFFECT (element)) {
GstControlSource *source;
GstControlBinding *tmp_binding, *binding;
source = gst_interpolation_control_source_new ();
/* Check binding creation and replacement */
binding =
ges_track_element_get_control_binding (element,
"scratch-lines");
fail_unless (binding == NULL);
ges_track_element_set_control_source (element,
source, "scratch-lines", "direct");
tmp_binding =
ges_track_element_get_control_binding (element,
"scratch-lines");
fail_unless (tmp_binding != NULL);
ges_track_element_set_control_source (element,
source, "scratch-lines", "direct");
binding =
ges_track_element_get_control_binding (element,
"scratch-lines");
fail_unless (binding != tmp_binding);
g_object_set (source, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
gst_timed_value_control_source_set (GST_TIMED_VALUE_CONTROL_SOURCE
(source), 0 * GST_SECOND, 0.);
gst_timed_value_control_source_set (GST_TIMED_VALUE_CONTROL_SOURCE
(source), 5 * GST_SECOND, 0.);
gst_timed_value_control_source_set (GST_TIMED_VALUE_CONTROL_SOURCE
(source), 10 * GST_SECOND, 1.);
}
/* Adding children properties */
else if (GES_IS_VIDEO_SOURCE (element)) {
gint64 posx = 42;
ges_timeline_element_set_child_properties (GES_TIMELINE_ELEMENT
(element), "posx", posx, NULL);
ges_timeline_element_get_child_properties (GES_TIMELINE_ELEMENT
(element), "posx", &posx, NULL);
fail_unless_equals_int64 (posx, 42);
}
}
break;
default:
break;
}
}
}
static void
_check_properties (GESTimeline * timeline)
{
GList *tracks;
GList *tmp;
tracks = ges_timeline_get_tracks (timeline);
for (tmp = tracks; tmp; tmp = tmp->next) {
GESTrack *track;
GList *track_elements;
GList *tmp_tck;
track = GES_TRACK (tmp->data);
switch (track->type) {
case GES_TRACK_TYPE_VIDEO:
track_elements = ges_track_get_elements (track);
for (tmp_tck = track_elements; tmp_tck; tmp_tck = tmp_tck->next) {
GESTrackElement *element = GES_TRACK_ELEMENT (tmp_tck->data);
/* Checking keyframes */
if (GES_IS_EFFECT (element)) {
GstControlBinding *binding;
GstControlSource *source;
GList *timed_values;
GstTimedValue *value;
binding =
ges_track_element_get_control_binding (element,
"scratch-lines");
fail_unless (binding != NULL);
g_object_get (binding, "control-source", &source, NULL);
fail_unless (source != NULL);
/* Now check keyframe position */
timed_values =
gst_timed_value_control_source_get_all
(GST_TIMED_VALUE_CONTROL_SOURCE (source));
value = timed_values->data;
fail_unless (value->value == 0.);
fail_unless (value->timestamp == 0 * GST_SECOND);
timed_values = timed_values->next;
value = timed_values->data;
fail_unless (value->value == 0.);
fail_unless (value->timestamp == 5 * GST_SECOND);
timed_values = timed_values->next;
value = timed_values->data;
fail_unless (value->value == 1.);
fail_unless (value->timestamp == 10 * GST_SECOND);
}
/* Checking children properties */
else if (GES_IS_VIDEO_SOURCE (element)) {
/* Init 'posx' with a wrong value */
gint64 posx = 27;
ges_timeline_element_get_child_properties (GES_TIMELINE_ELEMENT
(element), "posx", &posx, NULL);
fail_unless_equals_int64 (posx, 42);
}
}
break;
default:
break;
}
}
}
GST_START_TEST (test_project_add_properties)
{
GESProject *project;
GESTimeline *timeline;
GESAsset *formatter_asset;
gboolean saved;
gchar *uri = ges_test_file_uri ("test-properties.xges");
project = ges_project_new (uri);
mainloop = g_main_loop_new (NULL, FALSE);
/* Connect the signals */
g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop);
g_signal_connect (project, "missing-uri", (GCallback) _set_new_uri, NULL);
/* Now extract a timeline from it */
GST_LOG ("Loading project");
timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
g_main_loop_run (mainloop);
GST_LOG ("Test first loading");
g_free (uri);
_add_properties (timeline);
uri = ges_test_get_tmp_uri ("test-properties-save.xges");
formatter_asset = ges_asset_request (GES_TYPE_FORMATTER, "ges", NULL);
saved =
ges_project_save (project, timeline, uri, formatter_asset, TRUE, NULL);
fail_unless (saved);
gst_object_unref (timeline);
gst_object_unref (project);
project = ges_project_new (uri);
ASSERT_OBJECT_REFCOUNT (project, "Our + cache", 2);
g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop);
GST_LOG ("Loading saved project");
timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
fail_unless (GES_IS_TIMELINE (timeline));
g_main_loop_run (mainloop);
_check_properties (timeline);
gst_object_unref (timeline);
gst_object_unref (project);
g_free (uri);
g_main_loop_unref (mainloop);
g_signal_handlers_disconnect_by_func (project, (GCallback) project_loaded_cb,
mainloop);
g_signal_handlers_disconnect_by_func (project, (GCallback) asset_added_cb,
NULL);
}
GST_END_TEST;
GST_START_TEST (test_project_load_xges)
{
gboolean saved;
GESProject *loaded_project, *saved_project;
GESTimeline *timeline;
GESAsset *formatter_asset;
gchar *uri = ges_test_file_uri ("test-project.xges");
loaded_project = ges_project_new (uri);
mainloop = g_main_loop_new (NULL, FALSE);
fail_unless (GES_IS_PROJECT (loaded_project));
/* Connect the signals */
g_signal_connect (loaded_project, "asset-added", (GCallback) asset_added_cb,
NULL);
g_signal_connect (loaded_project, "loaded", (GCallback) project_loaded_cb,
mainloop);
/* Make sure we update the project's dummy URL to some actual URL */
g_signal_connect (loaded_project, "missing-uri", (GCallback) _set_new_uri,
NULL);
/* Now extract a timeline from it */
GST_LOG ("Loading project");
timeline =
GES_TIMELINE (ges_asset_extract (GES_ASSET (loaded_project), NULL));
fail_unless (GES_IS_TIMELINE (timeline));
assert_equals_int (g_list_length (ges_project_get_loading_assets
(loaded_project)), 1);
g_main_loop_run (mainloop);
GST_LOG ("Test first loading");
_test_project (loaded_project, timeline);
g_free (uri);
uri = ges_test_get_tmp_uri ("test-project_TMP.xges");
formatter_asset = ges_asset_request (GES_TYPE_FORMATTER, "ges", NULL);
saved =
ges_project_save (loaded_project, timeline, uri, formatter_asset, TRUE,
NULL);
fail_unless (saved);
gst_object_unref (timeline);
saved_project = ges_project_new (uri);
ASSERT_OBJECT_REFCOUNT (saved_project, "Our + cache", 2);
g_signal_connect (saved_project, "asset-added", (GCallback) asset_added_cb,
NULL);
g_signal_connect (saved_project, "loaded", (GCallback) project_loaded_cb,
mainloop);
GST_LOG ("Loading saved project");
timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (saved_project), NULL));
fail_unless (GES_IS_TIMELINE (timeline));
g_main_loop_run (mainloop);
_test_project (saved_project, timeline);
fail_unless (ges_meta_container_get_string (GES_META_CONTAINER
(loaded_project), GES_META_FORMAT_VERSION));
fail_unless_equals_string (ges_meta_container_get_string (GES_META_CONTAINER
(loaded_project), GES_META_FORMAT_VERSION),
ges_meta_container_get_string (GES_META_CONTAINER (loaded_project),
GES_META_FORMAT_VERSION));
gst_object_unref (timeline);
gst_object_unref (saved_project);
gst_object_unref (loaded_project);
g_free (uri);
ASSERT_OBJECT_REFCOUNT (saved_project, "Still 1 ref for asset cache", 1);
g_main_loop_unref (mainloop);
g_signal_handlers_disconnect_by_func (saved_project,
(GCallback) project_loaded_cb, mainloop);
g_signal_handlers_disconnect_by_func (saved_project,
(GCallback) asset_added_cb, NULL);
}
GST_END_TEST;
GST_START_TEST (test_project_auto_transition)
{
GList *layers;
GESProject *project;
GESTimeline *timeline;
GESLayer *layer = NULL;
GESAsset *formatter_asset;
gboolean saved;
gchar *tmpuri, *uri = ges_test_file_uri ("test-auto-transition.xges");
project = ges_project_new (uri);
mainloop = g_main_loop_new (NULL, FALSE);
fail_unless (GES_IS_PROJECT (project));
/* Connect the signals */
g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop);
g_signal_connect (project, "missing-uri", (GCallback) _set_new_uri, NULL);
/* Now extract a timeline from it */
GST_LOG ("Loading project");
timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
g_main_loop_run (mainloop);
/* Check timeline and layers auto-transition, must be FALSE */
fail_if (ges_timeline_get_auto_transition (timeline));
layers = ges_timeline_get_layers (timeline);
for (; layers; layers = layers->next) {
layer = layers->data;
fail_if (ges_layer_get_auto_transition (layer));
}
g_list_free_full (layers, gst_object_unref);
g_free (uri);
/* Set timeline and layers auto-transition to TRUE */
ges_timeline_set_auto_transition (timeline, TRUE);
tmpuri = ges_test_get_tmp_uri ("test-auto-transition-save.xges");
formatter_asset = ges_asset_request (GES_TYPE_FORMATTER, "ges", NULL);
saved =
ges_project_save (project, timeline, tmpuri, formatter_asset, TRUE, NULL);
fail_unless (saved);
gst_object_unref (timeline);
gst_object_unref (project);
project = ges_project_new (tmpuri);
ASSERT_OBJECT_REFCOUNT (project, "Our + cache", 2);
g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, mainloop);
GST_LOG ("Loading saved project");
timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
fail_unless (GES_IS_TIMELINE (timeline));
g_main_loop_run (mainloop);
/* Check timeline and layers auto-transition, must be TRUE */
fail_unless (ges_timeline_get_auto_transition (timeline));
layers = ges_timeline_get_layers (timeline);
for (; layers; layers = layers->next) {
layer = layers->data;
fail_unless (ges_layer_get_auto_transition (layer));
}
g_list_free_full (layers, gst_object_unref);
gst_object_unref (timeline);
gst_object_unref (project);
g_free (tmpuri);
g_main_loop_unref (mainloop);
g_signal_handlers_disconnect_by_func (project, (GCallback) project_loaded_cb,
mainloop);
g_signal_handlers_disconnect_by_func (project, (GCallback) asset_added_cb,
NULL);
}
GST_END_TEST;
/* FIXME This test does not pass for some bad reason */
#if 0
static void
project_loaded_now_play_cb (GESProject * project, GESTimeline * timeline)
{
GstBus *bus;
GstMessage *message;
gboolean carry_on = TRUE;
GESPipeline *pipeline = ges_pipeline_new ();
fail_unless (ges_pipeline_set_timeline (pipeline, timeline));
bus = gst_element_get_bus (GST_ELEMENT (pipeline));
fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE);
GST_DEBUG ("Let's poll the bus");
while (carry_on) {
message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 10);
if (message) {
GST_ERROR ("GOT MESSAGE: %" GST_PTR_FORMAT, message);
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_EOS:
/* we should check if we really finished here */
GST_WARNING ("Got an EOS, we did not even start!");
carry_on = FALSE;
fail_if (TRUE);
break;
case GST_MESSAGE_SEGMENT_START:
case GST_MESSAGE_SEGMENT_DONE:
/* We shouldn't see any segement messages, since we didn't do a segment seek */
GST_WARNING ("Saw a Segment start/stop");
fail_if (TRUE);
break;
case GST_MESSAGE_ERROR:
fail_error_message (message);
break;
case GST_MESSAGE_ASYNC_DONE:
GST_DEBUG ("prerolling done");
carry_on = FALSE;
break;
default:
break;
}
gst_mini_object_unref (GST_MINI_OBJECT (message));
}
}
fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
GST_STATE_READY) == GST_STATE_CHANGE_FAILURE);
gst_object_unref (pipeline);
g_main_loop_quit (mainloop);
}
GST_START_TEST (test_load_xges_and_play)
{
GESProject *project;
GESTimeline *timeline;
gchar *uri = ges_test_file_uri ("test-project_TMP.xges");
project = ges_project_new (uri);
fail_unless (GES_IS_PROJECT (project));
mainloop = g_main_loop_new (NULL, FALSE);
/* Connect the signals */
g_signal_connect (project, "loaded", (GCallback) project_loaded_now_play_cb,
NULL);
/* Now extract a timeline from it */
timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
fail_unless (GES_IS_TIMELINE (timeline));
g_main_loop_run (mainloop);
g_free (uri);
gst_object_unref (project);
gst_object_unref (timeline);
g_main_loop_unref (mainloop);
}
GST_END_TEST;
#endif
static Suite *
ges_suite (void)
{
Suite *s = suite_create ("ges-project");
TCase *tc_chain = tcase_create ("project");
suite_add_tcase (s, tc_chain);
ges_init ();
tcase_add_test (tc_chain, test_project_simple);
tcase_add_test (tc_chain, test_project_add_assets);
tcase_add_test (tc_chain, test_project_load_xges);
tcase_add_test (tc_chain, test_project_add_properties);
tcase_add_test (tc_chain, test_project_auto_transition);
/*tcase_add_test (tc_chain, test_load_xges_and_play); */
tcase_add_test (tc_chain, test_project_unexistant_effect);
return s;
}
GST_CHECK_MAIN (ges);