/* GStreamer Editing Services * * Copyright (C) <2012> Thibault Saunier * * 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., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "test-utils.h" #include #include #define DEEP_CHECK(element, start, inpoint, duration) \ { \ GList *track_elements, *tmp; \ \ assert_equals_uint64 (_START (element), start); \ assert_equals_uint64 (_INPOINT (element), inpoint); \ assert_equals_uint64 (_DURATION (element), duration); \ \ track_elements = GES_CONTAINER_CHILDREN (element); \ for (tmp = track_elements; tmp; tmp = tmp->next) { \ assert_equals_uint64 (_START (tmp->data), start); \ assert_equals_uint64 (_INPOINT (tmp->data), inpoint); \ assert_equals_uint64 (_DURATION (tmp->data), duration); \ } \ } GST_START_TEST (test_basic_timeline_edition) { GESAsset *asset; GESTrack *track; GESTimeline *timeline; GESLayer *layer; GESTrackElement *trackelement, *trackelement1, *trackelement2; GESContainer *clip, *clip1, *clip2; ges_init (); track = GES_TRACK (ges_audio_track_new ()); fail_unless (track != NULL); timeline = ges_timeline_new (); fail_unless (timeline != NULL); fail_unless (ges_timeline_add_track (timeline, track)); layer = ges_layer_new (); fail_unless (layer != NULL); fail_unless (ges_timeline_add_layer (timeline, layer)); asset = ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL); fail_unless (GES_IS_ASSET (asset)); /** * Our timeline * * inpoints 0------- 0-------- 0----------- * | clip | | clip1 | | clip2 | * time 0------- 10 --------20 50---------60 */ clip = GES_CONTAINER (ges_layer_add_asset (layer, asset, 0, 0, 10, GES_TRACK_TYPE_UNKNOWN)); trackelement = GES_CONTAINER_CHILDREN (clip)->data; fail_unless (GES_IS_TRACK_ELEMENT (trackelement)); clip1 = GES_CONTAINER (ges_layer_add_asset (layer, asset, 10, 0, 10, GES_TRACK_TYPE_UNKNOWN)); trackelement1 = GES_CONTAINER_CHILDREN (clip1)->data; fail_unless (GES_IS_TRACK_ELEMENT (trackelement1)); clip2 = GES_CONTAINER (ges_layer_add_asset (layer, asset, 50, 0, 60, GES_TRACK_TYPE_UNKNOWN)); trackelement2 = GES_CONTAINER_CHILDREN (clip2)->data; fail_unless (GES_IS_TRACK_ELEMENT (trackelement2)); CHECK_OBJECT_PROPS (trackelement, 0, 0, 10); CHECK_OBJECT_PROPS (trackelement1, 10, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 50, 0, 60); /** * Simple rippling clip to: 10 * * New timeline: * ------------ * * inpoints 0------- 0-------- 0----------- * | clip | | clip1 | | clip2 | * time 10------- 20 --------30 60---------120 */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 10) == TRUE); CHECK_OBJECT_PROPS (trackelement, 10, 0, 10); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 60, 0, 60); /* FIXME find a way to check that we are using the same MovingContext * inside the GESTrack */ fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 40) == TRUE); CHECK_OBJECT_PROPS (trackelement, 10, 0, 10); CHECK_OBJECT_PROPS (trackelement1, 40, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 80, 0, 60); /** * Rippling clip1 back to: 20 (getting to the exact same timeline as before */ fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 20) == TRUE); CHECK_OBJECT_PROPS (trackelement, 10, 0, 10); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 60, 0, 60); /** * Simple move clip to: 27 and clip2 to 35 * * New timeline: * ------------ * 0------------ * inpoints 0-------|--- clip 0--|---------- * | clip1 27 -|-----|-37 clip2 | * time 20-----------30 35-------------120 */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 27) == TRUE); fail_unless (ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 35) == TRUE); CHECK_OBJECT_PROPS (trackelement, 27, 0, 10); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60); /** * Trim start clip to: 32 and clip2 to 35 * * New timeline: * ------------ * 5-------- * inpoints 0----------- | clip 0--|---------- * | clip1 | 32----|-37 clip2 | * time 20-----------30 35-------------120 */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_START, 32) == TRUE); CHECK_OBJECT_PROPS (trackelement, 32, 5, 5); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60); /* Ripple end clip to 42 * New timeline: * ------------ * 5-------- * inpoints 0----------- | clip 0--|---------- * | clip1 | 32----|-42 clip2 | * time 20-----------30 35-------------120 */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 42) == TRUE); CHECK_OBJECT_PROPS (trackelement, 32, 5, 10); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60); /** * New timeline: * ------------ * inpoints 0------- 5-------- 0----------- * | clip1 | | clip1 || clip2 | * time 20-------30 32--------52 ---------112 */ fail_unless (ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 42) == TRUE); fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 52) == TRUE); CHECK_OBJECT_PROPS (trackelement, 32, 5, 20); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 52, 0, 60); /** * New timeline: * ------------ * inpoints 0------- 5-------- 0------------ * | clip1 | | clip || clip2 | * time 20-------40 42--------62 ---------122 */ fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 40) == TRUE); CHECK_OBJECT_PROPS (trackelement, 42, 5, 20); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /** * New timeline: * ------------ * inpoints 0------- 3-------- 0------------ * | clip1 || clip || clip2 | * time 20-------40 --------62 ---------122 */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_START, 40) == TRUE); CHECK_OBJECT_PROPS (trackelement, 40, 3, 22); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /** * New timeline: * ------------ * inpoints 0------- 0-------- 0----------- * | clip1 || clip || clip2 | * time 20------ 25 ------ 62 ---------122 */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_START, 40) == TRUE); fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_START, 25) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /* Make sure that not doing anything when not able to roll */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_START, 65) == TRUE); fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_END, 65) == TRUE, 0); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); gst_object_unref (timeline); } GST_END_TEST; GST_START_TEST (test_snapping) { GESTrack *track; GESTimeline *timeline; GESTrackElement *trackelement, *trackelement1, *trackelement2; GESContainer *clip, *clip1, *clip2; GESLayer *layer; GList *trackelements; ges_init (); track = GES_TRACK (ges_video_track_new ()); fail_unless (track != NULL); timeline = ges_timeline_new (); fail_unless (timeline != NULL); fail_unless (ges_timeline_add_track (timeline, track)); clip = GES_CONTAINER (ges_test_clip_new ()); clip1 = GES_CONTAINER (ges_test_clip_new ()); clip2 = GES_CONTAINER (ges_test_clip_new ()); fail_unless (clip && clip1 && clip2); /** * Our timeline * ------------ * inpoints 0------- 0-------- 0----------- * | clip1 || clip || clip2 | * time 20------ 25 ------ 62 ---------122 */ g_object_set (clip, "start", (guint64) 25, "duration", (guint64) 37, "in-point", (guint64) 0, NULL); g_object_set (clip1, "start", (guint64) 20, "duration", (guint64) 15, "in-point", (guint64) 0, NULL); g_object_set (clip2, "start", (guint64) 62, "duration", (guint64) 60, "in-point", (guint64) 0, NULL); fail_unless ((layer = ges_timeline_append_layer (timeline)) != NULL); assert_equals_int (ges_layer_get_priority (layer), 0); fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip))); fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip)) != NULL); fail_unless ((trackelement = GES_TRACK_ELEMENT (trackelements->data)) != NULL); fail_unless (ges_track_element_get_track (trackelement) == track); assert_equals_uint64 (_DURATION (trackelement), 37); /* We have 3 references to trackelement from: * track + timeline + clip */ ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 3); /* We have 1 ref to clip1: * + layer */ ASSERT_OBJECT_REFCOUNT (clip, "First clip", 1); fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip1))); fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip1)) != NULL); fail_unless ((trackelement1 = GES_TRACK_ELEMENT (trackelements->data)) != NULL); fail_unless (ges_track_element_get_track (trackelement1) == track); assert_equals_uint64 (_DURATION (trackelement1), 15); /* Same ref logic */ ASSERT_OBJECT_REFCOUNT (trackelement1, "First trackelement", 3); ASSERT_OBJECT_REFCOUNT (clip1, "First clip", 1); fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip2))); fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip2)) != NULL); fail_unless ((trackelement2 = GES_TRACK_ELEMENT (trackelements->data)) != NULL); fail_unless (ges_track_element_get_track (trackelement2) == track); assert_equals_uint64 (_DURATION (trackelement2), 60); /* Same ref logic */ ASSERT_OBJECT_REFCOUNT (trackelement2, "First trackelement", 3); ASSERT_OBJECT_REFCOUNT (clip2, "First clip", 1); /* Snaping to edge, so no move */ g_object_set (timeline, "snapping-distance", (guint64) 3, NULL); fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_END, 27) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /* Snaping to edge, so no move */ fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_END, 27) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /** * New timeline: * ------------ * 0----------- 0------------- * inpoints 0-------|-- clip || clip2 | * | clip1 25-|------- 62 -----------122 * time 20----------30 */ g_object_set (timeline, "snapping-distance", (guint64) 0, NULL); ges_timeline_element_set_duration (GES_TIMELINE_ELEMENT (clip1), 10); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /** * New timeline(the "layers" are just to help reading diagram, nothing else): * ------------ * 0---------- * | clip | * 25---------62 * inpoints 0----------------------- 10-------- * | clip1 || clip2 | * time 20---------------------- 72 --------122 */ /* Rolling involves only neighbour that are currently snapping */ fail_unless (ges_timeline_element_roll_end (GES_TIMELINE_ELEMENT (clip1), 62)); fail_unless (ges_timeline_element_roll_end (GES_TIMELINE_ELEMENT (clip1), 72) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 52); CHECK_OBJECT_PROPS (trackelement2, 72, 10, 50); /** * 0---------- * | clip | * 25---------62 * inpoints 5--------------- 10-------- * | clip1 || clip2 | * time 25------------- 72 --------122 */ g_object_set (timeline, "snapping-distance", (guint64) 4, NULL); fail_unless (ges_timeline_element_trim (GES_TIMELINE_ELEMENT (clip1), 28) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 25, 5, 47); CHECK_OBJECT_PROPS (trackelement2, 72, 10, 50); /** * 0---------- * | clip | * 25---------62 * inpoints 5---------- 0--------- * | clip1 || clip2 | * time 25-------- 62 --------122 */ fail_unless (ges_timeline_element_roll_start (GES_TIMELINE_ELEMENT (clip2), 59) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 25, 5, 37); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /** * inpoints 0----------5---------- 0---------- * | clip || clip1 || clip2 | * time 25---------62-------- 99 --------170 */ fail_unless (ges_timeline_element_ripple (GES_TIMELINE_ELEMENT (clip1), 58) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 62, 5, 37); CHECK_OBJECT_PROPS (trackelement2, 99, 0, 60); /** * inpoints 0----------5---------- 0---------- * | clip || clip1 | | clip2 | * time 25---------62-------- 99 110--------170 */ ges_timeline_element_set_start (GES_TIMELINE_ELEMENT (clip2), 110); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 62, 5, 37); CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60); /** * inpoints 0----------5 5 --------- 0---------- * | clip | | clip1 || clip2 | * time 25---------62 73---------110--------170 */ fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 72) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 73, 5, 37); CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60); /** * inpoints 0----------5---------- 0---------- * | clip || clip1 | | clip2 | * time 25---------62-------- 99 110--------170 */ fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 58) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 62, 5, 37); CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60); /** * inpoints 0----------5---------- 0---------- * | clip || clip1 || clip2 | * time 25---------62--------110--------170 */ g_object_set (clip1, "duration", (guint64) 46, NULL); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 62, 5, 48); CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60); /** * inpoints 5----------- 0--------- 0---------- * | clip1 || clip2 || clip | * time 62---------110--------170--------207 */ g_object_set (clip, "start", (guint64) 168, NULL); CHECK_OBJECT_PROPS (trackelement, 170, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 62, 5, 48); CHECK_OBJECT_PROPS (trackelement2, 110, 0, 60); /* Check we didn't lose/screwed any references */ ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 3); ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 3); ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 3); ASSERT_OBJECT_REFCOUNT (clip, "First clip", 1); ASSERT_OBJECT_REFCOUNT (clip1, "Second clip", 1); ASSERT_OBJECT_REFCOUNT (clip2, "Third clip", 1); check_destroyed (G_OBJECT (timeline), G_OBJECT (trackelement), trackelement1, trackelement2, clip, clip1, clip2, layer, NULL); } GST_END_TEST; static void asset_added_cb (GESProject * project, GESAsset * asset, void *mainloop) { GstDiscovererInfo *info; info = ges_uri_clip_asset_get_info (GES_URI_CLIP_ASSET (asset)); fail_unless (GST_IS_DISCOVERER_INFO (info)); g_main_loop_quit ((GMainLoop *) mainloop); } GST_START_TEST (test_simple_triming) { GList *assets; GMainLoop *mainloop; GESClipAsset *asset; GESProject *project; GESTimeline *timeline; GESLayer *layer; GESTimelineElement *element; gchar *uri = ges_test_file_uri ("audio_video.ogg"); ges_init (); project = ges_project_new (NULL); mainloop = g_main_loop_new (NULL, FALSE); g_signal_connect (project, "asset-added", (GCallback) asset_added_cb, mainloop); ges_project_create_asset (project, uri, GES_TYPE_URI_CLIP); g_free (uri); g_main_loop_run (mainloop); /* the asset is now loaded */ timeline = ges_timeline_new_audio_video (); assets = ges_project_list_assets (project, GES_TYPE_CLIP); assert_equals_int (g_list_length (assets), 1); asset = assets->data; layer = ges_layer_new (); ges_timeline_add_layer (timeline, layer); ges_layer_add_asset (layer, GES_ASSET (asset), 0, 0, 10, ges_clip_asset_get_supported_formats (asset)); element = ges_layer_get_clips (layer)->data; DEEP_CHECK (element, 0, 0, 10); ges_container_edit (GES_CONTAINER (element), NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_START, 5); DEEP_CHECK (element, 5, 5, 5); g_main_loop_unref (mainloop); gst_object_unref (timeline); gst_object_unref (project); } GST_END_TEST; GST_START_TEST (test_timeline_edition_mode) { guint i; GESTrack *track; GESTimeline *timeline; GESTrackElement *trackelement, *trackelement1, *trackelement2; GESContainer *clip, *clip1, *clip2; GESLayer *layer, *layer1, *layer2; GList *trackelements, *layers, *tmp; ges_init (); track = GES_TRACK (ges_video_track_new ()); fail_unless (track != NULL); timeline = ges_timeline_new (); fail_unless (timeline != NULL); fail_unless (ges_timeline_add_track (timeline, track)); clip = GES_CONTAINER (ges_test_clip_new ()); clip1 = GES_CONTAINER (ges_test_clip_new ()); clip2 = GES_CONTAINER (ges_test_clip_new ()); fail_unless (clip && clip1 && clip2); /** * Our timeline * * 0------- * layer: | clip | * 0-------10 * * 0-------- 0----------- * layer1: | clip1 | | clip2 | * 10--------20 50---------60 */ g_object_set (clip, "start", (guint64) 0, "duration", (guint64) 10, "in-point", (guint64) 0, NULL); g_object_set (clip1, "start", (guint64) 10, "duration", (guint64) 10, "in-point", (guint64) 0, NULL); g_object_set (clip2, "start", (guint64) 50, "duration", (guint64) 60, "in-point", (guint64) 0, NULL); fail_unless ((layer = ges_timeline_append_layer (timeline)) != NULL); assert_equals_int (ges_layer_get_priority (layer), 0); fail_unless (ges_layer_add_clip (layer, GES_CLIP (clip))); fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip)) != NULL); fail_unless ((trackelement = GES_TRACK_ELEMENT (trackelements->data)) != NULL); fail_unless (ges_track_element_get_track (trackelement) == track); assert_equals_uint64 (_DURATION (trackelement), 10); /* Add a new layer and add clipects to it */ fail_unless ((layer1 = ges_timeline_append_layer (timeline)) != NULL); fail_unless (layer != layer1); assert_equals_int (ges_layer_get_priority (layer1), 1); fail_unless (ges_layer_add_clip (layer1, GES_CLIP (clip1))); fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip1)) != NULL); fail_unless ((trackelement1 = GES_TRACK_ELEMENT (trackelements->data)) != NULL); fail_unless (ges_track_element_get_track (trackelement1) == track); assert_equals_uint64 (_DURATION (trackelement1), 10); fail_unless (ges_layer_add_clip (layer1, GES_CLIP (clip2))); fail_unless ((trackelements = GES_CONTAINER_CHILDREN (clip2)) != NULL); fail_unless ((trackelement2 = GES_TRACK_ELEMENT (trackelements->data)) != NULL); fail_unless (ges_track_element_get_track (trackelement2) == track); assert_equals_uint64 (_DURATION (trackelement2), 60); /** * Simple rippling clip to: 10 * * New timeline: * ------------ * * inpoints 0------- * | clip | * time 10-------20 * * 0-------- 0----------- * | clip1 | | clip2 | * 20--------30 60--------120 */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 10) == TRUE); CHECK_OBJECT_PROPS (trackelement, 10, 0, 10); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 60, 0, 60); /* FIXME find a way to check that we are using the same MovingContext * inside the GESTimeline */ fail_unless (ges_container_edit (clip1, NULL, 3, GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 40) == TRUE); CHECK_OBJECT_PROPS (trackelement, 10, 0, 10); CHECK_OBJECT_PROPS (trackelement1, 40, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 80, 0, 60); layer2 = ges_clip_get_layer (GES_CLIP (clip1)); assert_equals_int (ges_layer_get_priority (layer2), 3); /* clip2 should have moved layer too */ fail_unless (ges_clip_get_layer (GES_CLIP (clip2)) == layer2); /* We got 2 reference to the same clipect, unref them */ gst_object_unref (layer2); gst_object_unref (layer2); /** * Rippling clip1 back to: 20 (getting to the exact same timeline as before */ fail_unless (ges_container_edit (clip1, NULL, 1, GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 20) == TRUE); CHECK_OBJECT_PROPS (trackelement, 10, 0, 10); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 60, 0, 60); layer2 = ges_clip_get_layer (GES_CLIP (clip1)); assert_equals_int (ges_layer_get_priority (layer2), 1); /* clip2 should have moved layer too */ fail_unless (ges_clip_get_layer (GES_CLIP (clip2)) == layer2); /* We got 2 reference to the same clipect, unref them */ gst_object_unref (layer2); gst_object_unref (layer2); /** * Simple move clip to 27 and clip2 to 35 * * New timeline: * ------------ * * inpoints 0------- * | clip | * time 27-------37 * * 0-------- 0----------- * | clip1 | | clip2 | * 20--------30 35---------95 */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 27) == TRUE); fail_unless (ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 35) == TRUE); CHECK_OBJECT_PROPS (trackelement, 27, 0, 10); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60); /** * Simple trimming start clip to: 32 * * New timeline: * ------------ * * 5------- * layer 0: | clip | * 32-------37 * * 0-------- 0----------- * layer 1 | clip1 | | clip2 | * 20--------30 35---------95 */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_START, 32) == TRUE); CHECK_OBJECT_PROPS (trackelement, 32, 5, 5); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60); /* Ripple end clip to 35 and move to layer 2 * New timeline: * ------------ * * 0-------- 0----------- * layer 1: | clip1 | | clip2 | * 20--------30 35---------95 * * 5------ * layer 2: | clip | * 32------35 */ fail_unless (ges_container_edit (clip, NULL, 2, GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 35) == TRUE); CHECK_OBJECT_PROPS (trackelement, 32, 5, 3); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60); layer = ges_clip_get_layer (GES_CLIP (clip)); assert_equals_int (ges_layer_get_priority (layer), 2); gst_object_unref (layer); /* Roll end clip to 50 * New timeline: * ------------ * * 0-------- 0----------- * layer 1: | clip1 | | clip2 | * 20--------30 50---------95 * * 5------ * layer 2: | clip | * 32------50 */ fail_unless (ges_container_edit (clip, NULL, 2, GES_EDIT_MODE_ROLL, GES_EDGE_END, 50) == TRUE); CHECK_OBJECT_PROPS (trackelement, 32, 5, 18); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 50, 15, 45); layer = ges_clip_get_layer (GES_CLIP (clip)); assert_equals_int (ges_layer_get_priority (layer), 2); gst_object_unref (layer); /* Some more intensive roll testing */ for (i = 0; i < 20; i++) { gint32 random = g_random_int_range (35, 94); guint64 tck3_inpoint = random - 35; fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_END, random) == TRUE); CHECK_OBJECT_PROPS (trackelement, 32, 5, random - 32); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, random, tck3_inpoint, 95 - random); } /* Roll end clip back to 35 * New timeline: * ------------ * * 0-------- 0----------- * layer 1: | clip1 | | clip2 | * 20--------30 35---------95 * * 5------ * layer 2: | clip | * 32------35 */ fail_unless (ges_container_edit (clip, NULL, 2, GES_EDIT_MODE_ROLL, GES_EDGE_END, 35) == TRUE); CHECK_OBJECT_PROPS (trackelement, 32, 5, 3); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 35, 0, 60); layer = ges_clip_get_layer (GES_CLIP (clip)); assert_equals_int (ges_layer_get_priority (layer), 2); gst_object_unref (layer); /* Ripple clip end to 52 * New timeline: * ------------ * * 0-------- 0---------- * layer 1: | clip1 | | clip2 | * 20-------30 52---------112 * * 5------ * layer 2: | clip | * 32------52 * */ /* Can not move to the first layer as clip2 should move to a layer with priority < 0 */ fail_unless (ges_container_edit (clip, NULL, 0, GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 52) == TRUE); CHECK_OBJECT_PROPS (trackelement, 32, 5, 20); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 52, 0, 60) layer = ges_clip_get_layer (GES_CLIP (clip)); assert_equals_int (ges_layer_get_priority (layer), 2); gst_object_unref (layer); /* Little check that we have 4 layers in the timeline */ layers = ges_timeline_get_layers (timeline); assert_equals_int (g_list_length (layers), 4); /* Some refcount checkings */ /* We have a reference to each layer in layers */ for (tmp = layers; tmp; tmp = tmp->next) ASSERT_OBJECT_REFCOUNT (layer, "Layer", 2); g_list_free_full (layers, gst_object_unref); /* We have 3 references: * track + timeline + clip */ ASSERT_OBJECT_REFCOUNT (trackelement, "First trackelement", 3); ASSERT_OBJECT_REFCOUNT (trackelement1, "Second trackelement", 3); ASSERT_OBJECT_REFCOUNT (trackelement2, "Third trackelement", 3); /* We have 1 ref: * + layer */ ASSERT_OBJECT_REFCOUNT (clip, "First clip", 1); ASSERT_OBJECT_REFCOUNT (clip1, "Second clip", 1); ASSERT_OBJECT_REFCOUNT (clip2, "Third clip", 1); /* Ripple clip end to 52 * New timeline: * ------------ * * 0-------- 0----------- * layer 0: | clip1 | | clip2 | * 20-------40 62----------112 * * 5------ * layer 1: | clip | * 42------60 * */ fail_unless (ges_container_edit (clip1, NULL, 0, GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 40) == TRUE); CHECK_OBJECT_PROPS (trackelement, 42, 5, 20); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /* Check that movement between layer has been done properly */ layer1 = ges_clip_get_layer (GES_CLIP (clip)); layer = ges_clip_get_layer (GES_CLIP (clip1)); assert_equals_int (ges_layer_get_priority (layer1), 1); assert_equals_int (ges_layer_get_priority (layer), 0); fail_unless (ges_clip_get_layer (GES_CLIP (clip2)) == layer); gst_object_unref (layer1); /* We have 2 references to @layer that we do not need anymore */ ; gst_object_unref (layer); gst_object_unref (layer); /* Trim clip start to 40 * New timeline: * ------------ * * 0-------- 0----------- * layer 0: | clip1 | | clip2 | * 20-------40 62---------112 * * 0------ * layer 1: | clip | * 40------62 * */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_START, 40) == TRUE); CHECK_OBJECT_PROPS (trackelement, 40, 3, 22); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 20); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /* Roll clip end to 25 * New timeline: * ------------ * * 0-------- 0----------- * layer 0: | clip1 | | clip2 | * 20-------25 62---------112 * * 0------ * layer 1: | clip | * 25------62 * */ fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_END, 25) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /* Make sure that not doing anything when not able to roll */ fail_unless (ges_container_edit (clip, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_START, 65) == TRUE); fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_END, 65) == TRUE, 0); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /* Snaping to edge, so no move */ g_object_set (timeline, "snapping-distance", (guint64) 3, NULL); fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_END, 27) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /* Snaping to edge, so no move */ fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_END, 27) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 5); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /** * New timeline: * ------------ * 0----------- 0------------- * inpoints 0-------|-- clip || clip2 | * | clip1 25-|------- 62 -----------122 * time 20----------30 */ g_object_set (timeline, "snapping-distance", (guint64) 0, NULL); fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_END, 30) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 10); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); /** * New timeline * ------------ * 0---------- * | clip | * 25---------62 * inpoints 0----------------------- 10-------- * | clip1 || clip2 | * time 20---------------------- 72 --------122 */ /* Rolling involves only neighbours that are currently snapping */ fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_END, 62) == TRUE); fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_END, 72) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 20, 0, 52); CHECK_OBJECT_PROPS (trackelement2, 72, 10, 50); /* Test Snapping */ /** * 0---------- * | clip | * 25---------62 * inpoints 5--------------- 10-------- * | clip1 || clip2 | * time 25------------- 72 --------122 */ g_object_set (timeline, "snapping-distance", (guint64) 4, NULL); fail_unless (ges_container_edit (clip1, NULL, -1, GES_EDIT_MODE_TRIM, GES_EDGE_START, 28) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 25, 5, 47); CHECK_OBJECT_PROPS (trackelement2, 72, 10, 50); /** * 0---------- * | clip | * 25---------62 * inpoints 5---------- 0--------- * | clip1 || clip2 | * time 25-------- 62 --------122 */ fail_unless (ges_container_edit (clip2, NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_START, 59) == TRUE); CHECK_OBJECT_PROPS (trackelement, 25, 0, 37); CHECK_OBJECT_PROPS (trackelement1, 25, 5, 37); CHECK_OBJECT_PROPS (trackelement2, 62, 0, 60); } GST_END_TEST; GST_START_TEST (test_groups) { GESAsset *asset; GESTimeline *timeline; GESGroup *group; GESLayer *layer, *layer1, *layer2, *layer3; GESClip *c, *c1, *c2, *c3, *c4, *c5; GList *clips = NULL; ges_init (); timeline = ges_timeline_new_audio_video (); /* Our timeline * * --0------------10-Group-----20---------------30-----------------------70 * | +-----------+ |+-----------50 | * L | | C | || C3 | | * | +-----------+ |+-----------+ | * --|-------------------------------------------|-----40----------------| * | +------------+ +-------------+ | +--------60 | * L1 | | C1 | | C2 | | | C4 | | * | +------------+ +-------------+ | +--------+ | * --|-------------------------------------------|-----------------------| * | | +--------+| * L2 | | | c5 || * | | +--------+| * --+-------------------------------------------+-----------------------+ * * L3 * * ----------------------------------------------------------------------- */ layer = ges_timeline_append_layer (timeline); layer1 = ges_timeline_append_layer (timeline); layer2 = ges_timeline_append_layer (timeline); layer3 = ges_timeline_append_layer (timeline); assert_equals_int (ges_layer_get_priority (layer3), 3); asset = ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL); c = ges_layer_add_asset (layer, asset, 0, 0, 10, GES_TRACK_TYPE_UNKNOWN); c1 = ges_layer_add_asset (layer1, asset, 10, 0, 10, GES_TRACK_TYPE_UNKNOWN); c2 = ges_layer_add_asset (layer1, asset, 20, 0, 10, GES_TRACK_TYPE_UNKNOWN); clips = g_list_prepend (clips, c); clips = g_list_prepend (clips, c1); clips = g_list_prepend (clips, c2); group = GES_GROUP (ges_container_group (clips)); fail_unless (GES_TIMELINE_ELEMENT_TIMELINE (group) == timeline); g_list_free (clips); fail_unless (GES_IS_GROUP (group)); CHECK_OBJECT_PROPS (c, 0, 0, 10); CHECK_OBJECT_PROPS (c1, 10, 0, 10); CHECK_OBJECT_PROPS (c2, 20, 0, 10); CHECK_OBJECT_PROPS (group, 0, 0, 30); c3 = ges_layer_add_asset (layer, asset, 30, 0, 20, GES_TRACK_TYPE_UNKNOWN); c4 = ges_layer_add_asset (layer1, asset, 40, 0, 20, GES_TRACK_TYPE_UNKNOWN); c5 = ges_layer_add_asset (layer2, asset, 50, 0, 20, GES_TRACK_TYPE_UNKNOWN); CHECK_OBJECT_PROPS (c3, 30, 0, 20); CHECK_OBJECT_PROPS (c4, 40, 0, 20); CHECK_OBJECT_PROPS (c5, 50, 0, 20); check_layer (c, 0); check_layer (c1, 1); check_layer (c2, 1); check_layer (c3, 0); check_layer (c4, 1); check_layer (c5, 2); fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, -1, GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 10) == TRUE); CHECK_OBJECT_PROPS (c, 10, 0, 10); CHECK_OBJECT_PROPS (c1, 20, 0, 10); CHECK_OBJECT_PROPS (c2, 30, 0, 10); CHECK_OBJECT_PROPS (c3, 40, 0, 20); CHECK_OBJECT_PROPS (c4, 50, 0, 20); CHECK_OBJECT_PROPS (c5, 60, 0, 20); check_layer (c, 0); check_layer (c1, 1); check_layer (c2, 1); check_layer (c3, 0); check_layer (c4, 1); check_layer (c5, 2); fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 1, GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 10) == TRUE); CHECK_OBJECT_PROPS (c, 10, 0, 10); CHECK_OBJECT_PROPS (c1, 20, 0, 10); CHECK_OBJECT_PROPS (c2, 30, 0, 10); CHECK_OBJECT_PROPS (c3, 40, 0, 20); CHECK_OBJECT_PROPS (c4, 50, 0, 20); CHECK_OBJECT_PROPS (c5, 60, 0, 20); check_layer (c, 1); check_layer (c1, 2); check_layer (c2, 2); check_layer (c3, 1); check_layer (c4, 2); check_layer (c5, 3); fail_unless (ges_container_edit (GES_CONTAINER (c1), NULL, 2, GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 40) == TRUE); CHECK_OBJECT_PROPS (c, 10, 0, 10); CHECK_OBJECT_PROPS (c1, 20, 0, 20); CHECK_OBJECT_PROPS (c2, 40, 0, 10); CHECK_OBJECT_PROPS (c3, 50, 0, 20); CHECK_OBJECT_PROPS (c4, 60, 0, 20); CHECK_OBJECT_PROPS (c5, 70, 0, 20); check_layer (c, 1); check_layer (c1, 2); check_layer (c2, 2); check_layer (c3, 1); check_layer (c4, 2); check_layer (c5, 3); fail_unless (ges_container_edit (GES_CONTAINER (c1), NULL, 2, GES_EDIT_MODE_RIPPLE, GES_EDGE_END, 30) == TRUE); CHECK_OBJECT_PROPS (c, 10, 0, 10); CHECK_OBJECT_PROPS (c1, 20, 0, 10); CHECK_OBJECT_PROPS (c2, 30, 0, 10); CHECK_OBJECT_PROPS (c3, 40, 0, 20); CHECK_OBJECT_PROPS (c4, 50, 0, 20); CHECK_OBJECT_PROPS (c5, 60, 0, 20); check_layer (c, 1); check_layer (c1, 2); check_layer (c2, 2); check_layer (c3, 1); check_layer (c4, 2); check_layer (c5, 3); fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 0, GES_EDIT_MODE_RIPPLE, GES_EDGE_NONE, 0) == TRUE); CHECK_OBJECT_PROPS (c, 0, 0, 10); CHECK_OBJECT_PROPS (c1, 10, 0, 10); CHECK_OBJECT_PROPS (c2, 20, 0, 10); CHECK_OBJECT_PROPS (c3, 30, 0, 20); CHECK_OBJECT_PROPS (c4, 40, 0, 20); CHECK_OBJECT_PROPS (c5, 50, 0, 20); check_layer (c, 0); check_layer (c1, 1); check_layer (c2, 1); check_layer (c3, 0); check_layer (c4, 1); check_layer (c5, 2); fail_unless (ges_container_edit (GES_CONTAINER (c2), NULL, -1, GES_EDIT_MODE_ROLL, GES_EDGE_END, 40) == TRUE); CHECK_OBJECT_PROPS (c, 0, 0, 10); CHECK_OBJECT_PROPS (c1, 10, 0, 10); CHECK_OBJECT_PROPS (c2, 20, 0, 20); CHECK_OBJECT_PROPS (c3, 40, 10, 10); CHECK_OBJECT_PROPS (c4, 40, 0, 20); CHECK_OBJECT_PROPS (c5, 50, 0, 20); CHECK_OBJECT_PROPS (group, 0, 0, 40); check_layer (c, 0); check_layer (c1, 1); check_layer (c2, 1); check_layer (c3, 0); check_layer (c4, 1); check_layer (c5, 2); fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, 0, GES_EDIT_MODE_TRIM, GES_EDGE_START, 5) == TRUE); CHECK_OBJECT_PROPS (c, 5, 5, 5); CHECK_OBJECT_PROPS (c1, 10, 0, 10); CHECK_OBJECT_PROPS (c2, 20, 0, 20); CHECK_OBJECT_PROPS (c3, 40, 10, 10); CHECK_OBJECT_PROPS (c4, 40, 0, 20); CHECK_OBJECT_PROPS (c5, 50, 0, 20); CHECK_OBJECT_PROPS (group, 5, 0, 35); check_layer (c, 0); check_layer (c1, 1); check_layer (c2, 1); check_layer (c3, 0); check_layer (c4, 1); check_layer (c5, 2); gst_object_unref (timeline); gst_object_unref (asset); } GST_END_TEST; GST_START_TEST (test_snapping_groups) { GESAsset *asset; GESTimeline *timeline; GESGroup *group; GESLayer *layer, *layer1, *layer2, *layer3; GESClip *c, *c1, *c2, *c3, *c4, *c5; GList *clips = NULL; ges_init (); timeline = ges_timeline_new_audio_video (); g_object_set (timeline, "snapping-distance", (guint64) 3, NULL); /* Our timeline * * --0------------10-Group-----20---------25-----30----------------------70 * | +-----------+ | +-----------50 | * L | | C | | | C3 | | * | +-----------+ | +-----------+ | * --|------------------------------------|------------40----------------| * | +------------+ +--------+ +--------60 | * L1 | | C1 | | C2 | | C4 | | * | +------------+ +--------+ +--------+ | * --|------------------------------------+------------------------------| * | +--------+| * L2 | | c5 || * | +--------+| * --+-------------------------------------------------------------------+ * * L3 * * ----------------------------------------------------------------------- */ layer = ges_timeline_append_layer (timeline); layer1 = ges_timeline_append_layer (timeline); layer2 = ges_timeline_append_layer (timeline); layer3 = ges_timeline_append_layer (timeline); assert_equals_int (ges_layer_get_priority (layer3), 3); asset = ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL); c = ges_layer_add_asset (layer, asset, 0, 0, 10, GES_TRACK_TYPE_UNKNOWN); c1 = ges_layer_add_asset (layer1, asset, 10, 0, 10, GES_TRACK_TYPE_UNKNOWN); c2 = ges_layer_add_asset (layer1, asset, 20, 0, 5, GES_TRACK_TYPE_UNKNOWN); clips = g_list_prepend (clips, c); clips = g_list_prepend (clips, c1); clips = g_list_prepend (clips, c2); group = GES_GROUP (ges_container_group (clips)); fail_unless (GES_TIMELINE_ELEMENT_TIMELINE (group) == timeline); g_list_free (clips); fail_unless (GES_IS_GROUP (group)); CHECK_OBJECT_PROPS (c, 0, 0, 10); CHECK_OBJECT_PROPS (c1, 10, 0, 10); CHECK_OBJECT_PROPS (c2, 20, 0, 5); CHECK_OBJECT_PROPS (group, 0, 0, 25); c3 = ges_layer_add_asset (layer, asset, 30, 0, 20, GES_TRACK_TYPE_UNKNOWN); c4 = ges_layer_add_asset (layer1, asset, 40, 0, 20, GES_TRACK_TYPE_UNKNOWN); c5 = ges_layer_add_asset (layer2, asset, 50, 0, 20, GES_TRACK_TYPE_UNKNOWN); CHECK_OBJECT_PROPS (c3, 30, 0, 20); CHECK_OBJECT_PROPS (c4, 40, 0, 20); CHECK_OBJECT_PROPS (c5, 50, 0, 20); check_layer (c, 0); check_layer (c1, 1); check_layer (c2, 1); check_layer (c3, 0); check_layer (c4, 1); check_layer (c5, 2); /* c2 should snap with C3 and make the group moving to 5 */ fail_unless (ges_container_edit (GES_CONTAINER (c), NULL, -1, GES_EDIT_MODE_NORMAL, GES_EDGE_NONE, 3) == TRUE); DEEP_CHECK (c, 5, 0, 10); DEEP_CHECK (c1, 15, 0, 10); DEEP_CHECK (c2, 25, 0, 5); DEEP_CHECK (c2, 25, 0, 5); DEEP_CHECK (c4, 40, 0, 20); DEEP_CHECK (c5, 50, 0, 20); CHECK_OBJECT_PROPS (group, 5, 0, 25); check_layer (c, 0); check_layer (c1, 1); check_layer (c2, 1); check_layer (c3, 0); check_layer (c4, 1); check_layer (c5, 2); gst_object_unref (timeline); gst_object_unref (asset); } GST_END_TEST; static void _set_track_element_width_height (GESTrackElement * trksrc, gint wvalue, gint hvalue) { GValue width = { 0 }; GValue height = { 0 }; g_value_init (&width, G_TYPE_INT); g_value_init (&height, G_TYPE_INT); g_value_set_int (&width, wvalue); g_value_set_int (&height, hvalue); if (wvalue >= 0) ges_track_element_set_child_property (trksrc, "width", &width); if (hvalue >= 0) ges_track_element_set_child_property (trksrc, "height", &height); } static gboolean check_frame_positionner_size (GESClip * clip, gint width, gint height) { GESTrackElement *trksrc; GValue val_width = { 0 }; GValue val_height = { 0 }; gint real_width, real_height; trksrc = GES_CONTAINER_CHILDREN (clip)->data; if (!GES_IS_VIDEO_SOURCE (trksrc)) return FALSE; g_value_init (&val_width, G_TYPE_INT); g_value_init (&val_height, G_TYPE_INT); ges_track_element_get_child_property (trksrc, "width", &val_width); ges_track_element_get_child_property (trksrc, "height", &val_height); real_width = g_value_get_int (&val_width); real_height = g_value_get_int (&val_height); return (width == real_width && height == real_height); } GST_START_TEST (test_scaling) { GESTimeline *timeline; GESLayer *layer; GESAsset *asset1, *asset2; GESClip *clip; GESTrack *trackv = GES_TRACK (ges_video_track_new ()); GstCaps *caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, 1200, "height", G_TYPE_INT, 1000, NULL); ges_init (); timeline = ges_timeline_new (); ges_timeline_add_track (timeline, trackv); layer = ges_layer_new (); fail_unless (ges_timeline_add_layer (timeline, layer)); g_object_set (layer, "auto-transition", TRUE, NULL); asset1 = GES_ASSET (ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL)); asset2 = GES_ASSET (ges_asset_request (GES_TYPE_TEST_CLIP, NULL, NULL)); fail_unless (asset1 != NULL && asset2 != NULL); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (timeline), GST_DEBUG_GRAPH_SHOW_ALL, "ges-integration-timeline"); ges_track_set_restriction_caps (trackv, caps); gst_caps_unref (caps); GST_DEBUG ("adding clip, should be 1200 x 1000"); clip = ges_layer_add_asset (layer, GES_ASSET (asset1), 0 * GST_SECOND, 0 * GST_SECOND, 4 * GST_SECOND, GES_TRACK_TYPE_UNKNOWN); gst_object_unref (asset1); g_object_set (clip, "vpattern", (gint) GES_VIDEO_TEST_PATTERN_SMPTE75, NULL); /** * Our track: 1200 x 1000 * * 0--------------0 * | width : 1200 | * | height: 1000 | * 0--------------2 */ /* clip takes the size set on the track as a default */ fail_unless (check_frame_positionner_size (clip, 1200, 1000)); if (GES_IS_VIDEO_SOURCE (GES_CONTAINER_CHILDREN (clip)->data)) _set_track_element_width_height (GES_CONTAINER_CHILDREN (clip)->data, 1024, 768); GST_DEBUG ("Setting clip size, should be 1024 x 768"); /** * Our timeline : 1200 x 1000 * * 0--------------0 * | width : 1024 | * | height: 768 | * 0--------------2 */ /* Clip has to comply to direct orders */ fail_unless (check_frame_positionner_size (clip, 1024, 768)); GST_DEBUG ("Changing caps, should still be 1024 x 768"); caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, 1400, "height", G_TYPE_INT, 1200, NULL); ges_track_set_restriction_caps (trackv, caps); gst_caps_unref (caps); /** * Our timeline : 1400 x 1200 * * 0--------------0 * | width : 1024 | * | height: 768 | * 0--------------2 */ /* Clip still has to be the same size */ fail_unless (check_frame_positionner_size (clip, 1024, 768)); GST_DEBUG ("Setting width to 0, should be 1400 x 768"); /* -1 means don't set it, only valid here */ if (GES_IS_VIDEO_SOURCE (GES_CONTAINER_CHILDREN (clip)->data)) _set_track_element_width_height (GES_CONTAINER_CHILDREN (clip)->data, 0, -1); /** * Our timeline : 1400 x 1200 * * 0--------------0 * | width : 1400 | * | height: 768 | * 0--------------2 */ /* Clip width was set to 0 so it has to use track width */ /* Clip height is still directly set by the user */ fail_unless (check_frame_positionner_size (clip, 1400, 768)); GST_DEBUG ("Setting height to 0, should be 1400 x 1200"); if (GES_IS_VIDEO_SOURCE (GES_CONTAINER_CHILDREN (clip)->data)) _set_track_element_width_height (GES_CONTAINER_CHILDREN (clip)->data, -1, 0); /** * Our timeline : 1400 x 1200 * * 0--------------0 * | width : 1400 | * | height: 1200 | * 0--------------2 */ /* Clip width still has to use track width */ /* Clip height was set to 0 so it has to use track height */ fail_unless (check_frame_positionner_size (clip, 1400, 1200)); GST_DEBUG ("Removing restriction on track height, should be 1400 x 240"); caps = gst_caps_new_simple ("video/x-raw", "width", G_TYPE_INT, 1400, "height", G_TYPE_INT, 0, NULL); ges_track_set_restriction_caps (trackv, caps); gst_caps_unref (caps); /** * Our timeline : 1400 x no restriction * * 0--------------0 * | width : 1400 | * | height: 240 | * 0--------------2 */ /* Clip width still has to use track width */ /* Clip height was set to 0 so it has to use natural clip height */ fail_unless (check_frame_positionner_size (clip, 1400, 0)); GST_DEBUG ("Removing restriction on track width, should be 320 x 240"); caps = gst_caps_new_empty_simple ("video/x-raw"); ges_track_set_restriction_caps (trackv, caps); gst_caps_unref (caps); /** * Our timeline : no restriction x no restriction * * 0--------------0 * | width : 320 | * | height: 240 | * 0--------------2 */ /* Clip width was set to 0 so it has to use natural clip width */ /* Clip height was set to 0 so it has to use natural clip height */ fail_unless (check_frame_positionner_size (clip, 0, 0)); } GST_END_TEST; static Suite * ges_suite (void) { Suite *s = suite_create ("ges-timeline-edition"); TCase *tc_chain = tcase_create ("timeline-edition"); suite_add_tcase (s, tc_chain); tcase_add_test (tc_chain, test_basic_timeline_edition); tcase_add_test (tc_chain, test_snapping); tcase_add_test (tc_chain, test_timeline_edition_mode); tcase_add_test (tc_chain, test_simple_triming); tcase_add_test (tc_chain, test_groups); tcase_add_test (tc_chain, test_snapping_groups); tcase_add_test (tc_chain, test_scaling); return s; } GST_CHECK_MAIN (ges);