Blame gst/gstdevice.c

Packit Service 963350
/* GStreamer
Packit Service 963350
 * Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
Packit Service 963350
 *
Packit Service 963350
 * gstdevice.c: Device discovery
Packit Service 963350
 *
Packit Service 963350
 * This library is free software; you can redistribute it and/or
Packit Service 963350
 * modify it under the terms of the GNU Library General Public
Packit Service 963350
 * License as published by the Free Software Foundation; either
Packit Service 963350
 * version 2 of the License, or (at your option) any later version.
Packit Service 963350
 *
Packit Service 963350
 * This library is distributed in the hope that it will be useful,
Packit Service 963350
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 963350
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 963350
 * Library General Public License for more details.
Packit Service 963350
 *
Packit Service 963350
 * You should have received a copy of the GNU Library General Public
Packit Service 963350
 * License along with this library; if not, write to the
Packit Service 963350
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service 963350
 * Boston, MA 02111-1307, USA.
Packit Service 963350
 */
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * SECTION:gstdevice
Packit Service 963350
 * @title: GstDevice
Packit Service 963350
 * @short_description: Object representing a device
Packit Service 963350
 * @see_also: #GstDeviceProvider
Packit Service 963350
 *
Packit Service 963350
 * #GstDevice are objects representing a device, they contain
Packit Service 963350
 * relevant metadata about the device, such as its class and the #GstCaps
Packit Service 963350
 * representing the media types it can produce or handle.
Packit Service 963350
 *
Packit Service 963350
 * #GstDevice are created by #GstDeviceProvider objects which can be
Packit Service 963350
 * aggregated by #GstDeviceMonitor objects.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.4
Packit Service 963350
 */
Packit Service 963350
Packit Service 963350
#ifdef HAVE_CONFIG_H
Packit Service 963350
#include "config.h"
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
#include "gst_private.h"
Packit Service 963350
Packit Service 963350
#include "gstdevice.h"
Packit Service 963350
Packit Service 963350
enum
Packit Service 963350
{
Packit Service 963350
  PROP_DISPLAY_NAME = 1,
Packit Service 963350
  PROP_CAPS,
Packit Service 963350
  PROP_DEVICE_CLASS,
Packit Service 963350
  PROP_PROPERTIES
Packit Service 963350
};
Packit Service 963350
Packit Service 963350
enum
Packit Service 963350
{
Packit Service 963350
  REMOVED,
Packit Service 963350
  LAST_SIGNAL
Packit Service 963350
};
Packit Service 963350
Packit Service 963350
struct _GstDevicePrivate
Packit Service 963350
{
Packit Service 963350
  GstCaps *caps;
Packit Service 963350
  gchar *device_class;
Packit Service 963350
  gchar *display_name;
Packit Service 963350
  GstStructure *properties;
Packit Service 963350
};
Packit Service 963350
Packit Service 963350
Packit Service 963350
static guint signals[LAST_SIGNAL];
Packit Service 963350
Packit Service 963350
G_DEFINE_ABSTRACT_TYPE (GstDevice, gst_device, GST_TYPE_OBJECT);
Packit Service 963350
Packit Service 963350
static void gst_device_get_property (GObject * object, guint property_id,
Packit Service 963350
    GValue * value, GParamSpec * pspec);
Packit Service 963350
static void gst_device_set_property (GObject * object, guint property_id,
Packit Service 963350
    const GValue * value, GParamSpec * pspec);
Packit Service 963350
static void gst_device_finalize (GObject * object);
Packit Service 963350
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_device_class_init (GstDeviceClass * klass)
Packit Service 963350
{
Packit Service 963350
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit Service 963350
Packit Service 963350
  g_type_class_add_private (klass, sizeof (GstDevicePrivate));
Packit Service 963350
Packit Service 963350
  object_class->get_property = gst_device_get_property;
Packit Service 963350
  object_class->set_property = gst_device_set_property;
Packit Service 963350
  object_class->finalize = gst_device_finalize;
Packit Service 963350
Packit Service 963350
  g_object_class_install_property (object_class, PROP_DISPLAY_NAME,
Packit Service 963350
      g_param_spec_string ("display-name", "Display Name",
Packit Service 963350
          "The user-friendly name of the device", "",
Packit Service 963350
          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
Packit Service 963350
  g_object_class_install_property (object_class, PROP_CAPS,
Packit Service 963350
      g_param_spec_boxed ("caps", "Device Caps",
Packit Service 963350
          "The possible caps of a device", GST_TYPE_CAPS,
Packit Service 963350
          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
Packit Service 963350
  g_object_class_install_property (object_class, PROP_DEVICE_CLASS,
Packit Service 963350
      g_param_spec_string ("device-class", "Device Class",
Packit Service 963350
          "The Class of the device", "",
Packit Service 963350
          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
Packit Service 963350
  g_object_class_install_property (object_class, PROP_PROPERTIES,
Packit Service 963350
      g_param_spec_boxed ("properties", "Properties",
Packit Service 963350
          "The extra properties of the device", GST_TYPE_STRUCTURE,
Packit Service 963350
          G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
Packit Service 963350
Packit Service 963350
  signals[REMOVED] = g_signal_new ("removed", G_TYPE_FROM_CLASS (klass),
Packit Service 963350
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_device_init (GstDevice * device)
Packit Service 963350
{
Packit Service 963350
  device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device, GST_TYPE_DEVICE,
Packit Service 963350
      GstDevicePrivate);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_device_finalize (GObject * object)
Packit Service 963350
{
Packit Service 963350
  GstDevice *device = GST_DEVICE (object);
Packit Service 963350
Packit Service 963350
  gst_caps_replace (&device->priv->caps, NULL);
Packit Service 963350
Packit Service 963350
  if (device->priv->properties)
Packit Service 963350
    gst_structure_free (device->priv->properties);
Packit Service 963350
  g_free (device->priv->display_name);
Packit Service 963350
  g_free (device->priv->device_class);
Packit Service 963350
Packit Service 963350
  G_OBJECT_CLASS (gst_device_parent_class)->finalize (object);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_device_get_property (GObject * object, guint prop_id,
Packit Service 963350
    GValue * value, GParamSpec * pspec)
Packit Service 963350
{
Packit Service 963350
  GstDevice *gstdevice;
Packit Service 963350
Packit Service 963350
  gstdevice = GST_DEVICE_CAST (object);
Packit Service 963350
Packit Service 963350
  switch (prop_id) {
Packit Service 963350
    case PROP_DISPLAY_NAME:
Packit Service 963350
      g_value_take_string (value, gst_device_get_display_name (gstdevice));
Packit Service 963350
      break;
Packit Service 963350
    case PROP_CAPS:
Packit Service 963350
      if (gstdevice->priv->caps)
Packit Service 963350
        g_value_take_boxed (value, gst_device_get_caps (gstdevice));
Packit Service 963350
      break;
Packit Service 963350
    case PROP_DEVICE_CLASS:
Packit Service 963350
      g_value_take_string (value, gst_device_get_device_class (gstdevice));
Packit Service 963350
      break;
Packit Service 963350
    case PROP_PROPERTIES:
Packit Service 963350
      if (gstdevice->priv->properties)
Packit Service 963350
        g_value_take_boxed (value, gst_device_get_properties (gstdevice));
Packit Service 963350
      break;
Packit Service 963350
    default:
Packit Service 963350
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit Service 963350
      break;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_device_set_property (GObject * object, guint prop_id,
Packit Service 963350
    const GValue * value, GParamSpec * pspec)
Packit Service 963350
{
Packit Service 963350
  GstDevice *gstdevice;
Packit Service 963350
Packit Service 963350
  gstdevice = GST_DEVICE_CAST (object);
Packit Service 963350
Packit Service 963350
  switch (prop_id) {
Packit Service 963350
    case PROP_DISPLAY_NAME:
Packit Service 963350
      gstdevice->priv->display_name = g_value_dup_string (value);
Packit Service 963350
      break;
Packit Service 963350
    case PROP_CAPS:
Packit Service 963350
      gst_caps_replace (&gstdevice->priv->caps, g_value_get_boxed (value));
Packit Service 963350
      break;
Packit Service 963350
    case PROP_DEVICE_CLASS:
Packit Service 963350
      gstdevice->priv->device_class = g_value_dup_string (value);
Packit Service 963350
      break;
Packit Service 963350
    case PROP_PROPERTIES:
Packit Service 963350
      if (gstdevice->priv->properties)
Packit Service 963350
        gst_structure_free (gstdevice->priv->properties);
Packit Service 963350
      gstdevice->priv->properties = g_value_dup_boxed (value);
Packit Service 963350
      break;
Packit Service 963350
    default:
Packit Service 963350
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit Service 963350
      break;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_device_create_element:
Packit Service 963350
 * @device: a #GstDevice
Packit Service 963350
 * @name: (allow-none): name of new element, or %NULL to automatically
Packit Service 963350
 * create a unique name.
Packit Service 963350
 *
Packit Service 963350
 * Creates the element with all of the required parameters set to use
Packit Service 963350
 * this device.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): a new #GstElement configured to use
Packit Service 963350
 * this device
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.4
Packit Service 963350
 */
Packit Service 963350
GstElement *
Packit Service 963350
gst_device_create_element (GstDevice * device, const gchar * name)
Packit Service 963350
{
Packit Service 963350
  GstDeviceClass *klass = GST_DEVICE_GET_CLASS (device);
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_DEVICE (device), NULL);
Packit Service 963350
Packit Service 963350
  if (klass->create_element)
Packit Service 963350
    return klass->create_element (device, name);
Packit Service 963350
  else
Packit Service 963350
    return NULL;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_device_get_caps:
Packit Service 963350
 * @device: a #GstDevice
Packit Service 963350
 *
Packit Service 963350
 * Getter for the #GstCaps that this device supports.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (nullable): The #GstCaps supported by this device. Unref with
Packit Service 963350
 * gst_caps_unref() when done.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.4
Packit Service 963350
 */
Packit Service 963350
GstCaps *
Packit Service 963350
gst_device_get_caps (GstDevice * device)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_DEVICE (device), NULL);
Packit Service 963350
Packit Service 963350
  if (device->priv->caps)
Packit Service 963350
    return gst_caps_ref (device->priv->caps);
Packit Service 963350
  else
Packit Service 963350
    return NULL;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_device_get_display_name:
Packit Service 963350
 * @device: a #GstDevice
Packit Service 963350
 *
Packit Service 963350
 * Gets the user-friendly name of the device.
Packit Service 963350
 *
Packit Service 963350
 * Returns: The device name. Free with g_free() after use.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.4
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
gst_device_get_display_name (GstDevice * device)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_DEVICE (device), NULL);
Packit Service 963350
Packit Service 963350
  return
Packit Service 963350
      g_strdup (device->priv->display_name ? device->priv->display_name : "");
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_device_get_device_class:
Packit Service 963350
 * @device: a #GstDevice
Packit Service 963350
 *
Packit Service 963350
 * Gets the "class" of a device. This is a "/" separated list of
Packit Service 963350
 * classes that represent this device. They are a subset of the
Packit Service 963350
 * classes of the #GstDeviceProvider that produced this device.
Packit Service 963350
 *
Packit Service 963350
 * Returns: The device class. Free with g_free() after use.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.4
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
gst_device_get_device_class (GstDevice * device)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_DEVICE (device), NULL);
Packit Service 963350
Packit Service 963350
  if (device->priv->device_class != NULL)
Packit Service 963350
    return g_strdup (device->priv->device_class);
Packit Service 963350
  else
Packit Service 963350
    return g_strdup ("");
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_device_get_properties:
Packit Service 963350
 * @device: a #GstDevice
Packit Service 963350
 *
Packit Service 963350
 * Gets the extra properties of a device.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (nullable): The extra properties or %NULL when there are none.
Packit Service 963350
 *          Free with gst_structure_free() after use.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.6
Packit Service 963350
 */
Packit Service 963350
GstStructure *
Packit Service 963350
gst_device_get_properties (GstDevice * device)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_DEVICE (device), NULL);
Packit Service 963350
Packit Service 963350
  if (device->priv->properties != NULL)
Packit Service 963350
    return gst_structure_copy (device->priv->properties);
Packit Service 963350
  else
Packit Service 963350
    return NULL;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_device_reconfigure_element:
Packit Service 963350
 * @device: a #GstDevice
Packit Service 963350
 * @element: a #GstElement
Packit Service 963350
 *
Packit Service 963350
 * Tries to reconfigure an existing element to use the device. If this
Packit Service 963350
 * function fails, then one must destroy the element and create a new one
Packit Service 963350
 * using gst_device_create_element().
Packit Service 963350
 *
Packit Service 963350
 * Note: This should only be implemented for elements can change their
Packit Service 963350
 * device in the PLAYING state.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the element could be reconfigured to use this device,
Packit Service 963350
 * %FALSE otherwise.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.4
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_device_reconfigure_element (GstDevice * device, GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GstDeviceClass *klass = GST_DEVICE_GET_CLASS (device);
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_DEVICE (device), FALSE);
Packit Service 963350
Packit Service 963350
  if (klass->reconfigure_element)
Packit Service 963350
    return klass->reconfigure_element (device, element);
Packit Service 963350
  else
Packit Service 963350
    return FALSE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_device_has_classesv:
Packit Service 963350
 * @device: a #GstDevice
Packit Service 963350
 * @classes: (array zero-terminated=1): a %NULL terminated array of classes
Packit Service 963350
 *   to match, only match if all classes are matched
Packit Service 963350
 *
Packit Service 963350
 * Check if @factory matches all of the given classes
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if @device matches.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.4
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_device_has_classesv (GstDevice * device, gchar ** classes)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_DEVICE (device), FALSE);
Packit Service 963350
Packit Service 963350
  if (!classes)
Packit Service 963350
    return TRUE;
Packit Service 963350
Packit Service 963350
  for (; classes[0]; classes++) {
Packit Service 963350
    const gchar *klass = classes[0];
Packit Service 963350
    const gchar *found;
Packit Service 963350
    guint len;
Packit Service 963350
Packit Service 963350
    if (*klass == '\0')
Packit Service 963350
      continue;
Packit Service 963350
Packit Service 963350
    found = strstr (device->priv->device_class, klass);
Packit Service 963350
Packit Service 963350
    if (!found)
Packit Service 963350
      return FALSE;
Packit Service 963350
    if (found != device->priv->device_class && *(found - 1) != '/')
Packit Service 963350
      return FALSE;
Packit Service 963350
Packit Service 963350
    len = strlen (klass);
Packit Service 963350
    if (found[len] != 0 && found[len] != '/')
Packit Service 963350
      return FALSE;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_device_has_classes:
Packit Service 963350
 * @device: a #GstDevice
Packit Service 963350
 * @classes: a "/"-separated list of device classes to match, only match if
Packit Service 963350
 *  all classes are matched
Packit Service 963350
 *
Packit Service 963350
 * Check if @device matches all of the given classes
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if @device matches.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.4
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_device_has_classes (GstDevice * device, const gchar * classes)
Packit Service 963350
{
Packit Service 963350
  gchar **classesv;
Packit Service 963350
  gboolean res;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_DEVICE (device), FALSE);
Packit Service 963350
Packit Service 963350
  if (!classes)
Packit Service 963350
    return TRUE;
Packit Service 963350
Packit Service 963350
  classesv = g_strsplit (classes, "/", 0);
Packit Service 963350
Packit Service 963350
  res = gst_device_has_classesv (device, classesv);
Packit Service 963350
Packit Service 963350
  g_strfreev (classesv);
Packit Service 963350
Packit Service 963350
  return res;
Packit Service 963350
}