1 /* GStreamer
2 *
3 * Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
4 * Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@gmail.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 /**
23 * SECTION:gstplay-visualization
24 * @title: GstPlayVisualization
25 * @short_description: Play Visualization
26 *
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "gstplay-visualization.h"
34
35 #include <string.h>
36
37 static GMutex vis_lock;
38 static GQueue vis_list = G_QUEUE_INIT;
39 static guint32 vis_cookie;
40
41 G_DEFINE_BOXED_TYPE (GstPlayVisualization, gst_play_visualization,
42 (GBoxedCopyFunc) gst_play_visualization_copy,
43 (GBoxedFreeFunc) gst_play_visualization_free);
44
45 /**
46 * gst_play_visualization_free:
47 * @vis: #GstPlayVisualization instance
48 *
49 * Frees a #GstPlayVisualization.
50 * Since: 1.20
51 */
52 void
gst_play_visualization_free(GstPlayVisualization * vis)53 gst_play_visualization_free (GstPlayVisualization * vis)
54 {
55 g_return_if_fail (vis != NULL);
56
57 g_free (vis->name);
58 g_free (vis->description);
59 g_free (vis);
60 }
61
62 /**
63 * gst_play_visualization_copy:
64 * @vis: #GstPlayVisualization instance
65 *
66 * Makes a copy of the #GstPlayVisualization. The result must be
67 * freed using gst_play_visualization_free().
68 *
69 * Returns: (transfer full): an allocated copy of @vis.
70 * Since: 1.20
71 */
72 GstPlayVisualization *
gst_play_visualization_copy(const GstPlayVisualization * vis)73 gst_play_visualization_copy (const GstPlayVisualization * vis)
74 {
75 GstPlayVisualization *ret;
76
77 g_return_val_if_fail (vis != NULL, NULL);
78
79 ret = g_new0 (GstPlayVisualization, 1);
80 ret->name = vis->name ? g_strdup (vis->name) : NULL;
81 ret->description = vis->description ? g_strdup (vis->description) : NULL;
82
83 return ret;
84 }
85
86 /**
87 * gst_play_visualizations_free:
88 * @viss: a %NULL terminated array of #GstPlayVisualization to free
89 *
90 * Frees a %NULL terminated array of #GstPlayVisualization.
91 * Since: 1.20
92 */
93 void
gst_play_visualizations_free(GstPlayVisualization ** viss)94 gst_play_visualizations_free (GstPlayVisualization ** viss)
95 {
96 GstPlayVisualization **p;
97
98 g_return_if_fail (viss != NULL);
99
100 p = viss;
101 while (*p) {
102 g_free ((*p)->name);
103 g_free ((*p)->description);
104 g_free (*p);
105 p++;
106 }
107 g_free (viss);
108 }
109
110 static void
gst_play_update_visualization_list(void)111 gst_play_update_visualization_list (void)
112 {
113 GList *features;
114 GList *l;
115 guint32 cookie;
116 GstPlayVisualization *vis;
117
118 g_mutex_lock (&vis_lock);
119
120 /* check if we need to update the list */
121 cookie = gst_registry_get_feature_list_cookie (gst_registry_get ());
122 if (vis_cookie == cookie) {
123 g_mutex_unlock (&vis_lock);
124 return;
125 }
126
127 /* if update is needed then first free the existing list */
128 while ((vis = g_queue_pop_head (&vis_list)))
129 gst_play_visualization_free (vis);
130
131 features = gst_registry_get_feature_list (gst_registry_get (),
132 GST_TYPE_ELEMENT_FACTORY);
133
134 for (l = features; l; l = l->next) {
135 GstPluginFeature *feature = l->data;
136 const gchar *klass;
137
138 klass = gst_element_factory_get_metadata (GST_ELEMENT_FACTORY (feature),
139 GST_ELEMENT_METADATA_KLASS);
140
141 if (strstr (klass, "Visualization")) {
142 vis = g_new0 (GstPlayVisualization, 1);
143
144 vis->name = g_strdup (gst_plugin_feature_get_name (feature));
145 vis->description =
146 g_strdup (gst_element_factory_get_metadata (GST_ELEMENT_FACTORY
147 (feature), GST_ELEMENT_METADATA_DESCRIPTION));
148 g_queue_push_tail (&vis_list, vis);
149 }
150 }
151 gst_plugin_feature_list_free (features);
152
153 vis_cookie = cookie;
154
155 g_mutex_unlock (&vis_lock);
156 }
157
158 /**
159 * gst_play_visualizations_get:
160 *
161 * Returns: (transfer full) (array zero-terminated=1) (element-type GstPlayVisualization):
162 * a %NULL terminated array containing all available
163 * visualizations. Use gst_play_visualizations_free() after
164 * usage.
165 * Since: 1.20
166 */
167 GstPlayVisualization **
gst_play_visualizations_get(void)168 gst_play_visualizations_get (void)
169 {
170 gint i = 0;
171 GList *l;
172 GstPlayVisualization **ret;
173
174 gst_play_update_visualization_list ();
175
176 g_mutex_lock (&vis_lock);
177 ret = g_new0 (GstPlayVisualization *, g_queue_get_length (&vis_list) + 1);
178 for (l = vis_list.head; l; l = l->next)
179 ret[i++] = gst_play_visualization_copy (l->data);
180 g_mutex_unlock (&vis_lock);
181
182 return ret;
183 }
184