1 /* GStreamer Editing Services
2 * Copyright (C) 2010 Edward Hervey <edward.hervey@collabora.co.uk>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 /**
21 * SECTION:ges-utils
22 * @title: GES utilities
23 * @short_description: Convenience methods
24 *
25 */
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <string.h>
31
32 #include "ges-internal.h"
33 #include "ges-timeline.h"
34 #include "ges-track.h"
35 #include "ges-layer.h"
36 #include "ges.h"
37
38 static GstElementFactory *compositor_factory = NULL;
39
40 /**
41 * ges_timeline_new_audio_video:
42 *
43 * Creates a new #GESTimeline containing a raw audio and a
44 * raw video track.
45 *
46 * Returns: (transfer floating): The newly created #GESTimeline.
47 */
48
49 GESTimeline *
ges_timeline_new_audio_video(void)50 ges_timeline_new_audio_video (void)
51 {
52 GESTrack *tracka, *trackv;
53 GESTimeline *timeline;
54
55 /* This is our main GESTimeline */
56 timeline = ges_timeline_new ();
57
58 tracka = GES_TRACK (ges_audio_track_new ());
59 trackv = GES_TRACK (ges_video_track_new ());
60
61 if (!ges_timeline_add_track (timeline, trackv) ||
62 !ges_timeline_add_track (timeline, tracka)) {
63 gst_object_unref (timeline);
64 timeline = NULL;
65 }
66
67 return timeline;
68 }
69
70 /* Internal utilities */
71 gint
element_start_compare(GESTimelineElement * a,GESTimelineElement * b)72 element_start_compare (GESTimelineElement * a, GESTimelineElement * b)
73 {
74 if (a->start == b->start) {
75 if (a->priority < b->priority)
76 return -1;
77 if (a->priority > b->priority)
78 return 1;
79 if (a->duration < b->duration)
80 return -1;
81 if (a->duration > b->duration)
82 return 1;
83 return 0;
84 } else if (a->start < b->start)
85 return -1;
86
87 return 1;
88 }
89
90 gint
element_end_compare(GESTimelineElement * a,GESTimelineElement * b)91 element_end_compare (GESTimelineElement * a, GESTimelineElement * b)
92 {
93 if (GES_TIMELINE_ELEMENT_END (a) == GES_TIMELINE_ELEMENT_END (b)) {
94 if (a->priority < b->priority)
95 return -1;
96 if (a->priority > b->priority)
97 return 1;
98 if (a->duration < b->duration)
99 return -1;
100 if (a->duration > b->duration)
101 return 1;
102 return 0;
103 } else if (GES_TIMELINE_ELEMENT_END (a) < (GES_TIMELINE_ELEMENT_END (b)))
104 return -1;
105
106 return 1;
107 }
108
109 gboolean
ges_pspec_equal(gconstpointer key_spec_1,gconstpointer key_spec_2)110 ges_pspec_equal (gconstpointer key_spec_1, gconstpointer key_spec_2)
111 {
112 const GParamSpec *key1 = key_spec_1;
113 const GParamSpec *key2 = key_spec_2;
114
115 return (key1->owner_type == key2->owner_type &&
116 strcmp (key1->name, key2->name) == 0);
117 }
118
119 guint
ges_pspec_hash(gconstpointer key_spec)120 ges_pspec_hash (gconstpointer key_spec)
121 {
122 const GParamSpec *key = key_spec;
123 const gchar *p;
124 guint h = key->owner_type;
125
126 for (p = key->name; *p; p++)
127 h = (h << 5) - h + *p;
128
129 return h;
130 }
131
132 static gboolean
find_compositor(GstPluginFeatureFilter * feature,gpointer udata)133 find_compositor (GstPluginFeatureFilter * feature, gpointer udata)
134 {
135 const gchar *klass;
136
137 if (G_UNLIKELY (!GST_IS_ELEMENT_FACTORY (feature)))
138 return FALSE;
139
140 klass = gst_element_factory_get_metadata (GST_ELEMENT_FACTORY_CAST (feature),
141 GST_ELEMENT_METADATA_KLASS);
142
143 return (strstr (klass, "Compositor") != NULL);
144 }
145
146
147
148 GstElementFactory *
ges_get_compositor_factory(void)149 ges_get_compositor_factory (void)
150 {
151 GList *result;
152
153 if (compositor_factory)
154 return compositor_factory;
155
156 result = gst_registry_feature_filter (gst_registry_get (),
157 (GstPluginFeatureFilter) find_compositor, FALSE, NULL);
158
159 /* sort on rank and name */
160 result = g_list_sort (result, gst_plugin_feature_rank_compare_func);
161 g_assert (result);
162
163 compositor_factory = result->data;
164 gst_plugin_feature_list_free (result);
165
166 return compositor_factory;
167 }
168
169 gboolean
ges_nle_composition_add_object(GstElement * comp,GstElement * object)170 ges_nle_composition_add_object (GstElement * comp, GstElement * object)
171 {
172 return gst_bin_add (GST_BIN (comp), object);
173 }
174
175 gboolean
ges_nle_composition_remove_object(GstElement * comp,GstElement * object)176 ges_nle_composition_remove_object (GstElement * comp, GstElement * object)
177 {
178 return gst_bin_remove (GST_BIN (comp), object);
179 }
180
181 gboolean
ges_nle_object_commit(GstElement * nlesource,gboolean recurse)182 ges_nle_object_commit (GstElement * nlesource, gboolean recurse)
183 {
184 gboolean ret;
185
186 g_signal_emit_by_name (nlesource, "commit", recurse, &ret);
187
188 return ret;
189 }
190