mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
devicemonitor: Add GstDeviceMonitor and related
Also add GstDevice and GstDeviceMonitorFactory And add code to the registry to save them https://bugzilla.gnome.org/show_bug.cgi?id=678402
This commit is contained in:
parent
10d53423b5
commit
e4e85fc88a
18 changed files with 1978 additions and 7 deletions
|
@ -71,6 +71,9 @@ libgstreamer_@GST_API_VERSION@_la_SOURCES = \
|
|||
gstcontrolsource.c \
|
||||
gstdatetime.c \
|
||||
gstdebugutils.c \
|
||||
gstdevice.c \
|
||||
gstdevicemonitor.c \
|
||||
gstdevicemonitorfactory.c \
|
||||
gstelement.c \
|
||||
gstelementfactory.c \
|
||||
gsterror.c \
|
||||
|
@ -172,6 +175,9 @@ gst_headers = \
|
|||
gstdebugutils.h \
|
||||
gstelement.h \
|
||||
gstelementmetadata.h \
|
||||
gstdevice.h \
|
||||
gstdevicemonitor.h \
|
||||
gstdevicemonitorfactory.h \
|
||||
gstelementfactory.h \
|
||||
gsterror.h \
|
||||
gstevent.h \
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include <gst/gstcontrolsource.h>
|
||||
#include <gst/gstdatetime.h>
|
||||
#include <gst/gstdebugutils.h>
|
||||
#include <gst/gstdevice.h>
|
||||
#include <gst/gstdevicemonitor.h>
|
||||
#include <gst/gstelement.h>
|
||||
#include <gst/gstelementmetadata.h>
|
||||
#include <gst/gsterror.h>
|
||||
|
|
|
@ -54,6 +54,9 @@ extern const char g_log_domain_gstreamer[];
|
|||
/* for GstElement */
|
||||
#include "gstelement.h"
|
||||
|
||||
/* for GstDeviceMonitor */
|
||||
#include "gstdevicemonitor.h"
|
||||
|
||||
/* for GstToc */
|
||||
#include "gsttoc.h"
|
||||
|
||||
|
@ -393,5 +396,24 @@ struct _GstElementFactoryClass {
|
|||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstDeviceMonitorFactory {
|
||||
GstPluginFeature feature;
|
||||
/* <private> */
|
||||
|
||||
GType type; /* unique GType the device factory or 0 if not loaded */
|
||||
|
||||
volatile GstDeviceMonitor *monitor;
|
||||
gpointer metadata;
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstDeviceMonitorFactoryClass {
|
||||
GstPluginFeatureClass parent;
|
||||
/* <private> */
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
G_END_DECLS
|
||||
#endif /* __GST_PRIVATE_H__ */
|
||||
|
|
231
gst/gstdevice.c
Normal file
231
gst/gstdevice.c
Normal file
|
@ -0,0 +1,231 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
|
||||
*
|
||||
* gstdevice.c: Device discovery
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gst/gst_private.h"
|
||||
|
||||
#include <gst/gstdevice.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_DISPLAY_NAME = 1,
|
||||
PROP_CAPS
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
REMOVED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
struct _GstDevicePrivate
|
||||
{
|
||||
GstCaps *caps;
|
||||
gchar *display_name;
|
||||
};
|
||||
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GstDevice, gst_device, GST_TYPE_OBJECT);
|
||||
|
||||
static void gst_device_get_property (GObject * object, guint property_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
static void gst_device_set_property (GObject * object, guint property_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_device_finalize (GObject * object);
|
||||
|
||||
|
||||
static void
|
||||
gst_device_class_init (GstDeviceClass * klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstDevicePrivate));
|
||||
|
||||
object_class->get_property = gst_device_get_property;
|
||||
object_class->set_property = gst_device_set_property;
|
||||
object_class->finalize = gst_device_finalize;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_DISPLAY_NAME,
|
||||
g_param_spec_string ("display-name", "Display Name",
|
||||
"The user-friendly name of the device", "",
|
||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
g_object_class_install_property (object_class, PROP_CAPS,
|
||||
g_param_spec_boxed ("caps", "Device Caps",
|
||||
"The possible caps of a device", GST_TYPE_CAPS,
|
||||
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
signals[REMOVED] = g_signal_new ("removed", G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_device_init (GstDevice * device)
|
||||
{
|
||||
device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device, GST_TYPE_DEVICE,
|
||||
GstDevicePrivate);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_device_finalize (GObject * object)
|
||||
{
|
||||
GstDevice *device = GST_DEVICE (object);
|
||||
|
||||
gst_caps_replace (&device->priv->caps, NULL);
|
||||
|
||||
g_free (device->priv->display_name);
|
||||
|
||||
G_OBJECT_CLASS (gst_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_device_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstDevice *gstdevice;
|
||||
|
||||
gstdevice = GST_DEVICE_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DISPLAY_NAME:
|
||||
g_value_take_string (value, gst_device_get_display_name (gstdevice));
|
||||
break;
|
||||
case PROP_CAPS:
|
||||
if (gstdevice->priv->caps)
|
||||
g_value_take_boxed (value, gst_device_get_caps (gstdevice));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gst_device_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstDevice *gstdevice;
|
||||
|
||||
gstdevice = GST_DEVICE_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_DISPLAY_NAME:
|
||||
gstdevice->priv->display_name = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_CAPS:
|
||||
gst_caps_replace (&gstdevice->priv->caps, g_value_get_boxed (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_create_element:
|
||||
* @device: a #GstDevice
|
||||
* @name: (allow-none): name of new element, or NULL to automatically
|
||||
* create a unique name.
|
||||
*
|
||||
* Returns: (transfer full): a new #GstElement configured to use this device
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GstElement *
|
||||
gst_device_create_element (GstDevice * device, const gchar * name)
|
||||
{
|
||||
GstDeviceClass *klass = GST_DEVICE_GET_CLASS (device);
|
||||
|
||||
if (klass->create_element)
|
||||
return klass->create_element (device, name);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_get_caps:
|
||||
* @device: a #GstDevice
|
||||
*
|
||||
* Getter for the #GstCaps that this device supports.
|
||||
*
|
||||
* Returns: The #GstCaps supported by this device. Unref with
|
||||
* gst_caps_unref() when done.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GstCaps *
|
||||
gst_device_get_caps (GstDevice * device)
|
||||
{
|
||||
if (device->priv->caps)
|
||||
return gst_caps_ref (device->priv->caps);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_get_display_name:
|
||||
* @device: a #GstDevice
|
||||
*
|
||||
* Gets the user-friendly name of the device.
|
||||
*
|
||||
* Returns: The device name. Free with g_free() after use.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gchar *
|
||||
gst_device_get_display_name (GstDevice * device)
|
||||
{
|
||||
return g_strdup (device->priv->display_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_reconfigure_element:
|
||||
* @device: a #GstDevice
|
||||
* @element: a #GstElement
|
||||
*
|
||||
* Tries to reconfigure an existing element to use the device. If this
|
||||
* function fails, then one must destroy the element and create a new one
|
||||
* using gst_device_create_element().
|
||||
*
|
||||
* Note: This should only be implemented for elements can change their
|
||||
* device in the PLAYING state.
|
||||
*
|
||||
* Returns: %TRUE if the element could be reconfigured to use this device,
|
||||
* %FALSE otherwise.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gboolean
|
||||
gst_device_reconfigure_element (GstDevice * device, GstElement * element)
|
||||
{
|
||||
GstDeviceClass *klass = GST_DEVICE_GET_CLASS (device);
|
||||
|
||||
if (klass->reconfigure_element)
|
||||
return klass->reconfigure_element (device, element);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
76
gst/gstdevice.h
Normal file
76
gst/gstdevice.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
|
||||
*
|
||||
* gstdevice.c: Device discovery
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GST_DEVICE_H__
|
||||
#define __GST_DEVICE_H__
|
||||
|
||||
typedef struct _GstDevice GstDevice;
|
||||
typedef struct _GstDeviceClass GstDeviceClass;
|
||||
|
||||
#include <gst/gstelement.h>
|
||||
#include <gst/gstcaps.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstDevicePrivate GstDevicePrivate;
|
||||
|
||||
#define GST_TYPE_DEVICE (gst_device_get_type())
|
||||
#define GST_IS_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEVICE))
|
||||
#define GST_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEVICE))
|
||||
#define GST_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEVICE, GstDeviceClass))
|
||||
#define GST_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEVICE, GstDevice))
|
||||
#define GST_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE, GstDeviceClass))
|
||||
#define GST_DEVICE_CAST(obj) ((GstDevice *)(obj))
|
||||
|
||||
|
||||
struct _GstDevice {
|
||||
GstObject parent;
|
||||
|
||||
/*< private >*/
|
||||
GstDevicePrivate *priv;
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstDeviceClass {
|
||||
GstObjectClass parent_class;
|
||||
|
||||
GstElement * (*create_element) (GstDevice * device, const gchar * name);
|
||||
gboolean (*reconfigure_element) (GstDevice * device, GstElement * element);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_device_get_type (void);
|
||||
|
||||
GstElement * gst_device_create_element (GstDevice * device, const gchar * name);
|
||||
|
||||
GstCaps * gst_device_get_caps (GstDevice * device);
|
||||
gchar * gst_device_get_display_name (GstDevice * device);
|
||||
gboolean gst_device_reconfigure_element (GstDevice * device,
|
||||
GstElement * element);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_DEVICE_H__ */
|
570
gst/gstdevicemonitor.c
Normal file
570
gst/gstdevicemonitor.c
Normal file
|
@ -0,0 +1,570 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
|
||||
*
|
||||
* gstdevicemonitor.c: Device probing and monitoring
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <gst/gstdevicemonitor.h>
|
||||
|
||||
#include "gst/gst_private.h"
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <gst/gstelementmetadata.h>
|
||||
#include <gst/gstquark.h>
|
||||
|
||||
struct _GstDeviceMonitorPrivate
|
||||
{
|
||||
GstBus *bus;
|
||||
|
||||
GMutex start_lock;
|
||||
|
||||
gboolean started_count;
|
||||
};
|
||||
|
||||
/* this is used in gstelementfactory.c:gst_element_register() */
|
||||
GQuark __gst_devicemonitorclass_factory = 0;
|
||||
|
||||
static void gst_device_monitor_class_init (GstDeviceMonitorClass * klass);
|
||||
static void gst_device_monitor_init (GstDeviceMonitor * element);
|
||||
static void gst_device_monitor_base_class_init (gpointer g_class);
|
||||
static void gst_device_monitor_base_class_finalize (gpointer g_class);
|
||||
static void gst_device_monitor_dispose (GObject * object);
|
||||
static void gst_device_monitor_finalize (GObject * object);
|
||||
|
||||
static gpointer gst_device_monitor_parent_class = NULL;
|
||||
|
||||
GType
|
||||
gst_device_monitor_get_type (void)
|
||||
{
|
||||
static volatile gsize gst_device_monitor_type = 0;
|
||||
|
||||
if (g_once_init_enter (&gst_device_monitor_type)) {
|
||||
GType _type;
|
||||
static const GTypeInfo element_info = {
|
||||
sizeof (GstDeviceMonitorClass),
|
||||
gst_device_monitor_base_class_init,
|
||||
gst_device_monitor_base_class_finalize,
|
||||
(GClassInitFunc) gst_device_monitor_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof (GstDeviceMonitor),
|
||||
0,
|
||||
(GInstanceInitFunc) gst_device_monitor_init,
|
||||
NULL
|
||||
};
|
||||
|
||||
_type = g_type_register_static (GST_TYPE_OBJECT, "GstDeviceMonitor",
|
||||
&element_info, G_TYPE_FLAG_ABSTRACT);
|
||||
|
||||
__gst_devicemonitorclass_factory =
|
||||
g_quark_from_static_string ("GST_DEVICEMONITORCLASS_FACTORY");
|
||||
g_once_init_leave (&gst_device_monitor_type, _type);
|
||||
}
|
||||
return gst_device_monitor_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_device_monitor_base_class_init (gpointer g_class)
|
||||
{
|
||||
GstDeviceMonitorClass *klass = GST_DEVICE_MONITOR_CLASS (g_class);
|
||||
|
||||
/* Copy the element details here so elements can inherit the
|
||||
* details from their base class and classes only need to set
|
||||
* the details in class_init instead of base_init */
|
||||
klass->metadata =
|
||||
klass->metadata ? gst_structure_copy (klass->metadata) :
|
||||
gst_structure_new_empty ("metadata");
|
||||
|
||||
klass->factory = g_type_get_qdata (G_TYPE_FROM_CLASS (klass),
|
||||
__gst_devicemonitorclass_factory);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_device_monitor_base_class_finalize (gpointer g_class)
|
||||
{
|
||||
GstDeviceMonitorClass *klass = GST_DEVICE_MONITOR_CLASS (g_class);
|
||||
|
||||
gst_structure_free (klass->metadata);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_device_monitor_class_init (GstDeviceMonitorClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
gst_device_monitor_parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GstDeviceMonitorPrivate));
|
||||
|
||||
gobject_class->dispose = gst_device_monitor_dispose;
|
||||
gobject_class->finalize = gst_device_monitor_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_device_monitor_init (GstDeviceMonitor * monitor)
|
||||
{
|
||||
monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor,
|
||||
GST_TYPE_DEVICE_MONITOR, GstDeviceMonitorPrivate);
|
||||
|
||||
g_mutex_init (&monitor->priv->start_lock);
|
||||
|
||||
monitor->priv->bus = gst_bus_new ();
|
||||
gst_bus_set_flushing (monitor->priv->bus, TRUE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gst_device_monitor_dispose (GObject * object)
|
||||
{
|
||||
GstDeviceMonitor *monitor = GST_DEVICE_MONITOR (object);
|
||||
|
||||
gst_object_replace ((GstObject **) & monitor->priv->bus, NULL);
|
||||
|
||||
GST_OBJECT_LOCK (monitor);
|
||||
g_list_free_full (monitor->devices, (GDestroyNotify) gst_object_unparent);
|
||||
monitor->devices = NULL;
|
||||
GST_OBJECT_UNLOCK (monitor);
|
||||
|
||||
G_OBJECT_CLASS (gst_device_monitor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_device_monitor_finalize (GObject * object)
|
||||
{
|
||||
GstDeviceMonitor *monitor = GST_DEVICE_MONITOR (object);
|
||||
|
||||
g_mutex_clear (&monitor->priv->start_lock);
|
||||
|
||||
G_OBJECT_CLASS (gst_device_monitor_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_class_add_metadata:
|
||||
* @klass: class to set metadata for
|
||||
* @key: the key to set
|
||||
* @value: the value to set
|
||||
*
|
||||
* Set @key with @value as metadata in @klass.
|
||||
*/
|
||||
void
|
||||
gst_device_monitor_class_add_metadata (GstDeviceMonitorClass * klass,
|
||||
const gchar * key, const gchar * value)
|
||||
{
|
||||
g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
|
||||
g_return_if_fail (key != NULL);
|
||||
g_return_if_fail (value != NULL);
|
||||
|
||||
gst_structure_set ((GstStructure *) klass->metadata,
|
||||
key, G_TYPE_STRING, value, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_class_add_static_metadata:
|
||||
* @klass: class to set metadata for
|
||||
* @key: the key to set
|
||||
* @value: the value to set
|
||||
*
|
||||
* Set @key with @value as metadata in @klass.
|
||||
*
|
||||
* Same as gst_device_monitor_class_add_metadata(), but @value must be a static string
|
||||
* or an inlined string, as it will not be copied. (GStreamer plugins will
|
||||
* be made resident once loaded, so this function can be used even from
|
||||
* dynamically loaded plugins.)
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
gst_device_monitor_class_add_static_metadata (GstDeviceMonitorClass * klass,
|
||||
const gchar * key, const gchar * value)
|
||||
{
|
||||
GValue val = G_VALUE_INIT;
|
||||
|
||||
g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
|
||||
g_return_if_fail (key != NULL);
|
||||
g_return_if_fail (value != NULL);
|
||||
|
||||
g_value_init (&val, G_TYPE_STRING);
|
||||
g_value_set_static_string (&val, value);
|
||||
gst_structure_take_value ((GstStructure *) klass->metadata, key, &val);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_class_set_metadata:
|
||||
* @klass: class to set metadata for
|
||||
* @longname: The long English name of the device monitor. E.g. "File Sink"
|
||||
* @classification: String describing the type of device monitor, as an unordered list
|
||||
* separated with slashes ('/'). See draft-klass.txt of the design docs
|
||||
* for more details and common types. E.g: "Sink/File"
|
||||
* @description: Sentence describing the purpose of the device monitor.
|
||||
* E.g: "Write stream to a file"
|
||||
* @author: Name and contact details of the author(s). Use \n to separate
|
||||
* multiple author metadata. E.g: "Joe Bloggs <joe.blogs at foo.com>"
|
||||
*
|
||||
* Sets the detailed information for a #GstDeviceMonitorClass.
|
||||
* <note>This function is for use in _class_init functions only.</note>
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
gst_device_monitor_class_set_metadata (GstDeviceMonitorClass * klass,
|
||||
const gchar * longname, const gchar * classification,
|
||||
const gchar * description, const gchar * author)
|
||||
{
|
||||
g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
|
||||
g_return_if_fail (longname != NULL && *longname != '\0');
|
||||
g_return_if_fail (classification != NULL && *classification != '\0');
|
||||
g_return_if_fail (description != NULL && *description != '\0');
|
||||
g_return_if_fail (author != NULL && *author != '\0');
|
||||
|
||||
gst_structure_id_set ((GstStructure *) klass->metadata,
|
||||
GST_QUARK (ELEMENT_METADATA_LONGNAME), G_TYPE_STRING, longname,
|
||||
GST_QUARK (ELEMENT_METADATA_KLASS), G_TYPE_STRING, classification,
|
||||
GST_QUARK (ELEMENT_METADATA_DESCRIPTION), G_TYPE_STRING, description,
|
||||
GST_QUARK (ELEMENT_METADATA_AUTHOR), G_TYPE_STRING, author, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_class_set_static_metadata:
|
||||
* @klass: class to set metadata for
|
||||
* @longname: The long English name of the element. E.g. "File Sink"
|
||||
* @classification: String describing the type of element, as an unordered list
|
||||
* separated with slashes ('/'). See draft-klass.txt of the design docs
|
||||
* for more details and common types. E.g: "Sink/File"
|
||||
* @description: Sentence describing the purpose of the element.
|
||||
* E.g: "Write stream to a file"
|
||||
* @author: Name and contact details of the author(s). Use \n to separate
|
||||
* multiple author metadata. E.g: "Joe Bloggs <joe.blogs at foo.com>"
|
||||
*
|
||||
* Sets the detailed information for a #GstDeviceMonitorClass.
|
||||
* <note>This function is for use in _class_init functions only.</note>
|
||||
*
|
||||
* Same as gst_device_monitor_class_set_metadata(), but @longname, @classification,
|
||||
* @description, and @author must be static strings or inlined strings, as
|
||||
* they will not be copied. (GStreamer plugins will be made resident once
|
||||
* loaded, so this function can be used even from dynamically loaded plugins.)
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
gst_device_monitor_class_set_static_metadata (GstDeviceMonitorClass * klass,
|
||||
const gchar * longname, const gchar * classification,
|
||||
const gchar * description, const gchar * author)
|
||||
{
|
||||
GstStructure *s = (GstStructure *) klass->metadata;
|
||||
GValue val = G_VALUE_INIT;
|
||||
|
||||
g_return_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass));
|
||||
g_return_if_fail (longname != NULL && *longname != '\0');
|
||||
g_return_if_fail (classification != NULL && *classification != '\0');
|
||||
g_return_if_fail (description != NULL && *description != '\0');
|
||||
g_return_if_fail (author != NULL && *author != '\0');
|
||||
|
||||
g_value_init (&val, G_TYPE_STRING);
|
||||
|
||||
g_value_set_static_string (&val, longname);
|
||||
gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_LONGNAME), &val);
|
||||
|
||||
g_value_set_static_string (&val, classification);
|
||||
gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_KLASS), &val);
|
||||
|
||||
g_value_set_static_string (&val, description);
|
||||
gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_DESCRIPTION),
|
||||
&val);
|
||||
|
||||
g_value_set_static_string (&val, author);
|
||||
gst_structure_id_take_value (s, GST_QUARK (ELEMENT_METADATA_AUTHOR), &val);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_class_get_metadata:
|
||||
* @klass: class to get metadata for
|
||||
* @key: the key to get
|
||||
*
|
||||
* Get metadata with @key in @klass.
|
||||
*
|
||||
* Returns: the metadata for @key.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
const gchar *
|
||||
gst_device_monitor_class_get_metadata (GstDeviceMonitorClass * klass,
|
||||
const gchar * key)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_DEVICE_MONITOR_CLASS (klass), NULL);
|
||||
g_return_val_if_fail (key != NULL, NULL);
|
||||
|
||||
return gst_structure_get_string ((GstStructure *) klass->metadata, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_get_devices:
|
||||
* @monitor: A #GstDeviceMonitor
|
||||
*
|
||||
* Gets a list of devices that this monitor understands. This may actually
|
||||
* probe the hardware if the monitor is not currently started.
|
||||
*
|
||||
* Returns: (transfer full) (element-type GstDevice): a #GList of
|
||||
* #GstDevice
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
|
||||
GList *
|
||||
gst_device_monitor_get_devices (GstDeviceMonitor * monitor)
|
||||
{
|
||||
GstDeviceMonitorClass *klass;
|
||||
GList *devices = NULL;
|
||||
gboolean started;
|
||||
GList *item;
|
||||
|
||||
g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL);
|
||||
klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
|
||||
|
||||
g_mutex_lock (&monitor->priv->start_lock);
|
||||
started = (monitor->priv->started_count > 0);
|
||||
|
||||
if (started) {
|
||||
GST_OBJECT_LOCK (monitor);
|
||||
for (item = monitor->devices; item; item = item->next)
|
||||
devices = g_list_prepend (devices, gst_object_ref (item->data));
|
||||
GST_OBJECT_UNLOCK (monitor);
|
||||
} else if (klass->probe)
|
||||
devices = klass->probe (monitor);
|
||||
|
||||
g_mutex_unlock (&monitor->priv->start_lock);
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_start:
|
||||
* @monitor: A #GstDeviceMonitor
|
||||
*
|
||||
* Starts monitoring the devices. This will cause #GST_MESSAGE_DEVICE messages
|
||||
* to be posted on the monitor's bus when devices are added or removed from
|
||||
* the system.
|
||||
*
|
||||
* Since the #GstDeviceMonitor is a singleton,
|
||||
* gst_device_monitor_start() may already have been called by another
|
||||
* user of the object, gst_device_monitor_stop() needs to be called the same
|
||||
* number of times.
|
||||
*
|
||||
* Returns: %TRUE if the device monitoring could be started
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
|
||||
gboolean
|
||||
gst_device_monitor_start (GstDeviceMonitor * monitor)
|
||||
{
|
||||
GstDeviceMonitorClass *klass;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE);
|
||||
klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
|
||||
|
||||
g_mutex_lock (&monitor->priv->start_lock);
|
||||
|
||||
if (monitor->priv->started_count > 0) {
|
||||
ret = TRUE;
|
||||
goto started;
|
||||
}
|
||||
|
||||
if (klass->start)
|
||||
ret = klass->start (monitor);
|
||||
|
||||
if (ret) {
|
||||
monitor->priv->started_count++;
|
||||
gst_bus_set_flushing (monitor->priv->bus, FALSE);
|
||||
}
|
||||
|
||||
started:
|
||||
|
||||
g_mutex_unlock (&monitor->priv->start_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_stop:
|
||||
* @monitor: A #GstDeviceMonitor
|
||||
*
|
||||
* Decreases the use-count by one. If the use count reaches zero, this
|
||||
* #GstDeviceMonitor will stop monitoring the devices. This needs to be
|
||||
* called the same number of times that gst_device_monitor_start() was called.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
|
||||
void
|
||||
gst_device_monitor_stop (GstDeviceMonitor * monitor)
|
||||
{
|
||||
GstDeviceMonitorClass *klass;
|
||||
|
||||
g_return_if_fail (GST_IS_DEVICE_MONITOR (monitor));
|
||||
klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
|
||||
|
||||
g_mutex_lock (&monitor->priv->start_lock);
|
||||
|
||||
if (monitor->priv->started_count == 1) {
|
||||
gst_bus_set_flushing (monitor->priv->bus, TRUE);
|
||||
if (klass->stop)
|
||||
klass->stop (monitor);
|
||||
GST_OBJECT_LOCK (monitor);
|
||||
g_list_free_full (monitor->devices, (GDestroyNotify) gst_object_unparent);
|
||||
monitor->devices = NULL;
|
||||
GST_OBJECT_UNLOCK (monitor);
|
||||
} else if (monitor->priv->started_count < 1) {
|
||||
g_critical ("Trying to stop a GstDeviceMonitor %s which is already stopped",
|
||||
GST_OBJECT_NAME (monitor));
|
||||
}
|
||||
|
||||
monitor->priv->started_count--;
|
||||
g_mutex_unlock (&monitor->priv->start_lock);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gst_device_monitor_get_factory:
|
||||
* @monitor: a #GstDeviceMonitor to request the device monitor factory of.
|
||||
*
|
||||
* Retrieves the factory that was used to create this device monitor.
|
||||
*
|
||||
* Returns: (transfer none): the #GstDeviceMonitorFactory used for creating this
|
||||
* device monitor. no refcounting is needed.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GstDeviceMonitorFactory *
|
||||
gst_device_monitor_get_factory (GstDeviceMonitor * monitor)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL);
|
||||
|
||||
return GST_DEVICE_MONITOR_GET_CLASS (monitor)->factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_can_monitor:
|
||||
* @monitor: a #GstDeviceMonitor
|
||||
*
|
||||
* If this function returns %TRUE, then the device monitor can monitor if
|
||||
* devices are added or removed. Otherwise, it can only do static probing.
|
||||
*
|
||||
* Returns: %TRUE if the #GstDeviceMonitor support monitoring, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
gst_device_monitor_can_monitor (GstDeviceMonitor * monitor)
|
||||
{
|
||||
GstDeviceMonitorClass *klass;
|
||||
|
||||
g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE);
|
||||
klass = GST_DEVICE_MONITOR_GET_CLASS (monitor);
|
||||
|
||||
if (klass->start)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_get_bus:
|
||||
* @monitor: a #GstDeviceMonitor
|
||||
*
|
||||
* Gets the #GstBus of this #GstDeviceMonitor
|
||||
*
|
||||
* Returns: (transfer full): a #GstBus
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GstBus *
|
||||
gst_device_monitor_get_bus (GstDeviceMonitor * monitor)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), NULL);
|
||||
|
||||
return gst_object_ref (monitor->priv->bus);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_device_add:
|
||||
* @monitor: a #GstDeviceMonitor
|
||||
* @device: (transfer full): a #GstDevice that has been added
|
||||
*
|
||||
* Posts a message on the monitor's #GstBus to inform applications that
|
||||
* a new device has been added.
|
||||
*
|
||||
* This is for use by subclasses.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
gst_device_monitor_device_add (GstDeviceMonitor * monitor, GstDevice * device)
|
||||
{
|
||||
GstMessage *message;
|
||||
|
||||
if (!gst_object_set_parent (GST_OBJECT (device), GST_OBJECT (monitor))) {
|
||||
GST_WARNING_OBJECT (monitor, "Could not parent device %p to monitor,"
|
||||
" it already has a parent", device);
|
||||
return;
|
||||
}
|
||||
|
||||
GST_OBJECT_LOCK (monitor);
|
||||
monitor->devices = g_list_prepend (monitor->devices, gst_object_ref (device));
|
||||
GST_OBJECT_UNLOCK (monitor);
|
||||
|
||||
message = gst_message_new_device_added (GST_OBJECT (monitor), device);
|
||||
gst_bus_post (monitor->priv->bus, message);
|
||||
gst_object_unref (device);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gst_device_monitor_device_remove:
|
||||
* @monitor: a #GstDeviceMonitor
|
||||
* @device: a #GstDevice that has been removed
|
||||
*
|
||||
* Posts a message on the monitor's #GstBus to inform applications that
|
||||
* a device has been removed.
|
||||
*
|
||||
* This is for use by subclasses.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
gst_device_monitor_device_remove (GstDeviceMonitor * monitor,
|
||||
GstDevice * device)
|
||||
{
|
||||
GstMessage *message;
|
||||
GList *item;
|
||||
|
||||
GST_OBJECT_LOCK (monitor);
|
||||
item = g_list_find (monitor->devices, device);
|
||||
if (item) {
|
||||
monitor->devices = g_list_delete_link (monitor->devices, item);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (monitor);
|
||||
|
||||
message = gst_message_new_device_removed (GST_OBJECT (monitor), device);
|
||||
g_signal_emit_by_name (device, "removed");
|
||||
gst_bus_post (monitor->priv->bus, message);
|
||||
if (item)
|
||||
gst_object_unparent (GST_OBJECT (device));
|
||||
}
|
130
gst/gstdevicemonitor.h
Normal file
130
gst/gstdevicemonitor.h
Normal file
|
@ -0,0 +1,130 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
|
||||
*
|
||||
* gstdevicemonitor.h: Device probing and monitoring
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <gst/gstdevicemonitorfactory.h>
|
||||
|
||||
|
||||
#ifndef __GST_DEVICE_MONITOR_H__
|
||||
#define __GST_DEVICE_MONITOR_H__
|
||||
|
||||
#include <gst/gstelement.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstDeviceMonitor GstDeviceMonitor;
|
||||
typedef struct _GstDeviceMonitorClass GstDeviceMonitorClass;
|
||||
typedef struct _GstDeviceMonitorPrivate GstDeviceMonitorPrivate;
|
||||
|
||||
#define GST_TYPE_DEVICE_MONITOR (gst_device_monitor_get_type())
|
||||
#define GST_IS_DEVICE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DEVICE_MONITOR))
|
||||
#define GST_IS_DEVICE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DEVICE_MONITOR))
|
||||
#define GST_DEVICE_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_DEVICE_MONITOR, GstDeviceMonitorClass))
|
||||
#define GST_DEVICE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DEVICE_MONITOR, GstDeviceMonitor))
|
||||
#define GST_DEVICE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE_MONITOR, GstDeviceMonitorClass))
|
||||
#define GST_DEVICE_MONITOR_CAST(obj) ((GstDeviceMonitor *)(obj))
|
||||
|
||||
|
||||
struct _GstDeviceMonitor {
|
||||
GstObject parent;
|
||||
|
||||
/*< private >*/
|
||||
|
||||
/* Protected by the Object lock */
|
||||
GList *devices;
|
||||
|
||||
GstDeviceMonitorPrivate *priv;
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
/**
|
||||
* GstDeviceMonitorClass:
|
||||
* @factory: a pointer to the #GstDeviceMonitorFactory that creates this
|
||||
* monitor
|
||||
* @get_devices: Returns a list of devices that are currently available.
|
||||
* This should never block.
|
||||
* @start: Starts monitoring for new devices.
|
||||
* @stop: Stops monitoring for new devices
|
||||
*
|
||||
* The structure of the base #GstDeviceMonitorClass
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
|
||||
struct _GstDeviceMonitorClass {
|
||||
GstObjectClass parent_class;
|
||||
|
||||
GstDeviceMonitorFactory *factory;
|
||||
|
||||
GList* (*probe) (GstDeviceMonitor * monitor);
|
||||
|
||||
gboolean (*start) (GstDeviceMonitor * monitor);
|
||||
void (*stop) (GstDeviceMonitor * monitor);
|
||||
|
||||
|
||||
gpointer metadata;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_device_monitor_get_type (void);
|
||||
|
||||
|
||||
GList * gst_device_monitor_get_devices (GstDeviceMonitor * monitor);
|
||||
|
||||
gboolean gst_device_monitor_start (GstDeviceMonitor * monitor);
|
||||
void gst_device_monitor_stop (GstDeviceMonitor * monitor);
|
||||
|
||||
gboolean gst_device_monitor_can_monitor (GstDeviceMonitor * monitor);
|
||||
|
||||
GstBus * gst_device_monitor_get_bus (GstDeviceMonitor * monitor);
|
||||
|
||||
void gst_device_monitor_device_add (GstDeviceMonitor * monitor,
|
||||
GstDevice * device);
|
||||
void gst_device_monitor_device_remove (GstDeviceMonitor * monitor,
|
||||
GstDevice * device);
|
||||
|
||||
|
||||
/* device monitor class meta data */
|
||||
void gst_device_monitor_class_set_metadata (GstDeviceMonitorClass *klass,
|
||||
const gchar *longname,
|
||||
const gchar *classification,
|
||||
const gchar *description,
|
||||
const gchar *author);
|
||||
void gst_device_monitor_class_set_static_metadata (GstDeviceMonitorClass *klass,
|
||||
const gchar *longname,
|
||||
const gchar *classification,
|
||||
const gchar *description,
|
||||
const gchar *author);
|
||||
void gst_device_monitor_class_add_metadata (GstDeviceMonitorClass * klass,
|
||||
const gchar * key, const gchar * value);
|
||||
void gst_device_monitor_class_add_static_metadata (GstDeviceMonitorClass * klass,
|
||||
const gchar * key, const gchar * value);
|
||||
const gchar * gst_device_monitor_class_get_metadata (GstDeviceMonitorClass * klass,
|
||||
const gchar * key);
|
||||
|
||||
/* factory management */
|
||||
GstDeviceMonitorFactory * gst_device_monitor_get_factory (GstDeviceMonitor * monitor);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_DEVICE_MONITOR_H__ */
|
566
gst/gstdevicemonitorfactory.c
Normal file
566
gst/gstdevicemonitorfactory.c
Normal file
|
@ -0,0 +1,566 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
|
||||
* 2000 Wim Taymans <wtay@chello.be>
|
||||
* 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
||||
*
|
||||
* gstdevicemonitorfactory.c: GstDeviceMonitorFactory object, support routines
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstdevicemonitorfactory
|
||||
* @short_description: Create GstDeviceMonitors from a factory
|
||||
* @see_also: #GstDeviceMonitor, #GstPlugin, #GstPluginFeature, #GstPadTemplate.
|
||||
*
|
||||
* #GstDeviceMonitorFactory is used to create instances of device monitors. A
|
||||
* GstDeviceMonitorfactory can be added to a #GstPlugin as it is also a
|
||||
* #GstPluginFeature.
|
||||
*
|
||||
* Use the gst_device_monitor_factory_find() and gst_device_monitor_factory_create()
|
||||
* functions to create device monitor instances or use gst_device_monitor_factory_make() as a
|
||||
* convenient shortcut.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "gst_private.h"
|
||||
|
||||
#include "gstdevicemonitorfactory.h"
|
||||
#include "gst.h"
|
||||
|
||||
#include "glib-compat-private.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (device_monitor_factory_debug);
|
||||
#define GST_CAT_DEFAULT device_monitor_factory_debug
|
||||
|
||||
static void gst_device_monitor_factory_finalize (GObject * object);
|
||||
static void gst_device_monitor_factory_cleanup (GstDeviceMonitorFactory *
|
||||
factory);
|
||||
|
||||
/* static guint gst_device_monitor_factory_signals[LAST_SIGNAL] = { 0 }; */
|
||||
|
||||
/* this is defined in gstelement.c */
|
||||
extern GQuark __gst_devicemonitorclass_factory;
|
||||
|
||||
#define _do_init \
|
||||
{ \
|
||||
GST_DEBUG_CATEGORY_INIT (device_monitor_factory_debug, "GST_DEVICE_MONITOR_FACTORY", \
|
||||
GST_DEBUG_BOLD | GST_DEBUG_FG_WHITE | GST_DEBUG_BG_RED, \
|
||||
"device monitor factories keep information about installed device monitors"); \
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GstDeviceMonitorFactory, gst_device_monitor_factory,
|
||||
GST_TYPE_PLUGIN_FEATURE, _do_init);
|
||||
|
||||
static void
|
||||
gst_device_monitor_factory_class_init (GstDeviceMonitorFactoryClass * klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
gobject_class->finalize = gst_device_monitor_factory_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_device_monitor_factory_init (GstDeviceMonitorFactory * factory)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gst_device_monitor_factory_finalize (GObject * object)
|
||||
{
|
||||
GstDeviceMonitorFactory *factory = GST_DEVICE_MONITOR_FACTORY (object);
|
||||
GstDeviceMonitor *monitor;
|
||||
|
||||
gst_device_monitor_factory_cleanup (factory);
|
||||
|
||||
monitor = g_atomic_pointer_get (&factory->monitor);
|
||||
if (monitor)
|
||||
gst_object_unref (monitor);
|
||||
|
||||
G_OBJECT_CLASS (gst_device_monitor_factory_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_factory_find:
|
||||
* @name: name of factory to find
|
||||
*
|
||||
* Search for an device monitor factory of the given name. Refs the returned
|
||||
* device monitor factory; caller is responsible for unreffing.
|
||||
*
|
||||
* Returns: (transfer full): #GstDeviceMonitorFactory if found, NULL otherwise
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GstDeviceMonitorFactory *
|
||||
gst_device_monitor_factory_find (const gchar * name)
|
||||
{
|
||||
GstPluginFeature *feature;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
feature = gst_registry_find_feature (gst_registry_get (), name,
|
||||
GST_TYPE_DEVICE_MONITOR_FACTORY);
|
||||
if (feature)
|
||||
return GST_DEVICE_MONITOR_FACTORY (feature);
|
||||
|
||||
/* this isn't an error, for instance when you query if an device monitor factory is
|
||||
* present */
|
||||
GST_LOG ("no such device monitor factory \"%s\"", name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_device_monitor_factory_cleanup (GstDeviceMonitorFactory * factory)
|
||||
{
|
||||
if (factory->metadata) {
|
||||
gst_structure_free ((GstStructure *) factory->metadata);
|
||||
factory->metadata = NULL;
|
||||
}
|
||||
if (factory->type) {
|
||||
factory->type = G_TYPE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
#define CHECK_METADATA_FIELD(klass, name, key) \
|
||||
G_STMT_START { \
|
||||
const gchar *metafield = gst_device_monitor_class_get_metadata (klass, key); \
|
||||
if (G_UNLIKELY (metafield == NULL || *metafield == '\0')) { \
|
||||
g_warning ("Device monitor factory metadata for '%s' has no valid %s field", name, key); \
|
||||
goto detailserror; \
|
||||
} \
|
||||
} G_STMT_END;
|
||||
|
||||
/**
|
||||
* gst_device_monitor_register:
|
||||
* @plugin: (allow-none): #GstPlugin to register the device monitor with, or NULL for
|
||||
* a static device monitor.
|
||||
* @name: name of device monitors of this type
|
||||
* @rank: rank of device monitor (higher rank means more importance when autoplugging)
|
||||
* @type: GType of device monitor to register
|
||||
*
|
||||
* Create a new device monitorfactory capable of instantiating objects of the
|
||||
* @type and add the factory to @plugin.
|
||||
*
|
||||
* Returns: TRUE, if the registering succeeded, FALSE on error
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gboolean
|
||||
gst_device_monitor_register (GstPlugin * plugin, const gchar * name, guint rank,
|
||||
GType type)
|
||||
{
|
||||
GstPluginFeature *existing_feature;
|
||||
GstRegistry *registry;
|
||||
GstDeviceMonitorFactory *factory;
|
||||
GstDeviceMonitorClass *klass;
|
||||
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
g_return_val_if_fail (g_type_is_a (type, GST_TYPE_DEVICE_MONITOR), FALSE);
|
||||
|
||||
registry = gst_registry_get ();
|
||||
|
||||
/* check if feature already exists, if it exists there is no need to update it
|
||||
* when the registry is getting updated, outdated plugins and all their
|
||||
* features are removed and readded.
|
||||
*/
|
||||
existing_feature = gst_registry_lookup_feature (registry, name);
|
||||
if (existing_feature) {
|
||||
GST_DEBUG_OBJECT (registry, "update existing feature %p (%s)",
|
||||
existing_feature, name);
|
||||
factory = GST_DEVICE_MONITOR_FACTORY_CAST (existing_feature);
|
||||
factory->type = type;
|
||||
existing_feature->loaded = TRUE;
|
||||
g_type_set_qdata (type, __gst_devicemonitorclass_factory, factory);
|
||||
gst_object_unref (existing_feature);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
factory =
|
||||
GST_DEVICE_MONITOR_FACTORY_CAST (g_object_newv
|
||||
(GST_TYPE_DEVICE_MONITOR_FACTORY, 0, NULL));
|
||||
gst_plugin_feature_set_name (GST_PLUGIN_FEATURE_CAST (factory), name);
|
||||
GST_LOG_OBJECT (factory, "Created new device monitorfactory for type %s",
|
||||
g_type_name (type));
|
||||
|
||||
/* provide info needed during class structure setup */
|
||||
g_type_set_qdata (type, __gst_devicemonitorclass_factory, factory);
|
||||
klass = GST_DEVICE_MONITOR_CLASS (g_type_class_ref (type));
|
||||
|
||||
CHECK_METADATA_FIELD (klass, name, GST_ELEMENT_METADATA_LONGNAME);
|
||||
CHECK_METADATA_FIELD (klass, name, GST_ELEMENT_METADATA_KLASS);
|
||||
CHECK_METADATA_FIELD (klass, name, GST_ELEMENT_METADATA_DESCRIPTION);
|
||||
CHECK_METADATA_FIELD (klass, name, GST_ELEMENT_METADATA_AUTHOR);
|
||||
|
||||
factory->type = type;
|
||||
factory->metadata = gst_structure_copy ((GstStructure *) klass->metadata);
|
||||
|
||||
if (plugin && plugin->desc.name) {
|
||||
GST_PLUGIN_FEATURE_CAST (factory)->plugin_name = plugin->desc.name;
|
||||
GST_PLUGIN_FEATURE_CAST (factory)->plugin = plugin;
|
||||
g_object_add_weak_pointer ((GObject *) plugin,
|
||||
(gpointer *) & GST_PLUGIN_FEATURE_CAST (factory)->plugin);
|
||||
} else {
|
||||
GST_PLUGIN_FEATURE_CAST (factory)->plugin_name = "NULL";
|
||||
GST_PLUGIN_FEATURE_CAST (factory)->plugin = NULL;
|
||||
}
|
||||
gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE_CAST (factory), rank);
|
||||
GST_PLUGIN_FEATURE_CAST (factory)->loaded = TRUE;
|
||||
|
||||
gst_registry_add_feature (registry, GST_PLUGIN_FEATURE_CAST (factory));
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
detailserror:
|
||||
{
|
||||
gst_device_monitor_factory_cleanup (factory);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_factory_get:
|
||||
* @factory: factory to instantiate
|
||||
*
|
||||
* Returns the device monitor of the type defined by the given device
|
||||
* monitorfactory.
|
||||
*
|
||||
* Returns: (transfer full): the #GstDeviceMonitor or NULL if the
|
||||
* device monitor couldn't be created
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GstDeviceMonitor *
|
||||
gst_device_monitor_factory_get (GstDeviceMonitorFactory * factory)
|
||||
{
|
||||
GstDeviceMonitor *device_monitor;
|
||||
GstDeviceMonitorClass *oclass;
|
||||
GstDeviceMonitorFactory *newfactory;
|
||||
|
||||
g_return_val_if_fail (factory != NULL, NULL);
|
||||
|
||||
newfactory =
|
||||
GST_DEVICE_MONITOR_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
|
||||
(factory)));
|
||||
|
||||
if (newfactory == NULL)
|
||||
goto load_failed;
|
||||
|
||||
factory = newfactory;
|
||||
|
||||
GST_INFO ("getting device monitor \"%s\"", GST_OBJECT_NAME (factory));
|
||||
|
||||
if (factory->type == 0)
|
||||
goto no_type;
|
||||
|
||||
device_monitor = g_atomic_pointer_get (&newfactory->monitor);
|
||||
if (device_monitor)
|
||||
return gst_object_ref (device_monitor);
|
||||
|
||||
/* create an instance of the device monitor, cast so we don't assert on NULL
|
||||
* also set name as early as we can
|
||||
*/
|
||||
device_monitor = GST_DEVICE_MONITOR_CAST (g_object_newv (factory->type, 0,
|
||||
NULL));
|
||||
if (G_UNLIKELY (device_monitor == NULL))
|
||||
goto no_device_monitor;
|
||||
|
||||
/* fill in the pointer to the factory in the device monitor class. The
|
||||
* class will not be unreffed currently.
|
||||
* Be thread safe as there might be 2 threads creating the first instance of
|
||||
* an device monitor at the same moment
|
||||
*/
|
||||
oclass = GST_DEVICE_MONITOR_GET_CLASS (device_monitor);
|
||||
if (!g_atomic_pointer_compare_and_exchange (&oclass->factory, NULL, factory))
|
||||
gst_object_unref (factory);
|
||||
|
||||
gst_object_ref_sink (device_monitor);
|
||||
|
||||
/* We use an atomic to make sure we don't create two in parallel */
|
||||
if (!g_atomic_pointer_compare_and_exchange (&newfactory->monitor, NULL,
|
||||
device_monitor)) {
|
||||
gst_object_unref (device_monitor);
|
||||
|
||||
device_monitor = g_atomic_pointer_get (&newfactory->monitor);
|
||||
}
|
||||
|
||||
GST_DEBUG ("created device monitor \"%s\"", GST_OBJECT_NAME (factory));
|
||||
|
||||
return gst_object_ref (device_monitor);
|
||||
|
||||
/* ERRORS */
|
||||
load_failed:
|
||||
{
|
||||
GST_WARNING_OBJECT (factory,
|
||||
"loading plugin containing feature %s returned NULL!",
|
||||
GST_OBJECT_NAME (factory));
|
||||
return NULL;
|
||||
}
|
||||
no_type:
|
||||
{
|
||||
GST_WARNING_OBJECT (factory, "factory has no type");
|
||||
gst_object_unref (factory);
|
||||
return NULL;
|
||||
}
|
||||
no_device_monitor:
|
||||
{
|
||||
GST_WARNING_OBJECT (factory, "could not create device monitor");
|
||||
gst_object_unref (factory);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_factory_get_by_name:
|
||||
* @factoryname: a named factory to instantiate
|
||||
*
|
||||
* Returns the device monitor of the type defined by the given device
|
||||
* monitor factory.
|
||||
*
|
||||
* Returns: (transfer full): a #GstDeviceMonitor or NULL if unable to
|
||||
* create device monitor
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GstDeviceMonitor *
|
||||
gst_device_monitor_factory_get_by_name (const gchar * factoryname)
|
||||
{
|
||||
GstDeviceMonitorFactory *factory;
|
||||
GstDeviceMonitor *device_monitor;
|
||||
|
||||
g_return_val_if_fail (factoryname != NULL, NULL);
|
||||
g_return_val_if_fail (gst_is_initialized (), NULL);
|
||||
|
||||
GST_LOG ("gstdevicemonitorfactory: get_by_name \"%s\"", factoryname);
|
||||
|
||||
factory = gst_device_monitor_factory_find (factoryname);
|
||||
if (factory == NULL)
|
||||
goto no_factory;
|
||||
|
||||
GST_LOG_OBJECT (factory, "found factory %p", factory);
|
||||
device_monitor = gst_device_monitor_factory_get (factory);
|
||||
if (device_monitor == NULL)
|
||||
goto create_failed;
|
||||
|
||||
gst_object_unref (factory);
|
||||
return device_monitor;
|
||||
|
||||
/* ERRORS */
|
||||
no_factory:
|
||||
{
|
||||
GST_INFO ("no such device monitor factory \"%s\"!", factoryname);
|
||||
return NULL;
|
||||
}
|
||||
create_failed:
|
||||
{
|
||||
GST_INFO_OBJECT (factory, "couldn't create instance!");
|
||||
gst_object_unref (factory);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_factory_get_device_monitor_type:
|
||||
* @factory: factory to get managed #GType from
|
||||
*
|
||||
* Get the #GType for device monitors managed by this factory. The type can
|
||||
* only be retrieved if the device monitor factory is loaded, which can be
|
||||
* assured with gst_plugin_feature_load().
|
||||
*
|
||||
* Returns: the #GType for device monitors managed by this factory or 0 if
|
||||
* the factory is not loaded.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GType
|
||||
gst_device_monitor_factory_get_device_monitor_type (GstDeviceMonitorFactory *
|
||||
factory)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_DEVICE_MONITOR_FACTORY (factory), 0);
|
||||
|
||||
return factory->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_factory_get_metadata:
|
||||
* @factory: a #GstDeviceMonitorFactory
|
||||
* @key: a key
|
||||
*
|
||||
* Get the metadata on @factory with @key.
|
||||
*
|
||||
* Returns: the metadata with @key on @factory or %NULL when there was no
|
||||
* metadata with the given @key.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
const gchar *
|
||||
gst_device_monitor_factory_get_metadata (GstDeviceMonitorFactory * factory,
|
||||
const gchar * key)
|
||||
{
|
||||
return gst_structure_get_string ((GstStructure *) factory->metadata, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_factory_get_metadata_keys:
|
||||
* @factory: a #GstDeviceMonitorFactory
|
||||
*
|
||||
* Get the available keys for the metadata on @factory.
|
||||
*
|
||||
* Returns: (transfer full) (element-type utf8) (array zero-terminated=1):
|
||||
* a %NULL-terminated array of key strings, or %NULL when there is no
|
||||
* metadata. Free with g_strfreev() when no longer needed.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gchar **
|
||||
gst_device_monitor_factory_get_metadata_keys (GstDeviceMonitorFactory * factory)
|
||||
{
|
||||
GstStructure *metadata;
|
||||
gchar **arr;
|
||||
gint i, num;
|
||||
|
||||
g_return_val_if_fail (GST_IS_DEVICE_MONITOR_FACTORY (factory), NULL);
|
||||
|
||||
metadata = (GstStructure *) factory->metadata;
|
||||
if (metadata == NULL)
|
||||
return NULL;
|
||||
|
||||
num = gst_structure_n_fields (metadata);
|
||||
if (num == 0)
|
||||
return NULL;
|
||||
|
||||
arr = g_new (gchar *, num + 1);
|
||||
for (i = 0; i < num; ++i) {
|
||||
arr[i] = g_strdup (gst_structure_nth_field_name (metadata, i));
|
||||
}
|
||||
arr[i] = NULL;
|
||||
return arr;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GstDeviceMonitorFactoryListType type;
|
||||
GstRank minrank;
|
||||
} FilterData;
|
||||
|
||||
|
||||
/**
|
||||
* gst_device_monitor_factory_list_is_type:
|
||||
* @factory: a #GstDeviceMonitorFactory
|
||||
* @type: a #GstDeviceMonitorFactoryListType
|
||||
*
|
||||
* Check if @factory is of the given types.
|
||||
*
|
||||
* Returns: %TRUE if @factory is of @type.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
gboolean
|
||||
gst_device_monitor_factory_list_is_type (GstDeviceMonitorFactory * factory,
|
||||
GstDeviceMonitorFactoryListType type)
|
||||
{
|
||||
gboolean res = FALSE;
|
||||
const gchar *klass;
|
||||
|
||||
klass = gst_device_monitor_factory_get_metadata (factory,
|
||||
GST_ELEMENT_METADATA_KLASS);
|
||||
|
||||
if (klass == NULL) {
|
||||
GST_ERROR_OBJECT (factory,
|
||||
"device monitor factory is missing klass identifiers");
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Filter by device monitor type first, as soon as it matches
|
||||
* one type, we skip all other tests */
|
||||
if (!res && (type & GST_DEVICE_MONITOR_FACTORY_TYPE_SINK))
|
||||
res = (strstr (klass, "Sink") != NULL);
|
||||
|
||||
if (!res && (type & GST_DEVICE_MONITOR_FACTORY_TYPE_SRC))
|
||||
res = (strstr (klass, "Source") != NULL);
|
||||
|
||||
/* Filter by media type now, we only test if it
|
||||
* matched any of the types above. */
|
||||
if (res
|
||||
&& (type & (GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_AUDIO |
|
||||
GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_VIDEO |
|
||||
GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_IMAGE)))
|
||||
res = ((type & GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_AUDIO)
|
||||
&& (strstr (klass, "Audio") != NULL))
|
||||
|| ((type & GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_VIDEO)
|
||||
&& (strstr (klass, "Video") != NULL))
|
||||
|| ((type & GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_IMAGE)
|
||||
&& (strstr (klass, "Image") != NULL));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
device_monitor_filter (GstPluginFeature * feature, FilterData * data)
|
||||
{
|
||||
gboolean res;
|
||||
|
||||
/* we only care about device monitor factories */
|
||||
if (G_UNLIKELY (!GST_IS_DEVICE_MONITOR_FACTORY (feature)))
|
||||
return FALSE;
|
||||
|
||||
res = (gst_plugin_feature_get_rank (feature) >= data->minrank) &&
|
||||
gst_device_monitor_factory_list_is_type (GST_DEVICE_MONITOR_FACTORY_CAST
|
||||
(feature), data->type);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_device_monitor_factory_list_get_device_monitors:
|
||||
* @type: a #GstDeviceMonitorFactoryListType
|
||||
* @minrank: Minimum rank
|
||||
*
|
||||
* Get a list of factories that match the given @type. Only device monitors
|
||||
* with a rank greater or equal to @minrank will be returned.
|
||||
* The list of factories is returned by decreasing rank.
|
||||
*
|
||||
* Returns: (transfer full) (element-type Gst.DeviceMonitorFactory): a #GList of
|
||||
* #GstDeviceMonitorFactory device monitors. Use gst_plugin_feature_list_free() after
|
||||
* usage.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GList *gst_device_monitor_factory_list_get_device_monitors
|
||||
(GstDeviceMonitorFactoryListType type, GstRank minrank)
|
||||
{
|
||||
GList *result;
|
||||
FilterData data;
|
||||
|
||||
/* prepare type */
|
||||
data.type = type;
|
||||
data.minrank = minrank;
|
||||
|
||||
/* get the feature list using the filter */
|
||||
result = gst_registry_feature_filter (gst_registry_get (),
|
||||
(GstPluginFeatureFilter) device_monitor_filter, FALSE, &data);
|
||||
|
||||
/* sort on rank and name */
|
||||
result = g_list_sort (result, gst_plugin_feature_rank_compare_func);
|
||||
|
||||
return result;
|
||||
}
|
124
gst/gstdevicemonitorfactory.h
Normal file
124
gst/gstdevicemonitorfactory.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
|
||||
* 2000,2004 Wim Taymans <wim@fluendo.com>
|
||||
* 2012 Olivier Crete <olivier.crete@collabora.com>
|
||||
*
|
||||
* gstdevicemonitorfactory.h: Header for GstDeviceMonitorFactory
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef __GST_DEVICE_MONITOR_FACTORY_H__
|
||||
#define __GST_DEVICE_MONITOR_FACTORY_H__
|
||||
|
||||
/**
|
||||
* GstDeviceMonitorFactory:
|
||||
*
|
||||
* The opaque #GstDeviceMonitorFactory data structure.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
typedef struct _GstDeviceMonitorFactory GstDeviceMonitorFactory;
|
||||
typedef struct _GstDeviceMonitorFactoryClass GstDeviceMonitorFactoryClass;
|
||||
|
||||
#include <gst/gstconfig.h>
|
||||
#include <gst/gstplugin.h>
|
||||
#include <gst/gstpluginfeature.h>
|
||||
#include <gst/gstdevicemonitor.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_DEVICE_MONITOR_FACTORY (gst_device_monitor_factory_get_type())
|
||||
#define GST_DEVICE_MONITOR_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DEVICE_MONITOR_FACTORY,\
|
||||
GstDeviceMonitorFactory))
|
||||
#define GST_DEVICE_MONITOR_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DEVICE_MONITOR_FACTORY,\
|
||||
GstDeviceMonitorFactoryClass))
|
||||
#define GST_IS_DEVICE_MONITOR_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DEVICE_MONITOR_FACTORY))
|
||||
#define GST_IS_DEVICE_MONITOR_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DEVICE_MONITOR_FACTORY))
|
||||
#define GST_DEVICE_MONITOR_FACTORY_CAST(obj) ((GstDeviceMonitorFactory *)(obj))
|
||||
|
||||
GType gst_device_monitor_factory_get_type (void);
|
||||
|
||||
GstDeviceMonitorFactory * gst_device_monitor_factory_find (const gchar *name);
|
||||
|
||||
GType gst_device_monitor_factory_get_device_monitor_type (GstDeviceMonitorFactory *factory);
|
||||
|
||||
const gchar * gst_device_monitor_factory_get_metadata (GstDeviceMonitorFactory *factory, const gchar *key);
|
||||
gchar ** gst_device_monitor_factory_get_metadata_keys (GstDeviceMonitorFactory *factory);
|
||||
|
||||
GstDeviceMonitor* gst_device_monitor_factory_get (GstDeviceMonitorFactory *factory) G_GNUC_MALLOC;
|
||||
GstDeviceMonitor* gst_device_monitor_factory_get_by_name (const gchar *factoryname) G_GNUC_MALLOC;
|
||||
|
||||
gboolean gst_device_monitor_register (GstPlugin *plugin, const gchar *name,
|
||||
guint rank,
|
||||
GType type);
|
||||
|
||||
/* Factory list functions */
|
||||
|
||||
/**
|
||||
* GstDeviceMonitorFactoryListType:
|
||||
* @GST_DEVICE_MONITOR_FACTORY_TYPE_SINK: Sink elements
|
||||
* @GST_DEVICE_MONITOR_FACTORY_TYPE_SRC: Source elements
|
||||
* @GST_DEVICE_MONITOR_FACTORY_TYPE_MAX_DEVICE_MONITORS: Private, do not use
|
||||
* @GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_VIDEO: Elements handling video media types
|
||||
* @GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_AUDIO: Elements handling audio media types
|
||||
* @GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_IMAGE: Elements handling image media types
|
||||
* @GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_SUBTITLE: Elements handling subtitle media types
|
||||
* @GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_METADATA: Elements handling metadata media types
|
||||
*
|
||||
* The type of #GstDeviceMonitorFactory to filter.
|
||||
*
|
||||
* All @GstDeviceMonitorFactoryListType up to @GST_DEVICE_MONITOR_FACTORY_TYPE_MAX_DEVICE_MONITORS are exclusive.
|
||||
*
|
||||
* If one or more of the MEDIA types are specified, then only elements
|
||||
* matching the specified media types will be selected.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
|
||||
typedef guint64 GstDeviceMonitorFactoryListType;
|
||||
|
||||
#define GST_DEVICE_MONITOR_FACTORY_TYPE_SINK (G_GUINT64_CONSTANT (1) << 0)
|
||||
#define GST_DEVICE_MONITOR_FACTORY_TYPE_SRC (G_GUINT64_CONSTANT (1) << 1)
|
||||
#define GST_DEVICE_MONITOR_FACTORY_TYPE_MAX_DEVICE_MONITORS (G_GUINT64_CONSTANT (1) << 48)
|
||||
|
||||
#define GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_VIDEO (G_GUINT64_CONSTANT (1) << 49)
|
||||
#define GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_AUDIO (G_GUINT64_CONSTANT (1) << 50)
|
||||
#define GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_IMAGE (G_GUINT64_CONSTANT (1) << 51)
|
||||
#define GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_SUBTITLE (G_GUINT64_CONSTANT (1) << 52)
|
||||
#define GST_DEVICE_MONITOR_FACTORY_TYPE_MEDIA_METADATA (G_GUINT64_CONSTANT (1) << 53)
|
||||
|
||||
/* Element klass defines */
|
||||
#define GST_DEVICE_MONITOR_FACTORY_KLASS_DECODER "Decoder"
|
||||
#define GST_DEVICE_MONITOR_FACTORY_KLASS_ENCODER "Encoder"
|
||||
|
||||
#define GST_DEVICE_MONITOR_FACTORY_KLASS_MEDIA_VIDEO "Video"
|
||||
#define GST_DEVICE_MONITOR_FACTORY_KLASS_MEDIA_AUDIO "Audio"
|
||||
#define GST_DEVICE_MONITOR_FACTORY_KLASS_MEDIA_IMAGE "Image"
|
||||
#define GST_DEVICE_MONITOR_FACTORY_KLASS_MEDIA_SUBTITLE "Subtitle"
|
||||
#define GST_DEVICE_MONITOR_FACTORY_KLASS_MEDIA_METADATA "Metadata"
|
||||
|
||||
gboolean gst_device_monitor_factory_list_is_type (GstDeviceMonitorFactory *factory,
|
||||
GstDeviceMonitorFactoryListType type);
|
||||
|
||||
GList * gst_device_monitor_factory_list_get_device_monitors (GstDeviceMonitorFactoryListType type,
|
||||
GstRank minrank) G_GNUC_MALLOC;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_DEVICE_MONITOR_FACTORY_H__ */
|
104
gst/gstmessage.c
104
gst/gstmessage.c
|
@ -108,7 +108,8 @@ static GstMessageQuarks message_quarks[] = {
|
|||
{GST_MESSAGE_NEED_CONTEXT, "need-context", 0},
|
||||
{GST_MESSAGE_HAVE_CONTEXT, "have-context", 0},
|
||||
{GST_MESSAGE_EXTENDED, "extended", 0},
|
||||
{GST_MESSAGE_DEVICE, "device", 0},
|
||||
{GST_MESSAGE_DEVICE_ADDED, "device-added", 0},
|
||||
{GST_MESSAGE_DEVICE_REMOVED, "device-removed", 0},
|
||||
{0, NULL, 0}
|
||||
};
|
||||
|
||||
|
@ -2357,3 +2358,104 @@ gst_message_parse_have_context (GstMessage * message, GstContext ** context)
|
|||
gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
|
||||
GST_QUARK (CONTEXT), GST_TYPE_CONTEXT, context, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_message_new_device_added:
|
||||
* @src: The #GstObject that created the message
|
||||
* @device: (transfer none): The new #GstDevice
|
||||
*
|
||||
* Creates a new device-added message. The device-added message is produced by
|
||||
* #GstDeviceMonitor or a #GstGlobalDeviceMonitor. They announce the appearance
|
||||
* of monitored devices.
|
||||
*
|
||||
* Returns: a newly allocated #GstMessage
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GstMessage *
|
||||
gst_message_new_device_added (GstObject * src, GstDevice * device)
|
||||
{
|
||||
GstMessage *message;
|
||||
GstStructure *structure;
|
||||
|
||||
structure = gst_structure_new_id (GST_QUARK (MESSAGE_DEVICE_ADDED),
|
||||
GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
|
||||
message = gst_message_new_extended (GST_MESSAGE_DEVICE_ADDED, src, structure);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_message_parse_device_added:
|
||||
* @device: (out) (allow-none) (transfer none): A location where to store a
|
||||
* pointer to the new #GstDevice, or %NULL
|
||||
*
|
||||
* Parses a device-added message. The device-added message is produced by
|
||||
* #GstDeviceMonitor or a #GstGlobalDeviceMonitor. It announces the appearance
|
||||
* of monitored devices.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
gst_message_parse_device_added (GstMessage * message, GstDevice ** device)
|
||||
{
|
||||
g_return_if_fail (GST_IS_MESSAGE (message));
|
||||
g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EXTENDED);
|
||||
g_return_if_fail (gst_message_get_extended_type (message) ==
|
||||
GST_MESSAGE_DEVICE_ADDED);
|
||||
|
||||
if (device)
|
||||
gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
|
||||
GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_message_new_device_removed:
|
||||
* @src: The #GstObject that created the message
|
||||
* @device: (transfer none): The removed #GstDevice
|
||||
*
|
||||
* Creates a new device-removed message. The device-removed message is produced
|
||||
* by #GstDeviceMonitor or a #GstGlobalDeviceMonitor. They announce the
|
||||
* disappearance of monitored devices.
|
||||
*
|
||||
* Returns: a newly allocated #GstMessage
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
GstMessage *
|
||||
gst_message_new_device_removed (GstObject * src, GstDevice * device)
|
||||
{
|
||||
GstMessage *message;
|
||||
GstStructure *structure;
|
||||
|
||||
structure = gst_structure_new_id (GST_QUARK (MESSAGE_DEVICE_REMOVED),
|
||||
GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
|
||||
message = gst_message_new_extended (GST_MESSAGE_DEVICE_REMOVED, src,
|
||||
structure);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_message_parse_device_removed:
|
||||
* @device: (out) (allow-none) (transfer none): A location where to store a
|
||||
* pointer to the removed #GstDevice, or %NULL
|
||||
*
|
||||
* Parses a device-removed message. The device-removed message is produced by
|
||||
* #GstDeviceMonitor or a #GstGlobalDeviceMonitor. It announces the
|
||||
* disappearance of monitored devices.
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
void
|
||||
gst_message_parse_device_removed (GstMessage * message, GstDevice ** device)
|
||||
{
|
||||
g_return_if_fail (GST_IS_MESSAGE (message));
|
||||
g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EXTENDED);
|
||||
g_return_if_fail (gst_message_get_extended_type (message) ==
|
||||
GST_MESSAGE_DEVICE_REMOVED);
|
||||
|
||||
if (device)
|
||||
gst_structure_id_get (GST_MESSAGE_STRUCTURE (message),
|
||||
GST_QUARK (DEVICE), GST_TYPE_DEVICE, device, NULL);
|
||||
}
|
||||
|
|
|
@ -149,15 +149,20 @@ typedef enum
|
|||
|
||||
/**
|
||||
* GstMessageExtendedType:
|
||||
* @GST_MESSAGE_DEVICE: A #GstDevice addition or removal according to
|
||||
* a #GstDeviceMonitor
|
||||
* @GST_MESSAGE_DEVICE_ADDED: A #GstDevice addition according to
|
||||
* a #GstDeviceMonitor (Since 1.4)
|
||||
* @GST_MESSAGE_DEVICE_REMOVED: A #GstDevice removal according to
|
||||
* a #GstDeviceMonitor (Since 1.4)
|
||||
*
|
||||
* Extra message types, see #GstMessageType for the basic types
|
||||
*
|
||||
* Since: 1.4
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/* Skip those defined in #GstMessage to avoid confusion */
|
||||
GST_MESSAGE_DEVICE = 3
|
||||
GST_MESSAGE_DEVICE_ADDED = 3,
|
||||
GST_MESSAGE_DEVICE_REMOVED = 5
|
||||
} GstMessageExtendedType;
|
||||
|
||||
#include <gst/gstminiobject.h>
|
||||
|
@ -167,6 +172,7 @@ typedef enum {
|
|||
#include <gst/gststructure.h>
|
||||
#include <gst/gstquery.h>
|
||||
#include <gst/gsttoc.h>
|
||||
#include <gst/gstdevice.h>
|
||||
|
||||
#define GST_TYPE_MESSAGE (gst_message_get_type())
|
||||
#define GST_IS_MESSAGE(obj) (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_MESSAGE))
|
||||
|
@ -591,6 +597,15 @@ gboolean gst_message_parse_context_type (GstMessage * message, const gch
|
|||
GstMessage * gst_message_new_have_context (GstObject * src, GstContext *context) G_GNUC_MALLOC;
|
||||
void gst_message_parse_have_context (GstMessage *message, GstContext **context);
|
||||
|
||||
/* DEVICE_ADDED */
|
||||
GstMessage * gst_message_new_device_added (GstObject * src, GstDevice * device) G_GNUC_MALLOC;
|
||||
void gst_message_parse_device_added (GstMessage * message, GstDevice ** device);
|
||||
|
||||
/* DEVICE_REMOVED */
|
||||
GstMessage * gst_message_new_device_removed (GstObject * src, GstDevice * device) G_GNUC_MALLOC;
|
||||
void gst_message_parse_device_removed (GstMessage * message, GstDevice ** device);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_MESSAGE_H__ */
|
||||
|
|
|
@ -68,7 +68,8 @@ static const gchar *_quark_strings[] = {
|
|||
"GstEventSegmentDone",
|
||||
"GstEventStreamStart", "stream-id", "GstQueryContext",
|
||||
"GstMessageNeedContext", "GstMessageHaveContext", "context", "context-type",
|
||||
"GstMessageStreamStart", "group-id", "uri-redirection", "GstMessageExtended"
|
||||
"GstMessageStreamStart", "group-id", "uri-redirection", "GstMessageExtended",
|
||||
"GstMessageDeviceAdded", "GstMessageDeviceRemoved", "device"
|
||||
};
|
||||
|
||||
GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
||||
|
|
|
@ -197,7 +197,10 @@ typedef enum _GstQuarkId
|
|||
GST_QUARK_GROUP_ID = 168,
|
||||
GST_QUARK_URI_REDIRECTION = 169,
|
||||
GST_QUARK_MESSAGE_EXTENDED = 170,
|
||||
GST_QUARK_MAX = 171
|
||||
GST_QUARK_MESSAGE_DEVICE_ADDED = 171,
|
||||
GST_QUARK_MESSAGE_DEVICE_REMOVED = 172,
|
||||
GST_QUARK_DEVICE = 173,
|
||||
GST_QUARK_MAX = 174
|
||||
} GstQuarkId;
|
||||
|
||||
extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
|
||||
|
|
|
@ -129,6 +129,7 @@
|
|||
#include "gstinfo.h"
|
||||
#include "gsterror.h"
|
||||
#include "gstregistry.h"
|
||||
#include "gstdevicemonitorfactory.h"
|
||||
|
||||
#include "gstpluginloader.h"
|
||||
|
||||
|
@ -167,6 +168,8 @@ struct _GstRegistryPrivate
|
|||
guint32 efl_cookie;
|
||||
GList *typefind_factory_list;
|
||||
guint32 tfl_cookie;
|
||||
GList *device_monitor_factory_list;
|
||||
guint32 dmfl_cookie;
|
||||
};
|
||||
|
||||
/* the one instance of the default registry and the mutex protecting the
|
||||
|
@ -316,6 +319,12 @@ gst_registry_finalize (GObject * object)
|
|||
gst_plugin_feature_list_free (registry->priv->typefind_factory_list);
|
||||
}
|
||||
|
||||
if (registry->priv->device_monitor_factory_list) {
|
||||
GST_DEBUG_OBJECT (registry,
|
||||
"Cleaning up cached device monitor factory list");
|
||||
gst_plugin_feature_list_free (registry->priv->device_monitor_factory_list);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -780,6 +789,28 @@ gst_registry_get_typefind_factory_list (GstRegistry * registry)
|
|||
return list;
|
||||
}
|
||||
|
||||
|
||||
static GList *
|
||||
gst_registry_get_device_monitor_factory_list (GstRegistry * registry)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
GST_OBJECT_LOCK (registry);
|
||||
|
||||
gst_registry_get_feature_list_or_create (registry,
|
||||
®istry->priv->device_monitor_factory_list,
|
||||
®istry->priv->dmfl_cookie, GST_TYPE_DEVICE_MONITOR_FACTORY);
|
||||
|
||||
/* Return reffed copy */
|
||||
list =
|
||||
gst_plugin_feature_list_copy (registry->priv->
|
||||
device_monitor_factory_list);
|
||||
|
||||
GST_OBJECT_UNLOCK (registry);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_registry_feature_filter:
|
||||
* @registry: registry to query
|
||||
|
@ -922,6 +953,8 @@ gst_registry_get_feature_list (GstRegistry * registry, GType type)
|
|||
return gst_registry_get_element_factory_list (registry);
|
||||
else if (type == GST_TYPE_TYPE_FIND_FACTORY)
|
||||
return gst_registry_get_typefind_factory_list (registry);
|
||||
else if (type == GST_TYPE_DEVICE_MONITOR_FACTORY)
|
||||
return gst_registry_get_device_monitor_factory_list (registry);
|
||||
|
||||
data.type = type;
|
||||
data.name = NULL;
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include <gst/gstelement.h>
|
||||
#include <gst/gsttypefind.h>
|
||||
#include <gst/gsttypefindfactory.h>
|
||||
#include <gst/gstdevicemonitorfactory.h>
|
||||
#include <gst/gsturi.h>
|
||||
#include <gst/gstinfo.h>
|
||||
#include <gst/gstenumtypes.h>
|
||||
|
@ -525,6 +526,7 @@ priv_gst_registry_binary_read_cache (GstRegistry * registry,
|
|||
/* make sure these types exist */
|
||||
GST_TYPE_ELEMENT_FACTORY;
|
||||
GST_TYPE_TYPE_FIND_FACTORY;
|
||||
GST_TYPE_DEVICE_MONITOR_FACTORY;
|
||||
|
||||
#ifndef GST_DISABLE_GST_DEBUG
|
||||
timer = g_timer_new ();
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <gst/gstelement.h>
|
||||
#include <gst/gsttypefind.h>
|
||||
#include <gst/gsttypefindfactory.h>
|
||||
#include <gst/gstdevicemonitorfactory.h>
|
||||
#include <gst/gsturi.h>
|
||||
#include <gst/gstinfo.h>
|
||||
#include <gst/gstenumtypes.h>
|
||||
|
@ -332,6 +333,23 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
|
|||
} else {
|
||||
gst_registry_chunks_save_const_string (list, "");
|
||||
}
|
||||
} else if (GST_IS_DEVICE_MONITOR_FACTORY (feature)) {
|
||||
GstRegistryChunkDeviceMonitorFactory *tff;
|
||||
GstDeviceMonitorFactory *factory = GST_DEVICE_MONITOR_FACTORY (feature);
|
||||
|
||||
/* Initialize with zeroes because of struct padding and
|
||||
* valgrind complaining about copying unitialized memory
|
||||
*/
|
||||
tff = g_slice_new0 (GstRegistryChunkDeviceMonitorFactory);
|
||||
chk =
|
||||
gst_registry_chunks_make_data (tff,
|
||||
sizeof (GstRegistryChunkDeviceMonitorFactory));
|
||||
pf = (GstRegistryChunkPluginFeature *) tff;
|
||||
|
||||
|
||||
/* pack element metadata strings */
|
||||
gst_registry_chunks_save_string (list,
|
||||
gst_structure_to_string (factory->metadata));
|
||||
} else {
|
||||
GST_WARNING_OBJECT (feature, "unhandled feature type '%s'", type_name);
|
||||
}
|
||||
|
@ -650,6 +668,30 @@ gst_registry_chunks_load_feature (GstRegistry * registry, gchar ** in,
|
|||
factory->extensions[i - 1] = str;
|
||||
}
|
||||
}
|
||||
} else if (GST_IS_DEVICE_MONITOR_FACTORY (feature)) {
|
||||
GstRegistryChunkDeviceMonitorFactory *dmf;
|
||||
GstDeviceMonitorFactory *factory = GST_DEVICE_MONITOR_FACTORY (feature);
|
||||
const gchar *meta_data_str;
|
||||
|
||||
align (*in);
|
||||
GST_DEBUG
|
||||
("Reading/casting for GstRegistryChunkPluginFeature at address %p",
|
||||
*in);
|
||||
unpack_element (*in, dmf, GstRegistryChunkDeviceMonitorFactory, end, fail);
|
||||
|
||||
pf = (GstRegistryChunkPluginFeature *) dmf;
|
||||
|
||||
/* unpack element factory strings */
|
||||
unpack_string_nocopy (*in, meta_data_str, end, fail);
|
||||
if (meta_data_str && *meta_data_str) {
|
||||
factory->metadata = gst_structure_from_string (meta_data_str, NULL);
|
||||
if (!factory->metadata) {
|
||||
GST_ERROR
|
||||
("Error when trying to deserialize structure for metadata '%s'",
|
||||
meta_data_str);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GST_WARNING ("unhandled factory type : %s", G_OBJECT_TYPE_NAME (feature));
|
||||
goto fail;
|
||||
|
|
|
@ -122,7 +122,7 @@ typedef struct _GstRegistryChunkElementFactory
|
|||
* GstRegistryChunkTypeFindFactory:
|
||||
* @nextensions: stores the number of typefind extensions
|
||||
*
|
||||
* A structure containing the element factory fields
|
||||
* A structure containing the type find factory fields
|
||||
*/
|
||||
typedef struct _GstRegistryChunkTypeFindFactory
|
||||
{
|
||||
|
@ -131,6 +131,17 @@ typedef struct _GstRegistryChunkTypeFindFactory
|
|||
guint nextensions;
|
||||
} GstRegistryChunkTypeFindFactory;
|
||||
|
||||
/*
|
||||
* GstRegistryChunkDeviceMonitorFactory:
|
||||
*
|
||||
* A structure containing the device monitor factory fields
|
||||
*/
|
||||
typedef struct _GstRegistryChunkDeviceMonitorFactory
|
||||
{
|
||||
GstRegistryChunkPluginFeature plugin_feature;
|
||||
|
||||
} GstRegistryChunkDeviceMonitorFactory;
|
||||
|
||||
/*
|
||||
* GstRegistryChunkPadTemplate:
|
||||
*
|
||||
|
|
|
@ -390,6 +390,35 @@ EXPORTS
|
|||
gst_debug_set_threshold_from_string
|
||||
gst_debug_unset_threshold_for_name
|
||||
gst_deinit
|
||||
gst_device_create_element
|
||||
gst_device_get_caps
|
||||
gst_device_get_display_name
|
||||
gst_device_get_type
|
||||
gst_device_monitor_can_monitor
|
||||
gst_device_monitor_class_add_metadata
|
||||
gst_device_monitor_class_add_static_metadata
|
||||
gst_device_monitor_class_get_metadata
|
||||
gst_device_monitor_class_set_metadata
|
||||
gst_device_monitor_class_set_static_metadata
|
||||
gst_device_monitor_device_add
|
||||
gst_device_monitor_device_remove
|
||||
gst_device_monitor_factory_find
|
||||
gst_device_monitor_factory_get
|
||||
gst_device_monitor_factory_get_by_name
|
||||
gst_device_monitor_factory_get_device_monitor_type
|
||||
gst_device_monitor_factory_get_metadata
|
||||
gst_device_monitor_factory_get_metadata_keys
|
||||
gst_device_monitor_factory_get_type
|
||||
gst_device_monitor_factory_list_get_device_monitors
|
||||
gst_device_monitor_factory_list_is_type
|
||||
gst_device_monitor_get_bus
|
||||
gst_device_monitor_get_devices
|
||||
gst_device_monitor_get_factory
|
||||
gst_device_monitor_get_type
|
||||
gst_device_monitor_register
|
||||
gst_device_monitor_start
|
||||
gst_device_monitor_stop
|
||||
gst_device_reconfigure_element
|
||||
gst_double_range_get_type
|
||||
gst_element_abort_state
|
||||
gst_element_add_pad
|
||||
|
@ -592,6 +621,8 @@ EXPORTS
|
|||
gst_memory_resize
|
||||
gst_memory_share
|
||||
gst_memory_unmap
|
||||
gst_message_extended_type_get_type
|
||||
gst_message_get_extended_type
|
||||
gst_message_get_seqnum
|
||||
gst_message_get_stream_status_object
|
||||
gst_message_get_structure
|
||||
|
@ -604,6 +635,8 @@ EXPORTS
|
|||
gst_message_new_clock_lost
|
||||
gst_message_new_clock_provide
|
||||
gst_message_new_custom
|
||||
gst_message_new_device_added
|
||||
gst_message_new_device_removed
|
||||
gst_message_new_duration_changed
|
||||
gst_message_new_element
|
||||
gst_message_new_eos
|
||||
|
@ -635,6 +668,8 @@ EXPORTS
|
|||
gst_message_parse_clock_lost
|
||||
gst_message_parse_clock_provide
|
||||
gst_message_parse_context_type
|
||||
gst_message_parse_device_added
|
||||
gst_message_parse_device_removed
|
||||
gst_message_parse_error
|
||||
gst_message_parse_group_id
|
||||
gst_message_parse_have_context
|
||||
|
|
Loading…
Reference in a new issue