• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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