blob: 79976a7b2e71ec4e33dd4eccc76f9193b8c0b7e4 [file] [log] [blame]
/* GStreamer
*
* Copyright (C) 2014-2015 Sebastian Dröge <sebastian@centricular.com>
* Copyright (C) 2015 Brijesh Singh <brijesh.ksingh@gmail.com>
*
* 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.
*/
/**
* SECTION:gstplayer-visualization
* @short_description: Player Visualization
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstplayer-visualization.h"
#include <string.h>
static GMutex vis_lock;
static GQueue vis_list = G_QUEUE_INIT;
static guint32 vis_cookie;
G_DEFINE_BOXED_TYPE (GstPlayerVisualization, gst_player_visualization,
(GBoxedCopyFunc) gst_player_visualization_copy,
(GBoxedFreeFunc) gst_player_visualization_free);
/**
* gst_player_visualization_free:
* @vis: #GstPlayerVisualization instance
*
* Frees a #GstPlayerVisualization.
*/
void
gst_player_visualization_free (GstPlayerVisualization * vis)
{
g_return_if_fail (vis != NULL);
g_free (vis->name);
g_free (vis->description);
g_free (vis);
}
/**
* gst_player_visualization_copy:
* @vis: #GstPlayerVisualization instance
*
* Makes a copy of the #GstPlayerVisualization. The result must be
* freed using gst_player_visualization_free().
*
* Returns: (transfer full): an allocated copy of @vis.
*/
GstPlayerVisualization *
gst_player_visualization_copy (const GstPlayerVisualization * vis)
{
GstPlayerVisualization *ret;
g_return_val_if_fail (vis != NULL, NULL);
ret = g_new0 (GstPlayerVisualization, 1);
ret->name = vis->name ? g_strdup (vis->name) : NULL;
ret->description = vis->description ? g_strdup (vis->description) : NULL;
return ret;
}
/**
* gst_player_visualizations_free:
* @viss: a %NULL terminated array of #GstPlayerVisualization to free
*
* Frees a %NULL terminated array of #GstPlayerVisualization.
*/
void
gst_player_visualizations_free (GstPlayerVisualization ** viss)
{
GstPlayerVisualization **p;
g_return_if_fail (viss != NULL);
p = viss;
while (*p) {
g_free ((*p)->name);
g_free ((*p)->description);
g_free (*p);
p++;
}
g_free (viss);
}
static void
gst_player_update_visualization_list (void)
{
GList *features;
GList *l;
guint32 cookie;
GstPlayerVisualization *vis;
g_mutex_lock (&vis_lock);
/* check if we need to update the list */
cookie = gst_registry_get_feature_list_cookie (gst_registry_get ());
if (vis_cookie == cookie) {
g_mutex_unlock (&vis_lock);
return;
}
/* if update is needed then first free the existing list */
while ((vis = g_queue_pop_head (&vis_list)))
gst_player_visualization_free (vis);
features = gst_registry_get_feature_list (gst_registry_get (),
GST_TYPE_ELEMENT_FACTORY);
for (l = features; l; l = l->next) {
GstPluginFeature *feature = l->data;
const gchar *klass;
klass = gst_element_factory_get_metadata (GST_ELEMENT_FACTORY (feature),
GST_ELEMENT_METADATA_KLASS);
if (strstr (klass, "Visualization")) {
vis = g_new0 (GstPlayerVisualization, 1);
vis->name = g_strdup (gst_plugin_feature_get_name (feature));
vis->description =
g_strdup (gst_element_factory_get_metadata (GST_ELEMENT_FACTORY
(feature), GST_ELEMENT_METADATA_DESCRIPTION));
g_queue_push_tail (&vis_list, vis);
}
}
gst_plugin_feature_list_free (features);
vis_cookie = cookie;
g_mutex_unlock (&vis_lock);
}
/**
* gst_player_visualizations_get:
*
* Returns: (transfer full) (array zero-terminated=1) (element-type GstPlayerVisualization):
* a %NULL terminated array containing all available
* visualizations. Use gst_player_visualizations_free() after
* usage.
*/
GstPlayerVisualization **
gst_player_visualizations_get (void)
{
gint i = 0;
GList *l;
GstPlayerVisualization **ret;
gst_player_update_visualization_list ();
g_mutex_lock (&vis_lock);
ret = g_new0 (GstPlayerVisualization *, g_queue_get_length (&vis_list) + 1);
for (l = vis_list.head; l; l = l->next)
ret[i++] = gst_player_visualization_copy (l->data);
g_mutex_unlock (&vis_lock);
return ret;
}