mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
tests: Add GESProject tests
This commit is contained in:
parent
774e14fff0
commit
2cd77406e1
4 changed files with 471 additions and 52 deletions
|
@ -39,7 +39,8 @@ check_PROGRAMS = \
|
|||
ges/titles\
|
||||
ges/transition \
|
||||
ges/overlays\
|
||||
ges/text_properties
|
||||
ges/text_properties\
|
||||
ges/project
|
||||
|
||||
noinst_LTLIBRARIES=$(testutils_noisnt_libraries)
|
||||
noinst_HEADERS=$(testutils_noinst_headers)
|
||||
|
@ -49,4 +50,7 @@ TESTS = $(check_PROGRAMS)
|
|||
AM_CFLAGS = $(common_cflags) -UG_DISABLE_ASSERT -UG_DISABLE_CAST_CHECKS
|
||||
LDADD = $(common_ldadd) libtestutils.la
|
||||
|
||||
EXTRA_DIST = #gst-plugins-bad.supp
|
||||
EXTRA_DIST = \
|
||||
ges/test-project.xges \
|
||||
ges/audio_only.ogg \
|
||||
ges/audio_video.ogg
|
||||
|
|
437
tests/check/ges/project.c
Normal file
437
tests/check/ges/project.c
Normal file
|
@ -0,0 +1,437 @@
|
|||
/* 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>
|
||||
|
||||
GST_START_TEST (test_project_simple)
|
||||
{
|
||||
gchar *id;
|
||||
GESProject *project;
|
||||
GESTimeline *timeline;
|
||||
|
||||
ges_init ();
|
||||
|
||||
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");
|
||||
|
||||
timeline = GES_TIMELINE (ges_asset_extract (GES_ASSET (project), NULL));
|
||||
fail_unless (GES_IS_TIMELINE (timeline));
|
||||
id = ges_extractable_get_id (GES_EXTRACTABLE (timeline));
|
||||
assert_equals_string (id, "project-0");
|
||||
|
||||
g_free (id);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static void
|
||||
asset_removed_add_cb (GESProject * project, GESAsset * asset, gboolean * called)
|
||||
{
|
||||
*called = TRUE;
|
||||
}
|
||||
|
||||
GST_START_TEST (test_project_add_assets)
|
||||
{
|
||||
GESProject *project;
|
||||
GESAsset *asset;
|
||||
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));
|
||||
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);
|
||||
|
||||
asset = ges_asset_request (GES_TYPE_TIMELINE_TEST_SOURCE, NULL, NULL);
|
||||
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);
|
||||
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;
|
||||
GMainLoop *mainloop;
|
||||
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));
|
||||
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_TRACK_PARSE_LAUNCH_EFFECT));
|
||||
g_main_loop_run (mainloop);
|
||||
|
||||
/* And.... try again! */
|
||||
fail_unless (ges_project_create_asset (project, "nowaythiselementexists",
|
||||
GES_TYPE_TRACK_PARSE_LAUNCH_EFFECT));
|
||||
g_main_loop_run (mainloop);
|
||||
|
||||
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 GMainLoop *mainloop;
|
||||
|
||||
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_TRACK_PARSE_LAUNCH_EFFECT) {
|
||||
assert_equals_string (ges_asset_get_id (asset), "agingtv");
|
||||
} else {
|
||||
info = ges_asset_filesource_get_info (GES_ASSET_FILESOURCE (asset));
|
||||
fail_unless (GST_IS_DISCOVERER_INFO (info));
|
||||
assert_equals_string (ges_asset_get_id (asset), uri);
|
||||
}
|
||||
|
||||
g_free (uri);
|
||||
}
|
||||
|
||||
static void
|
||||
project_loaded_cb (GESProject * project, GESTimeline * timeline)
|
||||
{
|
||||
g_main_loop_quit (mainloop);
|
||||
}
|
||||
|
||||
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, *tmptckobj, *tlobjs;
|
||||
|
||||
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");
|
||||
tlobjs =
|
||||
ges_timeline_layer_get_objects (GES_TIMELINE_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 (tlobjs), 1);
|
||||
media_uri = ges_test_file_uri ("audio_video.ogg");
|
||||
assert_equals_string (ges_asset_get_id (ges_extractable_get_asset
|
||||
(GES_EXTRACTABLE (tlobjs->data))), media_uri);
|
||||
g_free (media_uri);
|
||||
|
||||
/* 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 *trackobjs;
|
||||
track = GES_TRACK (tmp->data);
|
||||
|
||||
trackobjs = ges_track_get_objects (track);
|
||||
switch (track->type) {
|
||||
case GES_TRACK_TYPE_VIDEO:
|
||||
GST_DEBUG_OBJECT (track, "Testing track");
|
||||
assert_equals_int (g_list_length (trackobjs), 2);
|
||||
for (tmptckobj = trackobjs; tmptckobj; tmptckobj = tmptckobj->next) {
|
||||
GESTrackObject *tckobj = GES_TRACK_OBJECT (tmptckobj->data);
|
||||
|
||||
if (GES_IS_TRACK_EFFECT (tckobj)) {
|
||||
guint nb_scratch_lines;
|
||||
|
||||
ges_track_object_get_child_properties (tckobj, "scratch-lines",
|
||||
&nb_scratch_lines, NULL);
|
||||
assert_equals_int (nb_scratch_lines, 12);
|
||||
|
||||
gnl_object_check (ges_track_object_get_gnlobject (tckobj),
|
||||
0, 1000000000, 0, 1000000000, 0, TRUE);
|
||||
} else {
|
||||
gnl_object_check (ges_track_object_get_gnlobject (tckobj),
|
||||
0, 1000000000, 0, 1000000000, 1, TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GES_TRACK_TYPE_AUDIO:
|
||||
assert_equals_int (g_list_length (trackobjs), 2);
|
||||
break;
|
||||
default:
|
||||
g_assert (1);
|
||||
}
|
||||
|
||||
g_list_free_full (trackobjs, 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);
|
||||
}
|
||||
|
||||
GST_START_TEST (test_project_load_xges)
|
||||
{
|
||||
gboolean saved;
|
||||
GESProject *project;
|
||||
GESTimeline *timeline;
|
||||
GESAsset *formatter_asset;
|
||||
gchar *tmpuri, *uri = ges_test_file_uri ("test-project.xges");
|
||||
|
||||
project = ges_project_new (uri);
|
||||
fail_unless (GES_IS_PROJECT (project));
|
||||
|
||||
/* Connect the signals */
|
||||
g_signal_connect (project, "asset-added", (GCallback) asset_added_cb, NULL);
|
||||
g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, NULL);
|
||||
|
||||
/* Make sure we update the project's dummy URL to some actual URL */
|
||||
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));
|
||||
fail_unless (GES_IS_TIMELINE (timeline));
|
||||
|
||||
mainloop = g_main_loop_new (NULL, FALSE);
|
||||
g_main_loop_run (mainloop);
|
||||
GST_LOG ("Test first loading");
|
||||
_test_project (project, timeline);
|
||||
g_free (uri);
|
||||
|
||||
tmpuri = g_build_filename (g_get_tmp_dir (), "test-project_TMP.xges", NULL);
|
||||
uri = gst_filename_to_uri (tmpuri, NULL);
|
||||
g_free (tmpuri);
|
||||
|
||||
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, "asset-added", (GCallback) asset_added_cb, NULL);
|
||||
g_signal_connect (project, "loaded", (GCallback) project_loaded_cb, NULL);
|
||||
|
||||
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);
|
||||
_test_project (project, timeline);
|
||||
gst_object_unref (timeline);
|
||||
gst_object_unref (project);
|
||||
g_free (uri);
|
||||
|
||||
ASSERT_OBJECT_REFCOUNT (project, "Still 1 ref for asset cache", 1);
|
||||
|
||||
g_main_loop_unref (mainloop);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
GESTimelinePipeline *pipeline = ges_timeline_pipeline_new ();
|
||||
|
||||
fail_unless (ges_timeline_pipeline_add_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);
|
||||
|
||||
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_load_xges_and_play); */
|
||||
tcase_add_test (tc_chain, test_project_unexistant_effect);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int nf;
|
||||
|
||||
Suite *s = ges_suite ();
|
||||
SRunner *sr = srunner_create (s);
|
||||
|
||||
gst_check_init (&argc, &argv);
|
||||
ges_init ();
|
||||
|
||||
srunner_run_all (sr, CK_NORMAL);
|
||||
nf = srunner_ntests_failed (sr);
|
||||
srunner_free (sr);
|
||||
|
||||
return nf;
|
||||
}
|
28
tests/check/ges/test-project.xges
Normal file
28
tests/check/ges/test-project.xges
Normal file
|
@ -0,0 +1,28 @@
|
|||
<ges version="0.1">
|
||||
<project metadatas='metadatas, name=(string)"Example\ project";'>
|
||||
<encoding-profiles>
|
||||
<encoding-profile name='first_profile' description='(null)' type='container' format='application/ogg'>
|
||||
<stream-profile parent='first_profile' id='0' type='video' presence='0' format='video/x-h264' pass='0' variableframerate='0' />
|
||||
<stream-profile parent='first_profile' id='1' type='audio' presence='0' format='audio/x-aac' />
|
||||
</encoding-profile>
|
||||
</encoding-profiles>
|
||||
<resources>
|
||||
<asset id="file:///test/not/exisiting"
|
||||
extractable-type-name="GESTimelineFileSource"/>
|
||||
</resources>
|
||||
<timeline>
|
||||
<track track-type="2" caps="audio/x-raw" track-id="0"/>
|
||||
<track track-type="4" caps="video/x-raw" track-id="1"/>
|
||||
<layer priority="0" properties='properties, auto-transition=(boolean)true;' metadatas='metadatas, a=(guint)3'>
|
||||
<timeline-object id="0" layer-priority='0' asset-id="file:///test/not/exisiting" type-name="GESTimelineFileSource" track-types="6" start="0" duration="1000000000">
|
||||
<effect asset-id='agingtv' timeline-object-id='0' type-name='GESTrackParseLaunchEffect' track-type='4' track-id='1' metadatas='metadatas;' children-properties='properties, scratch-lines=(uint)12;'/>
|
||||
</timeline-object>
|
||||
</layer>
|
||||
<layer priority="1" properties='properties, auto-transition=(boolean)true;'>
|
||||
<timeline-object id="1" asset-id="file:///test/not/exisiting" layer-priority="1"
|
||||
type-name="GESTimelineFileSource" track-types="2" start="1000000000" duration="1000000000">
|
||||
</timeline-object>
|
||||
</layer>
|
||||
</timeline>
|
||||
</project>
|
||||
</ges>
|
|
@ -1,50 +0,0 @@
|
|||
<pitivi formatter="GES" version="0.2">
|
||||
<factories>
|
||||
<sources>
|
||||
<source filename="file://./audio_video.ogg" id="1"/>
|
||||
</sources>
|
||||
</factories>
|
||||
<timeline>
|
||||
<tracks>
|
||||
<track>
|
||||
<stream caps="video/x-raw-yuv; video/x-raw-rgb" type="pitivi.stream.VideoStream"/>
|
||||
<track-objects>
|
||||
<track-object active="(bool)True" locked="(bool)True" priority="(int)0" duration="(gint64)14400000000" start="(gint64)14400000000" in_point="(gint64)0" id="0" type="pitivi.timeline.track.SourceTrackObject">
|
||||
<factory-ref id="1"/>
|
||||
</track-object>
|
||||
<track-object active="(bool)True" locked="(bool)True" priority="(int)0" duration="(gint64)14400000000" start="(gint64)0" in_point="(gint64)0" id="1" type="pitivi.timeline.track.SourceTrackObject">
|
||||
<factory-ref id="1"/>
|
||||
</track-object>
|
||||
</track-objects>
|
||||
</track>
|
||||
<track>
|
||||
<stream caps="audio/x-raw-int; audio/x-raw-float" type="pitivi.stream.AudioStream"/>
|
||||
<track-objects>
|
||||
<track-object active="(bool)True" locked="(bool)True" priority="(int)0" duration="(gint64)14400000000" start="(gint64)14400000000" in_point="(gint64)0" id="2" type="pitivi.timeline.track.SourceTrackObject">
|
||||
<factory-ref id="1"/>
|
||||
</track-object>
|
||||
<track-object active="(bool)True" locked="(bool)True" priority="(int)0" duration="(gint64)14400000000" start="(gint64)0" in_point="(gint64)0" id="3" type="pitivi.timeline.track.SourceTrackObject">
|
||||
<factory-ref id="1"/>
|
||||
</track-object>
|
||||
</track-objects>
|
||||
</track>
|
||||
</tracks>
|
||||
<timeline-objects>
|
||||
<timeline-object>
|
||||
<factory-ref id="1"/>
|
||||
<track-object-refs>
|
||||
<track-object-ref id="2"/>
|
||||
<track-object-ref id="0"/>
|
||||
</track-object-refs>
|
||||
</timeline-object>
|
||||
<timeline-object>
|
||||
<factory-ref id="1"/>
|
||||
<track-object-refs>
|
||||
<track-object-ref id="3"/>
|
||||
<track-object-ref id="1"/>
|
||||
</track-object-refs>
|
||||
</timeline-object>
|
||||
</timeline-objects>
|
||||
</timeline>
|
||||
</pitivi>
|
||||
|
Loading…
Reference in a new issue