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